diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2009-05-29 05:04:24 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-05-29 05:04:24 -0400 |
commit | 42f1d2e06a25628ae4ceaadccc4fa67c7787e2b4 (patch) | |
tree | 8aac83e399de7ad13748a59853a0feea9ed2c5cb | |
parent | 9af5324a070e0b2dcb6e22c89e17424eba245fcc (diff) | |
parent | 77bbca138c64cb80259732db6f70e1668123f2a7 (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci into devel
251 files changed, 14662 insertions, 1356 deletions
diff --git a/Documentation/ABI/testing/sysfs-kernel-slab b/Documentation/ABI/testing/sysfs-kernel-slab new file mode 100644 index 000000000000..6dcf75e594fb --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-slab | |||
@@ -0,0 +1,479 @@ | |||
1 | What: /sys/kernel/slab | ||
2 | Date: May 2007 | ||
3 | KernelVersion: 2.6.22 | ||
4 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
5 | Christoph Lameter <cl@linux-foundation.org> | ||
6 | Description: | ||
7 | The /sys/kernel/slab directory contains a snapshot of the | ||
8 | internal state of the SLUB allocator for each cache. Certain | ||
9 | files may be modified to change the behavior of the cache (and | ||
10 | any cache it aliases, if any). | ||
11 | Users: kernel memory tuning tools | ||
12 | |||
13 | What: /sys/kernel/slab/cache/aliases | ||
14 | Date: May 2007 | ||
15 | KernelVersion: 2.6.22 | ||
16 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
17 | Christoph Lameter <cl@linux-foundation.org> | ||
18 | Description: | ||
19 | The aliases file is read-only and specifies how many caches | ||
20 | have merged into this cache. | ||
21 | |||
22 | What: /sys/kernel/slab/cache/align | ||
23 | Date: May 2007 | ||
24 | KernelVersion: 2.6.22 | ||
25 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
26 | Christoph Lameter <cl@linux-foundation.org> | ||
27 | Description: | ||
28 | The align file is read-only and specifies the cache's object | ||
29 | alignment in bytes. | ||
30 | |||
31 | What: /sys/kernel/slab/cache/alloc_calls | ||
32 | Date: May 2007 | ||
33 | KernelVersion: 2.6.22 | ||
34 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
35 | Christoph Lameter <cl@linux-foundation.org> | ||
36 | Description: | ||
37 | The alloc_calls file is read-only and lists the kernel code | ||
38 | locations from which allocations for this cache were performed. | ||
39 | The alloc_calls file only contains information if debugging is | ||
40 | enabled for that cache (see Documentation/vm/slub.txt). | ||
41 | |||
42 | What: /sys/kernel/slab/cache/alloc_fastpath | ||
43 | Date: February 2008 | ||
44 | KernelVersion: 2.6.25 | ||
45 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
46 | Christoph Lameter <cl@linux-foundation.org> | ||
47 | Description: | ||
48 | The alloc_fastpath file is read-only and specifies how many | ||
49 | objects have been allocated using the fast path. | ||
50 | Available when CONFIG_SLUB_STATS is enabled. | ||
51 | |||
52 | What: /sys/kernel/slab/cache/alloc_from_partial | ||
53 | Date: February 2008 | ||
54 | KernelVersion: 2.6.25 | ||
55 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
56 | Christoph Lameter <cl@linux-foundation.org> | ||
57 | Description: | ||
58 | The alloc_from_partial file is read-only and specifies how | ||
59 | many times a cpu slab has been full and it has been refilled | ||
60 | by using a slab from the list of partially used slabs. | ||
61 | Available when CONFIG_SLUB_STATS is enabled. | ||
62 | |||
63 | What: /sys/kernel/slab/cache/alloc_refill | ||
64 | Date: February 2008 | ||
65 | KernelVersion: 2.6.25 | ||
66 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
67 | Christoph Lameter <cl@linux-foundation.org> | ||
68 | Description: | ||
69 | The alloc_refill file is read-only and specifies how many | ||
70 | times the per-cpu freelist was empty but there were objects | ||
71 | available as the result of remote cpu frees. | ||
72 | Available when CONFIG_SLUB_STATS is enabled. | ||
73 | |||
74 | What: /sys/kernel/slab/cache/alloc_slab | ||
75 | Date: February 2008 | ||
76 | KernelVersion: 2.6.25 | ||
77 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
78 | Christoph Lameter <cl@linux-foundation.org> | ||
79 | Description: | ||
80 | The alloc_slab file is read-only and specifies how many times | ||
81 | a new slab had to be allocated from the page allocator. | ||
82 | Available when CONFIG_SLUB_STATS is enabled. | ||
83 | |||
84 | What: /sys/kernel/slab/cache/alloc_slowpath | ||
85 | Date: February 2008 | ||
86 | KernelVersion: 2.6.25 | ||
87 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
88 | Christoph Lameter <cl@linux-foundation.org> | ||
89 | Description: | ||
90 | The alloc_slowpath file is read-only and specifies how many | ||
91 | objects have been allocated using the slow path because of a | ||
92 | refill or allocation from a partial or new slab. | ||
93 | Available when CONFIG_SLUB_STATS is enabled. | ||
94 | |||
95 | What: /sys/kernel/slab/cache/cache_dma | ||
96 | Date: May 2007 | ||
97 | KernelVersion: 2.6.22 | ||
98 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
99 | Christoph Lameter <cl@linux-foundation.org> | ||
100 | Description: | ||
101 | The cache_dma file is read-only and specifies whether objects | ||
102 | are from ZONE_DMA. | ||
103 | Available when CONFIG_ZONE_DMA is enabled. | ||
104 | |||
105 | What: /sys/kernel/slab/cache/cpu_slabs | ||
106 | Date: May 2007 | ||
107 | KernelVersion: 2.6.22 | ||
108 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
109 | Christoph Lameter <cl@linux-foundation.org> | ||
110 | Description: | ||
111 | The cpu_slabs file is read-only and displays how many cpu slabs | ||
112 | are active and their NUMA locality. | ||
113 | |||
114 | What: /sys/kernel/slab/cache/cpuslab_flush | ||
115 | Date: April 2009 | ||
116 | KernelVersion: 2.6.31 | ||
117 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
118 | Christoph Lameter <cl@linux-foundation.org> | ||
119 | Description: | ||
120 | The file cpuslab_flush is read-only and specifies how many | ||
121 | times a cache's cpu slabs have been flushed as the result of | ||
122 | destroying or shrinking a cache, a cpu going offline, or as | ||
123 | the result of forcing an allocation from a certain node. | ||
124 | Available when CONFIG_SLUB_STATS is enabled. | ||
125 | |||
126 | What: /sys/kernel/slab/cache/ctor | ||
127 | Date: May 2007 | ||
128 | KernelVersion: 2.6.22 | ||
129 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
130 | Christoph Lameter <cl@linux-foundation.org> | ||
131 | Description: | ||
132 | The ctor file is read-only and specifies the cache's object | ||
133 | constructor function, which is invoked for each object when a | ||
134 | new slab is allocated. | ||
135 | |||
136 | What: /sys/kernel/slab/cache/deactivate_empty | ||
137 | Date: February 2008 | ||
138 | KernelVersion: 2.6.25 | ||
139 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
140 | Christoph Lameter <cl@linux-foundation.org> | ||
141 | Description: | ||
142 | The file deactivate_empty is read-only and specifies how many | ||
143 | times an empty cpu slab was deactivated. | ||
144 | Available when CONFIG_SLUB_STATS is enabled. | ||
145 | |||
146 | What: /sys/kernel/slab/cache/deactivate_full | ||
147 | Date: February 2008 | ||
148 | KernelVersion: 2.6.25 | ||
149 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
150 | Christoph Lameter <cl@linux-foundation.org> | ||
151 | Description: | ||
152 | The file deactivate_full is read-only and specifies how many | ||
153 | times a full cpu slab was deactivated. | ||
154 | Available when CONFIG_SLUB_STATS is enabled. | ||
155 | |||
156 | What: /sys/kernel/slab/cache/deactivate_remote_frees | ||
157 | Date: February 2008 | ||
158 | KernelVersion: 2.6.25 | ||
159 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
160 | Christoph Lameter <cl@linux-foundation.org> | ||
161 | Description: | ||
162 | The file deactivate_remote_frees is read-only and specifies how | ||
163 | many times a cpu slab has been deactivated and contained free | ||
164 | objects that were freed remotely. | ||
165 | Available when CONFIG_SLUB_STATS is enabled. | ||
166 | |||
167 | What: /sys/kernel/slab/cache/deactivate_to_head | ||
168 | Date: February 2008 | ||
169 | KernelVersion: 2.6.25 | ||
170 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
171 | Christoph Lameter <cl@linux-foundation.org> | ||
172 | Description: | ||
173 | The file deactivate_to_head is read-only and specifies how | ||
174 | many times a partial cpu slab was deactivated and added to the | ||
175 | head of its node's partial list. | ||
176 | Available when CONFIG_SLUB_STATS is enabled. | ||
177 | |||
178 | What: /sys/kernel/slab/cache/deactivate_to_tail | ||
179 | Date: February 2008 | ||
180 | KernelVersion: 2.6.25 | ||
181 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
182 | Christoph Lameter <cl@linux-foundation.org> | ||
183 | Description: | ||
184 | The file deactivate_to_tail is read-only and specifies how | ||
185 | many times a partial cpu slab was deactivated and added to the | ||
186 | tail of its node's partial list. | ||
187 | Available when CONFIG_SLUB_STATS is enabled. | ||
188 | |||
189 | What: /sys/kernel/slab/cache/destroy_by_rcu | ||
190 | Date: May 2007 | ||
191 | KernelVersion: 2.6.22 | ||
192 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
193 | Christoph Lameter <cl@linux-foundation.org> | ||
194 | Description: | ||
195 | The destroy_by_rcu file is read-only and specifies whether | ||
196 | slabs (not objects) are freed by rcu. | ||
197 | |||
198 | What: /sys/kernel/slab/cache/free_add_partial | ||
199 | Date: February 2008 | ||
200 | KernelVersion: 2.6.25 | ||
201 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
202 | Christoph Lameter <cl@linux-foundation.org> | ||
203 | Description: | ||
204 | The file free_add_partial is read-only and specifies how many | ||
205 | times an object has been freed in a full slab so that it had to | ||
206 | added to its node's partial list. | ||
207 | Available when CONFIG_SLUB_STATS is enabled. | ||
208 | |||
209 | What: /sys/kernel/slab/cache/free_calls | ||
210 | Date: May 2007 | ||
211 | KernelVersion: 2.6.22 | ||
212 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
213 | Christoph Lameter <cl@linux-foundation.org> | ||
214 | Description: | ||
215 | The free_calls file is read-only and lists the locations of | ||
216 | object frees if slab debugging is enabled (see | ||
217 | Documentation/vm/slub.txt). | ||
218 | |||
219 | What: /sys/kernel/slab/cache/free_fastpath | ||
220 | Date: February 2008 | ||
221 | KernelVersion: 2.6.25 | ||
222 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
223 | Christoph Lameter <cl@linux-foundation.org> | ||
224 | Description: | ||
225 | The free_fastpath file is read-only and specifies how many | ||
226 | objects have been freed using the fast path because it was an | ||
227 | object from the cpu slab. | ||
228 | Available when CONFIG_SLUB_STATS is enabled. | ||
229 | |||
230 | What: /sys/kernel/slab/cache/free_frozen | ||
231 | Date: February 2008 | ||
232 | KernelVersion: 2.6.25 | ||
233 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
234 | Christoph Lameter <cl@linux-foundation.org> | ||
235 | Description: | ||
236 | The free_frozen file is read-only and specifies how many | ||
237 | objects have been freed to a frozen slab (i.e. a remote cpu | ||
238 | slab). | ||
239 | Available when CONFIG_SLUB_STATS is enabled. | ||
240 | |||
241 | What: /sys/kernel/slab/cache/free_remove_partial | ||
242 | Date: February 2008 | ||
243 | KernelVersion: 2.6.25 | ||
244 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
245 | Christoph Lameter <cl@linux-foundation.org> | ||
246 | Description: | ||
247 | The file free_remove_partial is read-only and specifies how | ||
248 | many times an object has been freed to a now-empty slab so | ||
249 | that it had to be removed from its node's partial list. | ||
250 | Available when CONFIG_SLUB_STATS is enabled. | ||
251 | |||
252 | What: /sys/kernel/slab/cache/free_slab | ||
253 | Date: February 2008 | ||
254 | KernelVersion: 2.6.25 | ||
255 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
256 | Christoph Lameter <cl@linux-foundation.org> | ||
257 | Description: | ||
258 | The free_slab file is read-only and specifies how many times an | ||
259 | empty slab has been freed back to the page allocator. | ||
260 | Available when CONFIG_SLUB_STATS is enabled. | ||
261 | |||
262 | What: /sys/kernel/slab/cache/free_slowpath | ||
263 | Date: February 2008 | ||
264 | KernelVersion: 2.6.25 | ||
265 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
266 | Christoph Lameter <cl@linux-foundation.org> | ||
267 | Description: | ||
268 | The free_slowpath file is read-only and specifies how many | ||
269 | objects have been freed using the slow path (i.e. to a full or | ||
270 | partial slab). | ||
271 | Available when CONFIG_SLUB_STATS is enabled. | ||
272 | |||
273 | What: /sys/kernel/slab/cache/hwcache_align | ||
274 | Date: May 2007 | ||
275 | KernelVersion: 2.6.22 | ||
276 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
277 | Christoph Lameter <cl@linux-foundation.org> | ||
278 | Description: | ||
279 | The hwcache_align file is read-only and specifies whether | ||
280 | objects are aligned on cachelines. | ||
281 | |||
282 | What: /sys/kernel/slab/cache/min_partial | ||
283 | Date: February 2009 | ||
284 | KernelVersion: 2.6.30 | ||
285 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
286 | David Rientjes <rientjes@google.com> | ||
287 | Description: | ||
288 | The min_partial file specifies how many empty slabs shall | ||
289 | remain on a node's partial list to avoid the overhead of | ||
290 | allocating new slabs. Such slabs may be reclaimed by utilizing | ||
291 | the shrink file. | ||
292 | |||
293 | What: /sys/kernel/slab/cache/object_size | ||
294 | Date: May 2007 | ||
295 | KernelVersion: 2.6.22 | ||
296 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
297 | Christoph Lameter <cl@linux-foundation.org> | ||
298 | Description: | ||
299 | The object_size file is read-only and specifies the cache's | ||
300 | object size. | ||
301 | |||
302 | What: /sys/kernel/slab/cache/objects | ||
303 | Date: May 2007 | ||
304 | KernelVersion: 2.6.22 | ||
305 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
306 | Christoph Lameter <cl@linux-foundation.org> | ||
307 | Description: | ||
308 | The objects file is read-only and displays how many objects are | ||
309 | active and from which nodes they are from. | ||
310 | |||
311 | What: /sys/kernel/slab/cache/objects_partial | ||
312 | Date: April 2008 | ||
313 | KernelVersion: 2.6.26 | ||
314 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
315 | Christoph Lameter <cl@linux-foundation.org> | ||
316 | Description: | ||
317 | The objects_partial file is read-only and displays how many | ||
318 | objects are on partial slabs and from which nodes they are | ||
319 | from. | ||
320 | |||
321 | What: /sys/kernel/slab/cache/objs_per_slab | ||
322 | Date: May 2007 | ||
323 | KernelVersion: 2.6.22 | ||
324 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
325 | Christoph Lameter <cl@linux-foundation.org> | ||
326 | Description: | ||
327 | The file objs_per_slab is read-only and specifies how many | ||
328 | objects may be allocated from a single slab of the order | ||
329 | specified in /sys/kernel/slab/cache/order. | ||
330 | |||
331 | What: /sys/kernel/slab/cache/order | ||
332 | Date: May 2007 | ||
333 | KernelVersion: 2.6.22 | ||
334 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
335 | Christoph Lameter <cl@linux-foundation.org> | ||
336 | Description: | ||
337 | The order file specifies the page order at which new slabs are | ||
338 | allocated. It is writable and can be changed to increase the | ||
339 | number of objects per slab. If a slab cannot be allocated | ||
340 | because of fragmentation, SLUB will retry with the minimum order | ||
341 | possible depending on its characteristics. | ||
342 | |||
343 | What: /sys/kernel/slab/cache/order_fallback | ||
344 | Date: April 2008 | ||
345 | KernelVersion: 2.6.26 | ||
346 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
347 | Christoph Lameter <cl@linux-foundation.org> | ||
348 | Description: | ||
349 | The file order_fallback is read-only and specifies how many | ||
350 | times an allocation of a new slab has not been possible at the | ||
351 | cache's order and instead fallen back to its minimum possible | ||
352 | order. | ||
353 | Available when CONFIG_SLUB_STATS is enabled. | ||
354 | |||
355 | What: /sys/kernel/slab/cache/partial | ||
356 | Date: May 2007 | ||
357 | KernelVersion: 2.6.22 | ||
358 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
359 | Christoph Lameter <cl@linux-foundation.org> | ||
360 | Description: | ||
361 | The partial file is read-only and displays how long many | ||
362 | partial slabs there are and how long each node's list is. | ||
363 | |||
364 | What: /sys/kernel/slab/cache/poison | ||
365 | Date: May 2007 | ||
366 | KernelVersion: 2.6.22 | ||
367 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
368 | Christoph Lameter <cl@linux-foundation.org> | ||
369 | Description: | ||
370 | The poison file specifies whether objects should be poisoned | ||
371 | when a new slab is allocated. | ||
372 | |||
373 | What: /sys/kernel/slab/cache/reclaim_account | ||
374 | Date: May 2007 | ||
375 | KernelVersion: 2.6.22 | ||
376 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
377 | Christoph Lameter <cl@linux-foundation.org> | ||
378 | Description: | ||
379 | The reclaim_account file specifies whether the cache's objects | ||
380 | are reclaimable (and grouped by their mobility). | ||
381 | |||
382 | What: /sys/kernel/slab/cache/red_zone | ||
383 | Date: May 2007 | ||
384 | KernelVersion: 2.6.22 | ||
385 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
386 | Christoph Lameter <cl@linux-foundation.org> | ||
387 | Description: | ||
388 | The red_zone file specifies whether the cache's objects are red | ||
389 | zoned. | ||
390 | |||
391 | What: /sys/kernel/slab/cache/remote_node_defrag_ratio | ||
392 | Date: January 2008 | ||
393 | KernelVersion: 2.6.25 | ||
394 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
395 | Christoph Lameter <cl@linux-foundation.org> | ||
396 | Description: | ||
397 | The file remote_node_defrag_ratio specifies the percentage of | ||
398 | times SLUB will attempt to refill the cpu slab with a partial | ||
399 | slab from a remote node as opposed to allocating a new slab on | ||
400 | the local node. This reduces the amount of wasted memory over | ||
401 | the entire system but can be expensive. | ||
402 | Available when CONFIG_NUMA is enabled. | ||
403 | |||
404 | What: /sys/kernel/slab/cache/sanity_checks | ||
405 | Date: May 2007 | ||
406 | KernelVersion: 2.6.22 | ||
407 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
408 | Christoph Lameter <cl@linux-foundation.org> | ||
409 | Description: | ||
410 | The sanity_checks file specifies whether expensive checks | ||
411 | should be performed on free and, at minimum, enables double free | ||
412 | checks. Caches that enable sanity_checks cannot be merged with | ||
413 | caches that do not. | ||
414 | |||
415 | What: /sys/kernel/slab/cache/shrink | ||
416 | Date: May 2007 | ||
417 | KernelVersion: 2.6.22 | ||
418 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
419 | Christoph Lameter <cl@linux-foundation.org> | ||
420 | Description: | ||
421 | The shrink file is written when memory should be reclaimed from | ||
422 | a cache. Empty partial slabs are freed and the partial list is | ||
423 | sorted so the slabs with the fewest available objects are used | ||
424 | first. | ||
425 | |||
426 | What: /sys/kernel/slab/cache/slab_size | ||
427 | Date: May 2007 | ||
428 | KernelVersion: 2.6.22 | ||
429 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
430 | Christoph Lameter <cl@linux-foundation.org> | ||
431 | Description: | ||
432 | The slab_size file is read-only and specifies the object size | ||
433 | with metadata (debugging information and alignment) in bytes. | ||
434 | |||
435 | What: /sys/kernel/slab/cache/slabs | ||
436 | Date: May 2007 | ||
437 | KernelVersion: 2.6.22 | ||
438 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
439 | Christoph Lameter <cl@linux-foundation.org> | ||
440 | Description: | ||
441 | The slabs file is read-only and displays how long many slabs | ||
442 | there are (both cpu and partial) and from which nodes they are | ||
443 | from. | ||
444 | |||
445 | What: /sys/kernel/slab/cache/store_user | ||
446 | Date: May 2007 | ||
447 | KernelVersion: 2.6.22 | ||
448 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
449 | Christoph Lameter <cl@linux-foundation.org> | ||
450 | Description: | ||
451 | The store_user file specifies whether the location of | ||
452 | allocation or free should be tracked for a cache. | ||
453 | |||
454 | What: /sys/kernel/slab/cache/total_objects | ||
455 | Date: April 2008 | ||
456 | KernelVersion: 2.6.26 | ||
457 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
458 | Christoph Lameter <cl@linux-foundation.org> | ||
459 | Description: | ||
460 | The total_objects file is read-only and displays how many total | ||
461 | objects a cache has and from which nodes they are from. | ||
462 | |||
463 | What: /sys/kernel/slab/cache/trace | ||
464 | Date: May 2007 | ||
465 | KernelVersion: 2.6.22 | ||
466 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
467 | Christoph Lameter <cl@linux-foundation.org> | ||
468 | Description: | ||
469 | The trace file specifies whether object allocations and frees | ||
470 | should be traced. | ||
471 | |||
472 | What: /sys/kernel/slab/cache/validate | ||
473 | Date: May 2007 | ||
474 | KernelVersion: 2.6.22 | ||
475 | Contact: Pekka Enberg <penberg@cs.helsinki.fi>, | ||
476 | Christoph Lameter <cl@linux-foundation.org> | ||
477 | Description: | ||
478 | Writing to the validate file causes SLUB to traverse all of its | ||
479 | cache's objects and check the validity of metadata. | ||
diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index 222437efd75a..3015da0c6b2a 100644 --- a/Documentation/filesystems/tmpfs.txt +++ b/Documentation/filesystems/tmpfs.txt | |||
@@ -133,4 +133,4 @@ RAM/SWAP in 10240 inodes and it is only accessible by root. | |||
133 | Author: | 133 | Author: |
134 | Christoph Rohland <cr@sap.com>, 1.12.01 | 134 | Christoph Rohland <cr@sap.com>, 1.12.01 |
135 | Updated: | 135 | Updated: |
136 | Hugh Dickins <hugh@veritas.com>, 4 June 2007 | 136 | Hugh Dickins, 4 June 2007 |
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index ec5de02f543f..b121c5db707f 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -1266,13 +1266,22 @@ sctp_rmem - vector of 3 INTEGERs: min, default, max | |||
1266 | sctp_wmem - vector of 3 INTEGERs: min, default, max | 1266 | sctp_wmem - vector of 3 INTEGERs: min, default, max |
1267 | See tcp_wmem for a description. | 1267 | See tcp_wmem for a description. |
1268 | 1268 | ||
1269 | UNDOCUMENTED: | ||
1270 | 1269 | ||
1271 | /proc/sys/net/core/* | 1270 | /proc/sys/net/core/* |
1272 | dev_weight FIXME | 1271 | dev_weight - INTEGER |
1272 | The maximum number of packets that kernel can handle on a NAPI | ||
1273 | interrupt, it's a Per-CPU variable. | ||
1274 | |||
1275 | Default: 64 | ||
1273 | 1276 | ||
1274 | /proc/sys/net/unix/* | 1277 | /proc/sys/net/unix/* |
1275 | max_dgram_qlen FIXME | 1278 | max_dgram_qlen - INTEGER |
1279 | The maximum length of dgram socket receive queue | ||
1280 | |||
1281 | Default: 10 | ||
1282 | |||
1283 | |||
1284 | UNDOCUMENTED: | ||
1276 | 1285 | ||
1277 | /proc/sys/net/irda/* | 1286 | /proc/sys/net/irda/* |
1278 | fast_poll_increase FIXME | 1287 | fast_poll_increase FIXME |
diff --git a/MAINTAINERS b/MAINTAINERS index 2b349ba4add4..77cbfb1a696c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1431,6 +1431,14 @@ P: Russell King | |||
1431 | M: linux@arm.linux.org.uk | 1431 | M: linux@arm.linux.org.uk |
1432 | F: include/linux/clk.h | 1432 | F: include/linux/clk.h |
1433 | 1433 | ||
1434 | CISCO FCOE HBA DRIVER | ||
1435 | P: Abhijeet Joglekar | ||
1436 | M: abjoglek@cisco.com | ||
1437 | P: Joe Eykholt | ||
1438 | M: jeykholt@cisco.com | ||
1439 | L: linux-scsi@vger.kernel.org | ||
1440 | S: Supported | ||
1441 | |||
1434 | CODA FILE SYSTEM | 1442 | CODA FILE SYSTEM |
1435 | P: Jan Harkes | 1443 | P: Jan Harkes |
1436 | M: jaharkes@cs.cmu.edu | 1444 | M: jaharkes@cs.cmu.edu |
@@ -5579,6 +5587,14 @@ M: ian@mnementh.co.uk | |||
5579 | S: Maintained | 5587 | S: Maintained |
5580 | F: drivers/mmc/host/tmio_mmc.* | 5588 | F: drivers/mmc/host/tmio_mmc.* |
5581 | 5589 | ||
5590 | TMPFS (SHMEM FILESYSTEM) | ||
5591 | P: Hugh Dickins | ||
5592 | M: hugh.dickins@tiscali.co.uk | ||
5593 | L: linux-mm@kvack.org | ||
5594 | S: Maintained | ||
5595 | F: include/linux/shmem_fs.h | ||
5596 | F: mm/shmem.c | ||
5597 | |||
5582 | TPM DEVICE DRIVER | 5598 | TPM DEVICE DRIVER |
5583 | P: Debora Velarde | 5599 | P: Debora Velarde |
5584 | M: debora@linux.vnet.ibm.com | 5600 | M: debora@linux.vnet.ibm.com |
@@ -1,8 +1,8 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 30 | 3 | SUBLEVEL = 30 |
4 | EXTRAVERSION = -rc6 | 4 | EXTRAVERSION = -rc7 |
5 | NAME = Vindictive Armadillo | 5 | NAME = Man-Eating Seals of Antiquity |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
8 | # To see a list of typical targets execute "make help" | 8 | # To see a list of typical targets execute "make help" |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c52f6909f65d..65bf774a26fd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -281,6 +281,7 @@ config ARCH_EP93XX | |||
281 | select HAVE_CLK | 281 | select HAVE_CLK |
282 | select COMMON_CLKDEV | 282 | select COMMON_CLKDEV |
283 | select ARCH_REQUIRE_GPIOLIB | 283 | select ARCH_REQUIRE_GPIOLIB |
284 | select ARCH_HAS_HOLES_MEMORYMODEL | ||
284 | help | 285 | help |
285 | This enables support for the Cirrus EP93xx series of CPUs. | 286 | This enables support for the Cirrus EP93xx series of CPUs. |
286 | 287 | ||
@@ -595,6 +596,7 @@ config ARCH_DAVINCI | |||
595 | select ZONE_DMA | 596 | select ZONE_DMA |
596 | select HAVE_IDE | 597 | select HAVE_IDE |
597 | select COMMON_CLKDEV | 598 | select COMMON_CLKDEV |
599 | select GENERIC_ALLOCATOR | ||
598 | help | 600 | help |
599 | Support for TI's DaVinci platform. | 601 | Support for TI's DaVinci platform. |
600 | 602 | ||
@@ -965,10 +967,9 @@ config OABI_COMPAT | |||
965 | UNPREDICTABLE (in fact it can be predicted that it won't work | 967 | UNPREDICTABLE (in fact it can be predicted that it won't work |
966 | at all). If in doubt say Y. | 968 | at all). If in doubt say Y. |
967 | 969 | ||
968 | config ARCH_FLATMEM_HAS_HOLES | 970 | config ARCH_HAS_HOLES_MEMORYMODEL |
969 | bool | 971 | bool |
970 | default y | 972 | default n |
971 | depends on FLATMEM | ||
972 | 973 | ||
973 | # Discontigmem is deprecated | 974 | # Discontigmem is deprecated |
974 | config ARCH_DISCONTIGMEM_ENABLE | 975 | config ARCH_DISCONTIGMEM_ENABLE |
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index c6884ba1d5ed..3e1714c6523f 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -253,9 +253,9 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) | |||
253 | } | 253 | } |
254 | 254 | ||
255 | #ifdef CONFIG_SMP | 255 | #ifdef CONFIG_SMP |
256 | void gic_raise_softirq(cpumask_t cpumask, unsigned int irq) | 256 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) |
257 | { | 257 | { |
258 | unsigned long map = *cpus_addr(cpumask); | 258 | unsigned long map = *cpus_addr(*mask); |
259 | 259 | ||
260 | /* this always happens on GIC0 */ | 260 | /* this always happens on GIC0 */ |
261 | writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); | 261 | writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); |
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index eb2738b5be5f..ac18662f38cc 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.30-rc2 | 3 | # Linux kernel version: 2.6.30-rc7 |
4 | # Wed Apr 15 08:16:53 2009 | 4 | # Tue May 26 07:24:28 2009 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y |
@@ -179,6 +179,7 @@ CONFIG_ARCH_DAVINCI=y | |||
179 | # CONFIG_ARCH_OMAP is not set | 179 | # CONFIG_ARCH_OMAP is not set |
180 | # CONFIG_ARCH_MSM is not set | 180 | # CONFIG_ARCH_MSM is not set |
181 | # CONFIG_ARCH_W90X900 is not set | 181 | # CONFIG_ARCH_W90X900 is not set |
182 | CONFIG_AINTC=y | ||
182 | 183 | ||
183 | # | 184 | # |
184 | # TI DaVinci Implementations | 185 | # TI DaVinci Implementations |
@@ -188,11 +189,17 @@ CONFIG_ARCH_DAVINCI=y | |||
188 | # DaVinci Core Type | 189 | # DaVinci Core Type |
189 | # | 190 | # |
190 | CONFIG_ARCH_DAVINCI_DM644x=y | 191 | CONFIG_ARCH_DAVINCI_DM644x=y |
192 | CONFIG_ARCH_DAVINCI_DM355=y | ||
193 | CONFIG_ARCH_DAVINCI_DM646x=y | ||
191 | 194 | ||
192 | # | 195 | # |
193 | # DaVinci Board Type | 196 | # DaVinci Board Type |
194 | # | 197 | # |
195 | CONFIG_MACH_DAVINCI_EVM=y | 198 | CONFIG_MACH_DAVINCI_EVM=y |
199 | CONFIG_MACH_SFFSDR=y | ||
200 | CONFIG_MACH_DAVINCI_DM355_EVM=y | ||
201 | CONFIG_MACH_DM355_LEOPARD=y | ||
202 | CONFIG_MACH_DAVINCI_DM6467_EVM=y | ||
196 | CONFIG_DAVINCI_MUX=y | 203 | CONFIG_DAVINCI_MUX=y |
197 | CONFIG_DAVINCI_MUX_DEBUG=y | 204 | CONFIG_DAVINCI_MUX_DEBUG=y |
198 | CONFIG_DAVINCI_MUX_WARNINGS=y | 205 | CONFIG_DAVINCI_MUX_WARNINGS=y |
@@ -245,7 +252,7 @@ CONFIG_PREEMPT=y | |||
245 | CONFIG_HZ=100 | 252 | CONFIG_HZ=100 |
246 | CONFIG_AEABI=y | 253 | CONFIG_AEABI=y |
247 | # CONFIG_OABI_COMPAT is not set | 254 | # CONFIG_OABI_COMPAT is not set |
248 | CONFIG_ARCH_FLATMEM_HAS_HOLES=y | 255 | # CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set |
249 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | 256 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set |
250 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | 257 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set |
251 | # CONFIG_HIGHMEM is not set | 258 | # CONFIG_HIGHMEM is not set |
@@ -661,7 +668,10 @@ CONFIG_NET_ETHERNET=y | |||
661 | CONFIG_MII=y | 668 | CONFIG_MII=y |
662 | # CONFIG_AX88796 is not set | 669 | # CONFIG_AX88796 is not set |
663 | # CONFIG_SMC91X is not set | 670 | # CONFIG_SMC91X is not set |
664 | # CONFIG_DM9000 is not set | 671 | CONFIG_TI_DAVINCI_EMAC=y |
672 | CONFIG_DM9000=y | ||
673 | CONFIG_DM9000_DEBUGLEVEL=4 | ||
674 | # CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set | ||
665 | # CONFIG_ETHOC is not set | 675 | # CONFIG_ETHOC is not set |
666 | # CONFIG_SMC911X is not set | 676 | # CONFIG_SMC911X is not set |
667 | # CONFIG_SMSC911X is not set | 677 | # CONFIG_SMSC911X is not set |
@@ -963,6 +973,7 @@ CONFIG_SSB_POSSIBLE=y | |||
963 | # CONFIG_MFD_CORE is not set | 973 | # CONFIG_MFD_CORE is not set |
964 | # CONFIG_MFD_SM501 is not set | 974 | # CONFIG_MFD_SM501 is not set |
965 | # CONFIG_MFD_ASIC3 is not set | 975 | # CONFIG_MFD_ASIC3 is not set |
976 | # CONFIG_MFD_DM355EVM_MSP is not set | ||
966 | # CONFIG_HTC_EGPIO is not set | 977 | # CONFIG_HTC_EGPIO is not set |
967 | # CONFIG_HTC_PASIC3 is not set | 978 | # CONFIG_HTC_PASIC3 is not set |
968 | # CONFIG_TPS65010 is not set | 979 | # CONFIG_TPS65010 is not set |
@@ -1317,6 +1328,7 @@ CONFIG_MMC_BLOCK=m | |||
1317 | # MMC/SD/SDIO Host Controller Drivers | 1328 | # MMC/SD/SDIO Host Controller Drivers |
1318 | # | 1329 | # |
1319 | # CONFIG_MMC_SDHCI is not set | 1330 | # CONFIG_MMC_SDHCI is not set |
1331 | # CONFIG_MMC_DAVINCI is not set | ||
1320 | # CONFIG_MEMSTICK is not set | 1332 | # CONFIG_MEMSTICK is not set |
1321 | # CONFIG_ACCESSIBILITY is not set | 1333 | # CONFIG_ACCESSIBILITY is not set |
1322 | CONFIG_NEW_LEDS=y | 1334 | CONFIG_NEW_LEDS=y |
@@ -1778,6 +1790,7 @@ CONFIG_CRC32=y | |||
1778 | CONFIG_ZLIB_INFLATE=y | 1790 | CONFIG_ZLIB_INFLATE=y |
1779 | CONFIG_ZLIB_DEFLATE=m | 1791 | CONFIG_ZLIB_DEFLATE=m |
1780 | CONFIG_DECOMPRESS_GZIP=y | 1792 | CONFIG_DECOMPRESS_GZIP=y |
1793 | CONFIG_GENERIC_ALLOCATOR=y | ||
1781 | CONFIG_HAS_IOMEM=y | 1794 | CONFIG_HAS_IOMEM=y |
1782 | CONFIG_HAS_IOPORT=y | 1795 | CONFIG_HAS_IOPORT=y |
1783 | CONFIG_HAS_DMA=y | 1796 | CONFIG_HAS_DMA=y |
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 4924914af188..7f34333bb545 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h | |||
@@ -36,7 +36,7 @@ | |||
36 | void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); | 36 | void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); |
37 | void gic_cpu_init(unsigned int gic_nr, void __iomem *base); | 37 | void gic_cpu_init(unsigned int gic_nr, void __iomem *base); |
38 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); | 38 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); |
39 | void gic_raise_softirq(cpumask_t cpumask, unsigned int irq); | 39 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #endif | 42 | #endif |
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index fad70da5911d..5995935338e1 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h | |||
@@ -53,17 +53,12 @@ extern void smp_store_cpu_info(unsigned int cpuid); | |||
53 | /* | 53 | /* |
54 | * Raise an IPI cross call on CPUs in callmap. | 54 | * Raise an IPI cross call on CPUs in callmap. |
55 | */ | 55 | */ |
56 | extern void smp_cross_call(cpumask_t callmap); | 56 | extern void smp_cross_call(const struct cpumask *mask); |
57 | |||
58 | /* | ||
59 | * Broadcast a timer interrupt to the other CPUs. | ||
60 | */ | ||
61 | extern void smp_send_timer(void); | ||
62 | 57 | ||
63 | /* | 58 | /* |
64 | * Broadcast a clock event to other CPUs. | 59 | * Broadcast a clock event to other CPUs. |
65 | */ | 60 | */ |
66 | extern void smp_timer_broadcast(cpumask_t mask); | 61 | extern void smp_timer_broadcast(const struct cpumask *mask); |
67 | 62 | ||
68 | /* | 63 | /* |
69 | * Boot a secondary CPU, and assign it the specified idle task. | 64 | * Boot a secondary CPU, and assign it the specified idle task. |
@@ -102,7 +97,8 @@ extern int platform_cpu_kill(unsigned int cpu); | |||
102 | extern void platform_cpu_enable(unsigned int cpu); | 97 | extern void platform_cpu_enable(unsigned int cpu); |
103 | 98 | ||
104 | extern void arch_send_call_function_single_ipi(int cpu); | 99 | extern void arch_send_call_function_single_ipi(int cpu); |
105 | extern void arch_send_call_function_ipi(cpumask_t mask); | 100 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); |
101 | #define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask | ||
106 | 102 | ||
107 | /* | 103 | /* |
108 | * Local timer interrupt handling function (can be IPI'ed). | 104 | * Local timer interrupt handling function (can be IPI'ed). |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7801aac3c043..6014dfd22af4 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -326,14 +326,14 @@ void __init smp_prepare_boot_cpu(void) | |||
326 | per_cpu(cpu_data, cpu).idle = current; | 326 | per_cpu(cpu_data, cpu).idle = current; |
327 | } | 327 | } |
328 | 328 | ||
329 | static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) | 329 | static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg) |
330 | { | 330 | { |
331 | unsigned long flags; | 331 | unsigned long flags; |
332 | unsigned int cpu; | 332 | unsigned int cpu; |
333 | 333 | ||
334 | local_irq_save(flags); | 334 | local_irq_save(flags); |
335 | 335 | ||
336 | for_each_cpu_mask(cpu, callmap) { | 336 | for_each_cpu(cpu, mask) { |
337 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); | 337 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); |
338 | 338 | ||
339 | spin_lock(&ipi->lock); | 339 | spin_lock(&ipi->lock); |
@@ -344,19 +344,19 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) | |||
344 | /* | 344 | /* |
345 | * Call the platform specific cross-CPU call function. | 345 | * Call the platform specific cross-CPU call function. |
346 | */ | 346 | */ |
347 | smp_cross_call(callmap); | 347 | smp_cross_call(mask); |
348 | 348 | ||
349 | local_irq_restore(flags); | 349 | local_irq_restore(flags); |
350 | } | 350 | } |
351 | 351 | ||
352 | void arch_send_call_function_ipi(cpumask_t mask) | 352 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) |
353 | { | 353 | { |
354 | send_ipi_message(mask, IPI_CALL_FUNC); | 354 | send_ipi_message(mask, IPI_CALL_FUNC); |
355 | } | 355 | } |
356 | 356 | ||
357 | void arch_send_call_function_single_ipi(int cpu) | 357 | void arch_send_call_function_single_ipi(int cpu) |
358 | { | 358 | { |
359 | send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE); | 359 | send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); |
360 | } | 360 | } |
361 | 361 | ||
362 | void show_ipi_list(struct seq_file *p) | 362 | void show_ipi_list(struct seq_file *p) |
@@ -498,17 +498,10 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs) | |||
498 | 498 | ||
499 | void smp_send_reschedule(int cpu) | 499 | void smp_send_reschedule(int cpu) |
500 | { | 500 | { |
501 | send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); | 501 | send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); |
502 | } | 502 | } |
503 | 503 | ||
504 | void smp_send_timer(void) | 504 | void smp_timer_broadcast(const struct cpumask *mask) |
505 | { | ||
506 | cpumask_t mask = cpu_online_map; | ||
507 | cpu_clear(smp_processor_id(), mask); | ||
508 | send_ipi_message(mask, IPI_TIMER); | ||
509 | } | ||
510 | |||
511 | void smp_timer_broadcast(cpumask_t mask) | ||
512 | { | 505 | { |
513 | send_ipi_message(mask, IPI_TIMER); | 506 | send_ipi_message(mask, IPI_TIMER); |
514 | } | 507 | } |
@@ -517,7 +510,7 @@ void smp_send_stop(void) | |||
517 | { | 510 | { |
518 | cpumask_t mask = cpu_online_map; | 511 | cpumask_t mask = cpu_online_map; |
519 | cpu_clear(smp_processor_id(), mask); | 512 | cpu_clear(smp_processor_id(), mask); |
520 | send_ipi_message(mask, IPI_CPU_STOP); | 513 | send_ipi_message(&mask, IPI_CPU_STOP); |
521 | } | 514 | } |
522 | 515 | ||
523 | /* | 516 | /* |
@@ -528,20 +521,17 @@ int setup_profiling_timer(unsigned int multiplier) | |||
528 | return -EINVAL; | 521 | return -EINVAL; |
529 | } | 522 | } |
530 | 523 | ||
531 | static int | 524 | static void |
532 | on_each_cpu_mask(void (*func)(void *), void *info, int wait, cpumask_t mask) | 525 | on_each_cpu_mask(void (*func)(void *), void *info, int wait, |
526 | const struct cpumask *mask) | ||
533 | { | 527 | { |
534 | int ret = 0; | ||
535 | |||
536 | preempt_disable(); | 528 | preempt_disable(); |
537 | 529 | ||
538 | ret = smp_call_function_mask(mask, func, info, wait); | 530 | smp_call_function_many(mask, func, info, wait); |
539 | if (cpu_isset(smp_processor_id(), mask)) | 531 | if (cpumask_test_cpu(smp_processor_id(), mask)) |
540 | func(info); | 532 | func(info); |
541 | 533 | ||
542 | preempt_enable(); | 534 | preempt_enable(); |
543 | |||
544 | return ret; | ||
545 | } | 535 | } |
546 | 536 | ||
547 | /**********************************************************************/ | 537 | /**********************************************************************/ |
@@ -602,20 +592,17 @@ void flush_tlb_all(void) | |||
602 | 592 | ||
603 | void flush_tlb_mm(struct mm_struct *mm) | 593 | void flush_tlb_mm(struct mm_struct *mm) |
604 | { | 594 | { |
605 | cpumask_t mask = mm->cpu_vm_mask; | 595 | on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, &mm->cpu_vm_mask); |
606 | |||
607 | on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mask); | ||
608 | } | 596 | } |
609 | 597 | ||
610 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | 598 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) |
611 | { | 599 | { |
612 | cpumask_t mask = vma->vm_mm->cpu_vm_mask; | ||
613 | struct tlb_args ta; | 600 | struct tlb_args ta; |
614 | 601 | ||
615 | ta.ta_vma = vma; | 602 | ta.ta_vma = vma; |
616 | ta.ta_start = uaddr; | 603 | ta.ta_start = uaddr; |
617 | 604 | ||
618 | on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mask); | 605 | on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, &vma->vm_mm->cpu_vm_mask); |
619 | } | 606 | } |
620 | 607 | ||
621 | void flush_tlb_kernel_page(unsigned long kaddr) | 608 | void flush_tlb_kernel_page(unsigned long kaddr) |
@@ -630,14 +617,13 @@ void flush_tlb_kernel_page(unsigned long kaddr) | |||
630 | void flush_tlb_range(struct vm_area_struct *vma, | 617 | void flush_tlb_range(struct vm_area_struct *vma, |
631 | unsigned long start, unsigned long end) | 618 | unsigned long start, unsigned long end) |
632 | { | 619 | { |
633 | cpumask_t mask = vma->vm_mm->cpu_vm_mask; | ||
634 | struct tlb_args ta; | 620 | struct tlb_args ta; |
635 | 621 | ||
636 | ta.ta_vma = vma; | 622 | ta.ta_vma = vma; |
637 | ta.ta_start = start; | 623 | ta.ta_start = start; |
638 | ta.ta_end = end; | 624 | ta.ta_end = end; |
639 | 625 | ||
640 | on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mask); | 626 | on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, &vma->vm_mm->cpu_vm_mask); |
641 | } | 627 | } |
642 | 628 | ||
643 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 629 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index a9c78bc72b84..76408670554d 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig | |||
@@ -1,11 +1,26 @@ | |||
1 | if ARCH_DAVINCI | 1 | if ARCH_DAVINCI |
2 | 2 | ||
3 | config AINTC | ||
4 | bool | ||
5 | |||
6 | config CP_INTC | ||
7 | bool | ||
8 | |||
3 | menu "TI DaVinci Implementations" | 9 | menu "TI DaVinci Implementations" |
4 | 10 | ||
5 | comment "DaVinci Core Type" | 11 | comment "DaVinci Core Type" |
6 | 12 | ||
7 | config ARCH_DAVINCI_DM644x | 13 | config ARCH_DAVINCI_DM644x |
8 | bool "DaVinci 644x based system" | 14 | bool "DaVinci 644x based system" |
15 | select AINTC | ||
16 | |||
17 | config ARCH_DAVINCI_DM355 | ||
18 | bool "DaVinci 355 based system" | ||
19 | select AINTC | ||
20 | |||
21 | config ARCH_DAVINCI_DM646x | ||
22 | bool "DaVinci 646x based system" | ||
23 | select AINTC | ||
9 | 24 | ||
10 | comment "DaVinci Board Type" | 25 | comment "DaVinci Board Type" |
11 | 26 | ||
@@ -17,6 +32,38 @@ config MACH_DAVINCI_EVM | |||
17 | Configure this option to specify the whether the board used | 32 | Configure this option to specify the whether the board used |
18 | for development is a DM644x EVM | 33 | for development is a DM644x EVM |
19 | 34 | ||
35 | config MACH_SFFSDR | ||
36 | bool "Lyrtech SFFSDR" | ||
37 | default n | ||
38 | depends on ARCH_DAVINCI_DM644x | ||
39 | help | ||
40 | Say Y here to select the Lyrtech Small Form Factor | ||
41 | Software Defined Radio (SFFSDR) board. | ||
42 | |||
43 | config MACH_DAVINCI_DM355_EVM | ||
44 | bool "TI DM355 EVM" | ||
45 | default n | ||
46 | depends on ARCH_DAVINCI_DM355 | ||
47 | help | ||
48 | Configure this option to specify the whether the board used | ||
49 | for development is a DM355 EVM | ||
50 | |||
51 | config MACH_DM355_LEOPARD | ||
52 | bool "DM355 Leopard board" | ||
53 | default n | ||
54 | depends on ARCH_DAVINCI_DM355 | ||
55 | help | ||
56 | Configure this option to specify the whether the board used | ||
57 | for development is a DM355 Leopard board. | ||
58 | |||
59 | config MACH_DAVINCI_DM6467_EVM | ||
60 | bool "TI DM6467 EVM" | ||
61 | default n | ||
62 | depends on ARCH_DAVINCI_DM646x | ||
63 | help | ||
64 | Configure this option to specify the whether the board used | ||
65 | for development is a DM6467 EVM | ||
66 | |||
20 | 67 | ||
21 | config DAVINCI_MUX | 68 | config DAVINCI_MUX |
22 | bool "DAVINCI multiplexing support" | 69 | bool "DAVINCI multiplexing support" |
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 1674661942f3..059ab78084ba 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile | |||
@@ -4,13 +4,22 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | # Common objects | 6 | # Common objects |
7 | obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \ | 7 | obj-y := time.o clock.o serial.o io.o psc.o \ |
8 | gpio.o devices.o dma.o usb.o | 8 | gpio.o devices.o dma.o usb.o common.o sram.o |
9 | 9 | ||
10 | obj-$(CONFIG_DAVINCI_MUX) += mux.o | 10 | obj-$(CONFIG_DAVINCI_MUX) += mux.o |
11 | 11 | ||
12 | # Chip specific | 12 | # Chip specific |
13 | obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o | 13 | obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o |
14 | obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o | ||
15 | obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o | ||
16 | |||
17 | obj-$(CONFIG_AINTC) += irq.o | ||
18 | obj-$(CONFIG_CP_INTC) += cp_intc.o | ||
14 | 19 | ||
15 | # Board specific | 20 | # Board specific |
16 | obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o | 21 | obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o |
22 | obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o | ||
23 | obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o | ||
24 | obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o | ||
25 | obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o | ||
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c new file mode 100644 index 000000000000..5ac2f565d860 --- /dev/null +++ b/arch/arm/mach-davinci/board-dm355-evm.c | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * TI DaVinci EVM board support | ||
3 | * | ||
4 | * Author: Kevin Hilman, Deep Root Systems, LLC | ||
5 | * | ||
6 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mtd/mtd.h> | ||
17 | #include <linux/mtd/partitions.h> | ||
18 | #include <linux/mtd/nand.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/spi/eeprom.h> | ||
25 | |||
26 | #include <asm/setup.h> | ||
27 | #include <asm/mach-types.h> | ||
28 | #include <asm/mach/arch.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | #include <asm/mach/flash.h> | ||
31 | |||
32 | #include <mach/hardware.h> | ||
33 | #include <mach/dm355.h> | ||
34 | #include <mach/psc.h> | ||
35 | #include <mach/common.h> | ||
36 | #include <mach/i2c.h> | ||
37 | #include <mach/serial.h> | ||
38 | #include <mach/nand.h> | ||
39 | #include <mach/mmc.h> | ||
40 | #include <mach/common.h> | ||
41 | |||
42 | #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 | ||
43 | #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 | ||
44 | |||
45 | /* NOTE: this is geared for the standard config, with a socketed | ||
46 | * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you | ||
47 | * swap chips, maybe with a different block size, partitioning may | ||
48 | * need to be changed. | ||
49 | */ | ||
50 | #define NAND_BLOCK_SIZE SZ_128K | ||
51 | |||
52 | static struct mtd_partition davinci_nand_partitions[] = { | ||
53 | { | ||
54 | /* UBL (a few copies) plus U-Boot */ | ||
55 | .name = "bootloader", | ||
56 | .offset = 0, | ||
57 | .size = 15 * NAND_BLOCK_SIZE, | ||
58 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
59 | }, { | ||
60 | /* U-Boot environment */ | ||
61 | .name = "params", | ||
62 | .offset = MTDPART_OFS_APPEND, | ||
63 | .size = 1 * NAND_BLOCK_SIZE, | ||
64 | .mask_flags = 0, | ||
65 | }, { | ||
66 | .name = "kernel", | ||
67 | .offset = MTDPART_OFS_APPEND, | ||
68 | .size = SZ_4M, | ||
69 | .mask_flags = 0, | ||
70 | }, { | ||
71 | .name = "filesystem1", | ||
72 | .offset = MTDPART_OFS_APPEND, | ||
73 | .size = SZ_512M, | ||
74 | .mask_flags = 0, | ||
75 | }, { | ||
76 | .name = "filesystem2", | ||
77 | .offset = MTDPART_OFS_APPEND, | ||
78 | .size = MTDPART_SIZ_FULL, | ||
79 | .mask_flags = 0, | ||
80 | } | ||
81 | /* two blocks with bad block table (and mirror) at the end */ | ||
82 | }; | ||
83 | |||
84 | static struct davinci_nand_pdata davinci_nand_data = { | ||
85 | .mask_chipsel = BIT(14), | ||
86 | .parts = davinci_nand_partitions, | ||
87 | .nr_parts = ARRAY_SIZE(davinci_nand_partitions), | ||
88 | .ecc_mode = NAND_ECC_HW_SYNDROME, | ||
89 | .options = NAND_USE_FLASH_BBT, | ||
90 | }; | ||
91 | |||
92 | static struct resource davinci_nand_resources[] = { | ||
93 | { | ||
94 | .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, | ||
95 | .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, | ||
96 | .flags = IORESOURCE_MEM, | ||
97 | }, { | ||
98 | .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, | ||
99 | .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, | ||
100 | .flags = IORESOURCE_MEM, | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static struct platform_device davinci_nand_device = { | ||
105 | .name = "davinci_nand", | ||
106 | .id = 0, | ||
107 | |||
108 | .num_resources = ARRAY_SIZE(davinci_nand_resources), | ||
109 | .resource = davinci_nand_resources, | ||
110 | |||
111 | .dev = { | ||
112 | .platform_data = &davinci_nand_data, | ||
113 | }, | ||
114 | }; | ||
115 | |||
116 | static struct davinci_i2c_platform_data i2c_pdata = { | ||
117 | .bus_freq = 400 /* kHz */, | ||
118 | .bus_delay = 0 /* usec */, | ||
119 | }; | ||
120 | |||
121 | static int dm355evm_mmc_gpios = -EINVAL; | ||
122 | |||
123 | static void dm355evm_mmcsd_gpios(unsigned gpio) | ||
124 | { | ||
125 | gpio_request(gpio + 0, "mmc0_ro"); | ||
126 | gpio_request(gpio + 1, "mmc0_cd"); | ||
127 | gpio_request(gpio + 2, "mmc1_ro"); | ||
128 | gpio_request(gpio + 3, "mmc1_cd"); | ||
129 | |||
130 | /* we "know" these are input-only so we don't | ||
131 | * need to call gpio_direction_input() | ||
132 | */ | ||
133 | |||
134 | dm355evm_mmc_gpios = gpio; | ||
135 | } | ||
136 | |||
137 | static struct i2c_board_info dm355evm_i2c_info[] = { | ||
138 | { I2C_BOARD_INFO("dm355evm_msp", 0x25), | ||
139 | .platform_data = dm355evm_mmcsd_gpios, | ||
140 | /* plus irq */ }, | ||
141 | /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */ | ||
142 | /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */ | ||
143 | }; | ||
144 | |||
145 | static void __init evm_init_i2c(void) | ||
146 | { | ||
147 | davinci_init_i2c(&i2c_pdata); | ||
148 | |||
149 | gpio_request(5, "dm355evm_msp"); | ||
150 | gpio_direction_input(5); | ||
151 | dm355evm_i2c_info[0].irq = gpio_to_irq(5); | ||
152 | |||
153 | i2c_register_board_info(1, dm355evm_i2c_info, | ||
154 | ARRAY_SIZE(dm355evm_i2c_info)); | ||
155 | } | ||
156 | |||
157 | static struct resource dm355evm_dm9000_rsrc[] = { | ||
158 | { | ||
159 | /* addr */ | ||
160 | .start = 0x04014000, | ||
161 | .end = 0x04014001, | ||
162 | .flags = IORESOURCE_MEM, | ||
163 | }, { | ||
164 | /* data */ | ||
165 | .start = 0x04014002, | ||
166 | .end = 0x04014003, | ||
167 | .flags = IORESOURCE_MEM, | ||
168 | }, { | ||
169 | .flags = IORESOURCE_IRQ | ||
170 | | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */, | ||
171 | }, | ||
172 | }; | ||
173 | |||
174 | static struct platform_device dm355evm_dm9000 = { | ||
175 | .name = "dm9000", | ||
176 | .id = -1, | ||
177 | .resource = dm355evm_dm9000_rsrc, | ||
178 | .num_resources = ARRAY_SIZE(dm355evm_dm9000_rsrc), | ||
179 | }; | ||
180 | |||
181 | static struct platform_device *davinci_evm_devices[] __initdata = { | ||
182 | &dm355evm_dm9000, | ||
183 | &davinci_nand_device, | ||
184 | }; | ||
185 | |||
186 | static struct davinci_uart_config uart_config __initdata = { | ||
187 | .enabled_uarts = (1 << 0), | ||
188 | }; | ||
189 | |||
190 | static void __init dm355_evm_map_io(void) | ||
191 | { | ||
192 | dm355_init(); | ||
193 | } | ||
194 | |||
195 | static int dm355evm_mmc_get_cd(int module) | ||
196 | { | ||
197 | if (!gpio_is_valid(dm355evm_mmc_gpios)) | ||
198 | return -ENXIO; | ||
199 | /* low == card present */ | ||
200 | return !gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 1); | ||
201 | } | ||
202 | |||
203 | static int dm355evm_mmc_get_ro(int module) | ||
204 | { | ||
205 | if (!gpio_is_valid(dm355evm_mmc_gpios)) | ||
206 | return -ENXIO; | ||
207 | /* high == card's write protect switch active */ | ||
208 | return gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 0); | ||
209 | } | ||
210 | |||
211 | static struct davinci_mmc_config dm355evm_mmc_config = { | ||
212 | .get_cd = dm355evm_mmc_get_cd, | ||
213 | .get_ro = dm355evm_mmc_get_ro, | ||
214 | .wires = 4, | ||
215 | .max_freq = 50000000, | ||
216 | .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, | ||
217 | .version = MMC_CTLR_VERSION_1, | ||
218 | }; | ||
219 | |||
220 | /* Don't connect anything to J10 unless you're only using USB host | ||
221 | * mode *and* have to do so with some kind of gender-bender. If | ||
222 | * you have proper Mini-B or Mini-A cables (or Mini-A adapters) | ||
223 | * the ID pin won't need any help. | ||
224 | */ | ||
225 | #ifdef CONFIG_USB_MUSB_PERIPHERAL | ||
226 | #define USB_ID_VALUE 0 /* ID pulled high; *should* float */ | ||
227 | #else | ||
228 | #define USB_ID_VALUE 1 /* ID pulled low */ | ||
229 | #endif | ||
230 | |||
231 | static struct spi_eeprom at25640a = { | ||
232 | .byte_len = SZ_64K / 8, | ||
233 | .name = "at25640a", | ||
234 | .page_size = 32, | ||
235 | .flags = EE_ADDR2, | ||
236 | }; | ||
237 | |||
238 | static struct spi_board_info dm355_evm_spi_info[] __initconst = { | ||
239 | { | ||
240 | .modalias = "at25", | ||
241 | .platform_data = &at25640a, | ||
242 | .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */ | ||
243 | .bus_num = 0, | ||
244 | .chip_select = 0, | ||
245 | .mode = SPI_MODE_0, | ||
246 | }, | ||
247 | }; | ||
248 | |||
249 | static __init void dm355_evm_init(void) | ||
250 | { | ||
251 | struct clk *aemif; | ||
252 | |||
253 | gpio_request(1, "dm9000"); | ||
254 | gpio_direction_input(1); | ||
255 | dm355evm_dm9000_rsrc[2].start = gpio_to_irq(1); | ||
256 | |||
257 | aemif = clk_get(&dm355evm_dm9000.dev, "aemif"); | ||
258 | if (IS_ERR(aemif)) | ||
259 | WARN("%s: unable to get AEMIF clock\n", __func__); | ||
260 | else | ||
261 | clk_enable(aemif); | ||
262 | |||
263 | platform_add_devices(davinci_evm_devices, | ||
264 | ARRAY_SIZE(davinci_evm_devices)); | ||
265 | evm_init_i2c(); | ||
266 | davinci_serial_init(&uart_config); | ||
267 | |||
268 | /* NOTE: NAND flash timings set by the UBL are slower than | ||
269 | * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204 | ||
270 | * but could be 0x0400008c for about 25% faster page reads. | ||
271 | */ | ||
272 | |||
273 | gpio_request(2, "usb_id_toggle"); | ||
274 | gpio_direction_output(2, USB_ID_VALUE); | ||
275 | /* irlml6401 switches over 1A in under 8 msec */ | ||
276 | setup_usb(500, 8); | ||
277 | |||
278 | davinci_setup_mmc(0, &dm355evm_mmc_config); | ||
279 | davinci_setup_mmc(1, &dm355evm_mmc_config); | ||
280 | |||
281 | dm355_init_spi0(BIT(0), dm355_evm_spi_info, | ||
282 | ARRAY_SIZE(dm355_evm_spi_info)); | ||
283 | } | ||
284 | |||
285 | static __init void dm355_evm_irq_init(void) | ||
286 | { | ||
287 | davinci_irq_init(); | ||
288 | } | ||
289 | |||
290 | MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") | ||
291 | .phys_io = IO_PHYS, | ||
292 | .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, | ||
293 | .boot_params = (0x80000100), | ||
294 | .map_io = dm355_evm_map_io, | ||
295 | .init_irq = dm355_evm_irq_init, | ||
296 | .timer = &davinci_timer, | ||
297 | .init_machine = dm355_evm_init, | ||
298 | MACHINE_END | ||
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c new file mode 100644 index 000000000000..28c9008df4f4 --- /dev/null +++ b/arch/arm/mach-davinci/board-dm355-leopard.c | |||
@@ -0,0 +1,296 @@ | |||
1 | /* | ||
2 | * DM355 leopard board support | ||
3 | * | ||
4 | * Based on board-dm355-evm.c | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/dma-mapping.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/mtd/mtd.h> | ||
16 | #include <linux/mtd/partitions.h> | ||
17 | #include <linux/mtd/nand.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/spi/spi.h> | ||
23 | #include <linux/spi/eeprom.h> | ||
24 | |||
25 | #include <asm/setup.h> | ||
26 | #include <asm/mach-types.h> | ||
27 | #include <asm/mach/arch.h> | ||
28 | #include <asm/mach/map.h> | ||
29 | #include <asm/mach/flash.h> | ||
30 | |||
31 | #include <mach/hardware.h> | ||
32 | #include <mach/dm355.h> | ||
33 | #include <mach/psc.h> | ||
34 | #include <mach/common.h> | ||
35 | #include <mach/i2c.h> | ||
36 | #include <mach/serial.h> | ||
37 | #include <mach/nand.h> | ||
38 | #include <mach/mmc.h> | ||
39 | #include <mach/common.h> | ||
40 | |||
41 | #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 | ||
42 | #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 | ||
43 | |||
44 | /* NOTE: this is geared for the standard config, with a socketed | ||
45 | * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you | ||
46 | * swap chips, maybe with a different block size, partitioning may | ||
47 | * need to be changed. | ||
48 | */ | ||
49 | #define NAND_BLOCK_SIZE SZ_128K | ||
50 | |||
51 | static struct mtd_partition davinci_nand_partitions[] = { | ||
52 | { | ||
53 | /* UBL (a few copies) plus U-Boot */ | ||
54 | .name = "bootloader", | ||
55 | .offset = 0, | ||
56 | .size = 15 * NAND_BLOCK_SIZE, | ||
57 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
58 | }, { | ||
59 | /* U-Boot environment */ | ||
60 | .name = "params", | ||
61 | .offset = MTDPART_OFS_APPEND, | ||
62 | .size = 1 * NAND_BLOCK_SIZE, | ||
63 | .mask_flags = 0, | ||
64 | }, { | ||
65 | .name = "kernel", | ||
66 | .offset = MTDPART_OFS_APPEND, | ||
67 | .size = SZ_4M, | ||
68 | .mask_flags = 0, | ||
69 | }, { | ||
70 | .name = "filesystem1", | ||
71 | .offset = MTDPART_OFS_APPEND, | ||
72 | .size = SZ_512M, | ||
73 | .mask_flags = 0, | ||
74 | }, { | ||
75 | .name = "filesystem2", | ||
76 | .offset = MTDPART_OFS_APPEND, | ||
77 | .size = MTDPART_SIZ_FULL, | ||
78 | .mask_flags = 0, | ||
79 | } | ||
80 | /* two blocks with bad block table (and mirror) at the end */ | ||
81 | }; | ||
82 | |||
83 | static struct davinci_nand_pdata davinci_nand_data = { | ||
84 | .mask_chipsel = BIT(14), | ||
85 | .parts = davinci_nand_partitions, | ||
86 | .nr_parts = ARRAY_SIZE(davinci_nand_partitions), | ||
87 | .ecc_mode = NAND_ECC_HW_SYNDROME, | ||
88 | .options = NAND_USE_FLASH_BBT, | ||
89 | }; | ||
90 | |||
91 | static struct resource davinci_nand_resources[] = { | ||
92 | { | ||
93 | .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, | ||
94 | .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, | ||
95 | .flags = IORESOURCE_MEM, | ||
96 | }, { | ||
97 | .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, | ||
98 | .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, | ||
99 | .flags = IORESOURCE_MEM, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static struct platform_device davinci_nand_device = { | ||
104 | .name = "davinci_nand", | ||
105 | .id = 0, | ||
106 | |||
107 | .num_resources = ARRAY_SIZE(davinci_nand_resources), | ||
108 | .resource = davinci_nand_resources, | ||
109 | |||
110 | .dev = { | ||
111 | .platform_data = &davinci_nand_data, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | static struct davinci_i2c_platform_data i2c_pdata = { | ||
116 | .bus_freq = 400 /* kHz */, | ||
117 | .bus_delay = 0 /* usec */, | ||
118 | }; | ||
119 | |||
120 | static int leopard_mmc_gpio = -EINVAL; | ||
121 | |||
122 | static void dm355leopard_mmcsd_gpios(unsigned gpio) | ||
123 | { | ||
124 | gpio_request(gpio + 0, "mmc0_ro"); | ||
125 | gpio_request(gpio + 1, "mmc0_cd"); | ||
126 | gpio_request(gpio + 2, "mmc1_ro"); | ||
127 | gpio_request(gpio + 3, "mmc1_cd"); | ||
128 | |||
129 | /* we "know" these are input-only so we don't | ||
130 | * need to call gpio_direction_input() | ||
131 | */ | ||
132 | |||
133 | leopard_mmc_gpio = gpio; | ||
134 | } | ||
135 | |||
136 | static struct i2c_board_info dm355leopard_i2c_info[] = { | ||
137 | { I2C_BOARD_INFO("dm355leopard_msp", 0x25), | ||
138 | .platform_data = dm355leopard_mmcsd_gpios, | ||
139 | /* plus irq */ }, | ||
140 | /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */ | ||
141 | /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */ | ||
142 | }; | ||
143 | |||
144 | static void __init leopard_init_i2c(void) | ||
145 | { | ||
146 | davinci_init_i2c(&i2c_pdata); | ||
147 | |||
148 | gpio_request(5, "dm355leopard_msp"); | ||
149 | gpio_direction_input(5); | ||
150 | dm355leopard_i2c_info[0].irq = gpio_to_irq(5); | ||
151 | |||
152 | i2c_register_board_info(1, dm355leopard_i2c_info, | ||
153 | ARRAY_SIZE(dm355leopard_i2c_info)); | ||
154 | } | ||
155 | |||
156 | static struct resource dm355leopard_dm9000_rsrc[] = { | ||
157 | { | ||
158 | /* addr */ | ||
159 | .start = 0x04000000, | ||
160 | .end = 0x04000001, | ||
161 | .flags = IORESOURCE_MEM, | ||
162 | }, { | ||
163 | /* data */ | ||
164 | .start = 0x04000016, | ||
165 | .end = 0x04000017, | ||
166 | .flags = IORESOURCE_MEM, | ||
167 | }, { | ||
168 | .flags = IORESOURCE_IRQ | ||
169 | | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */, | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | static struct platform_device dm355leopard_dm9000 = { | ||
174 | .name = "dm9000", | ||
175 | .id = -1, | ||
176 | .resource = dm355leopard_dm9000_rsrc, | ||
177 | .num_resources = ARRAY_SIZE(dm355leopard_dm9000_rsrc), | ||
178 | }; | ||
179 | |||
180 | static struct platform_device *davinci_leopard_devices[] __initdata = { | ||
181 | &dm355leopard_dm9000, | ||
182 | &davinci_nand_device, | ||
183 | }; | ||
184 | |||
185 | static struct davinci_uart_config uart_config __initdata = { | ||
186 | .enabled_uarts = (1 << 0), | ||
187 | }; | ||
188 | |||
189 | static void __init dm355_leopard_map_io(void) | ||
190 | { | ||
191 | dm355_init(); | ||
192 | } | ||
193 | |||
194 | static int dm355leopard_mmc_get_cd(int module) | ||
195 | { | ||
196 | if (!gpio_is_valid(leopard_mmc_gpio)) | ||
197 | return -ENXIO; | ||
198 | /* low == card present */ | ||
199 | return !gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 1); | ||
200 | } | ||
201 | |||
202 | static int dm355leopard_mmc_get_ro(int module) | ||
203 | { | ||
204 | if (!gpio_is_valid(leopard_mmc_gpio)) | ||
205 | return -ENXIO; | ||
206 | /* high == card's write protect switch active */ | ||
207 | return gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 0); | ||
208 | } | ||
209 | |||
210 | static struct davinci_mmc_config dm355leopard_mmc_config = { | ||
211 | .get_cd = dm355leopard_mmc_get_cd, | ||
212 | .get_ro = dm355leopard_mmc_get_ro, | ||
213 | .wires = 4, | ||
214 | .max_freq = 50000000, | ||
215 | .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, | ||
216 | }; | ||
217 | |||
218 | /* Don't connect anything to J10 unless you're only using USB host | ||
219 | * mode *and* have to do so with some kind of gender-bender. If | ||
220 | * you have proper Mini-B or Mini-A cables (or Mini-A adapters) | ||
221 | * the ID pin won't need any help. | ||
222 | */ | ||
223 | #ifdef CONFIG_USB_MUSB_PERIPHERAL | ||
224 | #define USB_ID_VALUE 0 /* ID pulled high; *should* float */ | ||
225 | #else | ||
226 | #define USB_ID_VALUE 1 /* ID pulled low */ | ||
227 | #endif | ||
228 | |||
229 | static struct spi_eeprom at25640a = { | ||
230 | .byte_len = SZ_64K / 8, | ||
231 | .name = "at25640a", | ||
232 | .page_size = 32, | ||
233 | .flags = EE_ADDR2, | ||
234 | }; | ||
235 | |||
236 | static struct spi_board_info dm355_leopard_spi_info[] __initconst = { | ||
237 | { | ||
238 | .modalias = "at25", | ||
239 | .platform_data = &at25640a, | ||
240 | .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */ | ||
241 | .bus_num = 0, | ||
242 | .chip_select = 0, | ||
243 | .mode = SPI_MODE_0, | ||
244 | }, | ||
245 | }; | ||
246 | |||
247 | static __init void dm355_leopard_init(void) | ||
248 | { | ||
249 | struct clk *aemif; | ||
250 | |||
251 | gpio_request(9, "dm9000"); | ||
252 | gpio_direction_input(9); | ||
253 | dm355leopard_dm9000_rsrc[2].start = gpio_to_irq(9); | ||
254 | |||
255 | aemif = clk_get(&dm355leopard_dm9000.dev, "aemif"); | ||
256 | if (IS_ERR(aemif)) | ||
257 | WARN("%s: unable to get AEMIF clock\n", __func__); | ||
258 | else | ||
259 | clk_enable(aemif); | ||
260 | |||
261 | platform_add_devices(davinci_leopard_devices, | ||
262 | ARRAY_SIZE(davinci_leopard_devices)); | ||
263 | leopard_init_i2c(); | ||
264 | davinci_serial_init(&uart_config); | ||
265 | |||
266 | /* NOTE: NAND flash timings set by the UBL are slower than | ||
267 | * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204 | ||
268 | * but could be 0x0400008c for about 25% faster page reads. | ||
269 | */ | ||
270 | |||
271 | gpio_request(2, "usb_id_toggle"); | ||
272 | gpio_direction_output(2, USB_ID_VALUE); | ||
273 | /* irlml6401 switches over 1A in under 8 msec */ | ||
274 | setup_usb(500, 8); | ||
275 | |||
276 | davinci_setup_mmc(0, &dm355leopard_mmc_config); | ||
277 | davinci_setup_mmc(1, &dm355leopard_mmc_config); | ||
278 | |||
279 | dm355_init_spi0(BIT(0), dm355_leopard_spi_info, | ||
280 | ARRAY_SIZE(dm355_leopard_spi_info)); | ||
281 | } | ||
282 | |||
283 | static __init void dm355_leopard_irq_init(void) | ||
284 | { | ||
285 | davinci_irq_init(); | ||
286 | } | ||
287 | |||
288 | MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") | ||
289 | .phys_io = IO_PHYS, | ||
290 | .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, | ||
291 | .boot_params = (0x80000100), | ||
292 | .map_io = dm355_leopard_map_io, | ||
293 | .init_irq = dm355_leopard_irq_init, | ||
294 | .timer = &davinci_timer, | ||
295 | .init_machine = dm355_leopard_init, | ||
296 | MACHINE_END | ||
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index b2e7f9c63bc5..d9d40450bdc5 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c | |||
@@ -16,12 +16,11 @@ | |||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/leds.h> | 17 | #include <linux/leds.h> |
18 | #include <linux/memory.h> | 18 | #include <linux/memory.h> |
19 | #include <linux/etherdevice.h> | ||
20 | 19 | ||
21 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
22 | #include <linux/i2c/pcf857x.h> | 21 | #include <linux/i2c/pcf857x.h> |
23 | #include <linux/i2c/at24.h> | 22 | #include <linux/i2c/at24.h> |
24 | 23 | #include <linux/etherdevice.h> | |
25 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
26 | #include <linux/mtd/nand.h> | 25 | #include <linux/mtd/nand.h> |
27 | #include <linux/mtd/partitions.h> | 26 | #include <linux/mtd/partitions.h> |
@@ -44,6 +43,9 @@ | |||
44 | #include <mach/mux.h> | 43 | #include <mach/mux.h> |
45 | #include <mach/psc.h> | 44 | #include <mach/psc.h> |
46 | #include <mach/nand.h> | 45 | #include <mach/nand.h> |
46 | #include <mach/mmc.h> | ||
47 | #include <mach/emac.h> | ||
48 | #include <mach/common.h> | ||
47 | 49 | ||
48 | #define DM644X_EVM_PHY_MASK (0x2) | 50 | #define DM644X_EVM_PHY_MASK (0x2) |
49 | #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ | 51 | #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ |
@@ -436,45 +438,15 @@ static struct pcf857x_platform_data pcf_data_u35 = { | |||
436 | * - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL) | 438 | * - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL) |
437 | * - ... newer boards may have more | 439 | * - ... newer boards may have more |
438 | */ | 440 | */ |
439 | static struct memory_accessor *at24_mem_acc; | ||
440 | |||
441 | static void at24_setup(struct memory_accessor *mem_acc, void *context) | ||
442 | { | ||
443 | DECLARE_MAC_BUF(mac_str); | ||
444 | char mac_addr[6]; | ||
445 | |||
446 | at24_mem_acc = mem_acc; | ||
447 | |||
448 | /* Read MAC addr from EEPROM */ | ||
449 | if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, 6) == 6) { | ||
450 | printk(KERN_INFO "Read MAC addr from EEPROM: %s\n", | ||
451 | print_mac(mac_str, mac_addr)); | ||
452 | } | ||
453 | } | ||
454 | 441 | ||
455 | static struct at24_platform_data eeprom_info = { | 442 | static struct at24_platform_data eeprom_info = { |
456 | .byte_len = (256*1024) / 8, | 443 | .byte_len = (256*1024) / 8, |
457 | .page_size = 64, | 444 | .page_size = 64, |
458 | .flags = AT24_FLAG_ADDR16, | 445 | .flags = AT24_FLAG_ADDR16, |
459 | .setup = at24_setup, | 446 | .setup = davinci_get_mac_addr, |
447 | .context = (void *)0x7f00, | ||
460 | }; | 448 | }; |
461 | 449 | ||
462 | int dm6446evm_eeprom_read(void *buf, off_t off, size_t count) | ||
463 | { | ||
464 | if (at24_mem_acc) | ||
465 | return at24_mem_acc->read(at24_mem_acc, buf, off, count); | ||
466 | return -ENODEV; | ||
467 | } | ||
468 | EXPORT_SYMBOL(dm6446evm_eeprom_read); | ||
469 | |||
470 | int dm6446evm_eeprom_write(void *buf, off_t off, size_t count) | ||
471 | { | ||
472 | if (at24_mem_acc) | ||
473 | return at24_mem_acc->write(at24_mem_acc, buf, off, count); | ||
474 | return -ENODEV; | ||
475 | } | ||
476 | EXPORT_SYMBOL(dm6446evm_eeprom_write); | ||
477 | |||
478 | /* | 450 | /* |
479 | * MSP430 supports RTC, card detection, input from IR remote, and | 451 | * MSP430 supports RTC, card detection, input from IR remote, and |
480 | * a bit more. It triggers interrupts on GPIO(7) from pressing | 452 | * a bit more. It triggers interrupts on GPIO(7) from pressing |
@@ -545,6 +517,27 @@ static int dm6444evm_msp430_get_pins(void) | |||
545 | return (buf[3] << 8) | buf[2]; | 517 | return (buf[3] << 8) | buf[2]; |
546 | } | 518 | } |
547 | 519 | ||
520 | static int dm6444evm_mmc_get_cd(int module) | ||
521 | { | ||
522 | int status = dm6444evm_msp430_get_pins(); | ||
523 | |||
524 | return (status < 0) ? status : !(status & BIT(1)); | ||
525 | } | ||
526 | |||
527 | static int dm6444evm_mmc_get_ro(int module) | ||
528 | { | ||
529 | int status = dm6444evm_msp430_get_pins(); | ||
530 | |||
531 | return (status < 0) ? status : status & BIT(6 + 8); | ||
532 | } | ||
533 | |||
534 | static struct davinci_mmc_config dm6446evm_mmc_config = { | ||
535 | .get_cd = dm6444evm_mmc_get_cd, | ||
536 | .get_ro = dm6444evm_mmc_get_ro, | ||
537 | .wires = 4, | ||
538 | .version = MMC_CTLR_VERSION_1 | ||
539 | }; | ||
540 | |||
548 | static struct i2c_board_info __initdata i2c_info[] = { | 541 | static struct i2c_board_info __initdata i2c_info[] = { |
549 | { | 542 | { |
550 | I2C_BOARD_INFO("dm6446evm_msp", 0x23), | 543 | I2C_BOARD_INFO("dm6446evm_msp", 0x23), |
@@ -598,7 +591,6 @@ static struct davinci_uart_config uart_config __initdata = { | |||
598 | static void __init | 591 | static void __init |
599 | davinci_evm_map_io(void) | 592 | davinci_evm_map_io(void) |
600 | { | 593 | { |
601 | davinci_map_common_io(); | ||
602 | dm644x_init(); | 594 | dm644x_init(); |
603 | } | 595 | } |
604 | 596 | ||
@@ -639,6 +631,7 @@ static int davinci_phy_fixup(struct phy_device *phydev) | |||
639 | static __init void davinci_evm_init(void) | 631 | static __init void davinci_evm_init(void) |
640 | { | 632 | { |
641 | struct clk *aemif_clk; | 633 | struct clk *aemif_clk; |
634 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
642 | 635 | ||
643 | aemif_clk = clk_get(NULL, "aemif"); | 636 | aemif_clk = clk_get(NULL, "aemif"); |
644 | clk_enable(aemif_clk); | 637 | clk_enable(aemif_clk); |
@@ -671,8 +664,13 @@ static __init void davinci_evm_init(void) | |||
671 | ARRAY_SIZE(davinci_evm_devices)); | 664 | ARRAY_SIZE(davinci_evm_devices)); |
672 | evm_init_i2c(); | 665 | evm_init_i2c(); |
673 | 666 | ||
667 | davinci_setup_mmc(0, &dm6446evm_mmc_config); | ||
668 | |||
674 | davinci_serial_init(&uart_config); | 669 | davinci_serial_init(&uart_config); |
675 | 670 | ||
671 | soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK; | ||
672 | soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY; | ||
673 | |||
676 | /* Register the fixup for PHY on DaVinci */ | 674 | /* Register the fixup for PHY on DaVinci */ |
677 | phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, | 675 | phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, |
678 | davinci_phy_fixup); | 676 | davinci_phy_fixup); |
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c new file mode 100644 index 000000000000..e17de6352624 --- /dev/null +++ b/arch/arm/mach-davinci/board-dm646x-evm.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * TI DaVinci DM646X EVM board | ||
3 | * | ||
4 | * Derived from: arch/arm/mach-davinci/board-evm.c | ||
5 | * Copyright (C) 2006 Texas Instruments. | ||
6 | * | ||
7 | * (C) 2007-2008, MontaVista Software, Inc. | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public License | ||
10 | * version 2. This program is licensed "as is" without any warranty of any | ||
11 | * kind, whether express or implied. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | /************************************************************************** | ||
16 | * Included Files | ||
17 | **************************************************************************/ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/major.h> | ||
24 | #include <linux/root_dev.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | #include <linux/serial.h> | ||
27 | #include <linux/serial_8250.h> | ||
28 | #include <linux/leds.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/i2c.h> | ||
33 | #include <linux/i2c/at24.h> | ||
34 | #include <linux/i2c/pcf857x.h> | ||
35 | #include <linux/etherdevice.h> | ||
36 | |||
37 | #include <asm/setup.h> | ||
38 | #include <asm/mach-types.h> | ||
39 | #include <asm/mach/arch.h> | ||
40 | #include <asm/mach/map.h> | ||
41 | #include <asm/mach/flash.h> | ||
42 | |||
43 | #include <mach/dm646x.h> | ||
44 | #include <mach/common.h> | ||
45 | #include <mach/psc.h> | ||
46 | #include <mach/serial.h> | ||
47 | #include <mach/i2c.h> | ||
48 | #include <mach/mmc.h> | ||
49 | #include <mach/emac.h> | ||
50 | #include <mach/common.h> | ||
51 | |||
52 | #define DM646X_EVM_PHY_MASK (0x2) | ||
53 | #define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ | ||
54 | |||
55 | static struct davinci_uart_config uart_config __initdata = { | ||
56 | .enabled_uarts = (1 << 0), | ||
57 | }; | ||
58 | |||
59 | /* LEDS */ | ||
60 | |||
61 | static struct gpio_led evm_leds[] = { | ||
62 | { .name = "DS1", .active_low = 1, }, | ||
63 | { .name = "DS2", .active_low = 1, }, | ||
64 | { .name = "DS3", .active_low = 1, }, | ||
65 | { .name = "DS4", .active_low = 1, }, | ||
66 | }; | ||
67 | |||
68 | static __initconst struct gpio_led_platform_data evm_led_data = { | ||
69 | .num_leds = ARRAY_SIZE(evm_leds), | ||
70 | .leds = evm_leds, | ||
71 | }; | ||
72 | |||
73 | static struct platform_device *evm_led_dev; | ||
74 | |||
75 | static int evm_led_setup(struct i2c_client *client, int gpio, | ||
76 | unsigned int ngpio, void *c) | ||
77 | { | ||
78 | struct gpio_led *leds = evm_leds; | ||
79 | int status; | ||
80 | |||
81 | while (ngpio--) { | ||
82 | leds->gpio = gpio++; | ||
83 | leds++; | ||
84 | }; | ||
85 | |||
86 | evm_led_dev = platform_device_alloc("leds-gpio", 0); | ||
87 | platform_device_add_data(evm_led_dev, &evm_led_data, | ||
88 | sizeof(evm_led_data)); | ||
89 | |||
90 | evm_led_dev->dev.parent = &client->dev; | ||
91 | status = platform_device_add(evm_led_dev); | ||
92 | if (status < 0) { | ||
93 | platform_device_put(evm_led_dev); | ||
94 | evm_led_dev = NULL; | ||
95 | } | ||
96 | return status; | ||
97 | } | ||
98 | |||
99 | static int evm_led_teardown(struct i2c_client *client, int gpio, | ||
100 | unsigned ngpio, void *c) | ||
101 | { | ||
102 | if (evm_led_dev) { | ||
103 | platform_device_unregister(evm_led_dev); | ||
104 | evm_led_dev = NULL; | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL }; | ||
110 | |||
111 | static int evm_sw_setup(struct i2c_client *client, int gpio, | ||
112 | unsigned ngpio, void *c) | ||
113 | { | ||
114 | int status; | ||
115 | int i; | ||
116 | char label[10]; | ||
117 | |||
118 | for (i = 0; i < 4; ++i) { | ||
119 | snprintf(label, 10, "user_sw%d", i); | ||
120 | status = gpio_request(gpio, label); | ||
121 | if (status) | ||
122 | goto out_free; | ||
123 | evm_sw_gpio[i] = gpio++; | ||
124 | |||
125 | status = gpio_direction_input(evm_sw_gpio[i]); | ||
126 | if (status) { | ||
127 | gpio_free(evm_sw_gpio[i]); | ||
128 | evm_sw_gpio[i] = -EINVAL; | ||
129 | goto out_free; | ||
130 | } | ||
131 | |||
132 | status = gpio_export(evm_sw_gpio[i], 0); | ||
133 | if (status) { | ||
134 | gpio_free(evm_sw_gpio[i]); | ||
135 | evm_sw_gpio[i] = -EINVAL; | ||
136 | goto out_free; | ||
137 | } | ||
138 | } | ||
139 | return status; | ||
140 | out_free: | ||
141 | for (i = 0; i < 4; ++i) { | ||
142 | if (evm_sw_gpio[i] != -EINVAL) { | ||
143 | gpio_free(evm_sw_gpio[i]); | ||
144 | evm_sw_gpio[i] = -EINVAL; | ||
145 | } | ||
146 | } | ||
147 | return status; | ||
148 | } | ||
149 | |||
150 | static int evm_sw_teardown(struct i2c_client *client, int gpio, | ||
151 | unsigned ngpio, void *c) | ||
152 | { | ||
153 | int i; | ||
154 | |||
155 | for (i = 0; i < 4; ++i) { | ||
156 | if (evm_sw_gpio[i] != -EINVAL) { | ||
157 | gpio_unexport(evm_sw_gpio[i]); | ||
158 | gpio_free(evm_sw_gpio[i]); | ||
159 | evm_sw_gpio[i] = -EINVAL; | ||
160 | } | ||
161 | } | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int evm_pcf_setup(struct i2c_client *client, int gpio, | ||
166 | unsigned int ngpio, void *c) | ||
167 | { | ||
168 | int status; | ||
169 | |||
170 | if (ngpio < 8) | ||
171 | return -EINVAL; | ||
172 | |||
173 | status = evm_sw_setup(client, gpio, 4, c); | ||
174 | if (status) | ||
175 | return status; | ||
176 | |||
177 | return evm_led_setup(client, gpio+4, 4, c); | ||
178 | } | ||
179 | |||
180 | static int evm_pcf_teardown(struct i2c_client *client, int gpio, | ||
181 | unsigned int ngpio, void *c) | ||
182 | { | ||
183 | BUG_ON(ngpio < 8); | ||
184 | |||
185 | evm_sw_teardown(client, gpio, 4, c); | ||
186 | evm_led_teardown(client, gpio+4, 4, c); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static struct pcf857x_platform_data pcf_data = { | ||
192 | .gpio_base = DAVINCI_N_GPIO+1, | ||
193 | .setup = evm_pcf_setup, | ||
194 | .teardown = evm_pcf_teardown, | ||
195 | }; | ||
196 | |||
197 | /* Most of this EEPROM is unused, but U-Boot uses some data: | ||
198 | * - 0x7f00, 6 bytes Ethernet Address | ||
199 | * - ... newer boards may have more | ||
200 | */ | ||
201 | |||
202 | static struct at24_platform_data eeprom_info = { | ||
203 | .byte_len = (256*1024) / 8, | ||
204 | .page_size = 64, | ||
205 | .flags = AT24_FLAG_ADDR16, | ||
206 | .setup = davinci_get_mac_addr, | ||
207 | .context = (void *)0x7f00, | ||
208 | }; | ||
209 | |||
210 | static struct i2c_board_info __initdata i2c_info[] = { | ||
211 | { | ||
212 | I2C_BOARD_INFO("24c256", 0x50), | ||
213 | .platform_data = &eeprom_info, | ||
214 | }, | ||
215 | { | ||
216 | I2C_BOARD_INFO("pcf8574a", 0x38), | ||
217 | .platform_data = &pcf_data, | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | static struct davinci_i2c_platform_data i2c_pdata = { | ||
222 | .bus_freq = 100 /* kHz */, | ||
223 | .bus_delay = 0 /* usec */, | ||
224 | }; | ||
225 | |||
226 | static void __init evm_init_i2c(void) | ||
227 | { | ||
228 | davinci_init_i2c(&i2c_pdata); | ||
229 | i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); | ||
230 | } | ||
231 | |||
232 | static void __init davinci_map_io(void) | ||
233 | { | ||
234 | dm646x_init(); | ||
235 | } | ||
236 | |||
237 | static __init void evm_init(void) | ||
238 | { | ||
239 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
240 | |||
241 | evm_init_i2c(); | ||
242 | davinci_serial_init(&uart_config); | ||
243 | |||
244 | soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK; | ||
245 | soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY; | ||
246 | } | ||
247 | |||
248 | static __init void davinci_dm646x_evm_irq_init(void) | ||
249 | { | ||
250 | davinci_irq_init(); | ||
251 | } | ||
252 | |||
253 | MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") | ||
254 | .phys_io = IO_PHYS, | ||
255 | .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, | ||
256 | .boot_params = (0x80000100), | ||
257 | .map_io = davinci_map_io, | ||
258 | .init_irq = davinci_dm646x_evm_irq_init, | ||
259 | .timer = &davinci_timer, | ||
260 | .init_machine = evm_init, | ||
261 | MACHINE_END | ||
262 | |||
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c new file mode 100644 index 000000000000..748a8e48541e --- /dev/null +++ b/arch/arm/mach-davinci/board-sffsdr.c | |||
@@ -0,0 +1,189 @@ | |||
1 | /* | ||
2 | * Lyrtech SFFSDR board support. | ||
3 | * | ||
4 | * Copyright (C) 2008 Philip Balister, OpenSDR <philip@opensdr.com> | ||
5 | * Copyright (C) 2008 Lyrtech <www.lyrtech.com> | ||
6 | * | ||
7 | * Based on DV-EVM platform, original copyright follows: | ||
8 | * | ||
9 | * Copyright (C) 2007 MontaVista Software, Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/dma-mapping.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/gpio.h> | ||
32 | |||
33 | #include <linux/i2c.h> | ||
34 | #include <linux/i2c/at24.h> | ||
35 | #include <linux/etherdevice.h> | ||
36 | #include <linux/mtd/mtd.h> | ||
37 | #include <linux/mtd/nand.h> | ||
38 | #include <linux/mtd/partitions.h> | ||
39 | #include <linux/mtd/physmap.h> | ||
40 | #include <linux/io.h> | ||
41 | |||
42 | #include <asm/setup.h> | ||
43 | #include <asm/mach-types.h> | ||
44 | |||
45 | #include <asm/mach/arch.h> | ||
46 | #include <asm/mach/map.h> | ||
47 | #include <asm/mach/flash.h> | ||
48 | |||
49 | #include <mach/dm644x.h> | ||
50 | #include <mach/common.h> | ||
51 | #include <mach/i2c.h> | ||
52 | #include <mach/serial.h> | ||
53 | #include <mach/psc.h> | ||
54 | #include <mach/mux.h> | ||
55 | #include <mach/common.h> | ||
56 | |||
57 | #define SFFSDR_PHY_MASK (0x2) | ||
58 | #define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ | ||
59 | |||
60 | #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000 | ||
61 | #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 | ||
62 | |||
63 | struct mtd_partition davinci_sffsdr_nandflash_partition[] = { | ||
64 | /* U-Boot Environment: Block 0 | ||
65 | * UBL: Block 1 | ||
66 | * U-Boot: Blocks 6-7 (256 kb) | ||
67 | * Integrity Kernel: Blocks 8-31 (3 Mb) | ||
68 | * Integrity Data: Blocks 100-END | ||
69 | */ | ||
70 | { | ||
71 | .name = "Linux Kernel", | ||
72 | .offset = 32 * SZ_128K, | ||
73 | .size = 16 * SZ_128K, /* 2 Mb */ | ||
74 | .mask_flags = MTD_WRITEABLE, /* Force read-only */ | ||
75 | }, | ||
76 | { | ||
77 | .name = "Linux ROOT", | ||
78 | .offset = MTDPART_OFS_APPEND, | ||
79 | .size = 256 * SZ_128K, /* 32 Mb */ | ||
80 | .mask_flags = 0, /* R/W */ | ||
81 | }, | ||
82 | }; | ||
83 | |||
84 | static struct flash_platform_data davinci_sffsdr_nandflash_data = { | ||
85 | .parts = davinci_sffsdr_nandflash_partition, | ||
86 | .nr_parts = ARRAY_SIZE(davinci_sffsdr_nandflash_partition), | ||
87 | }; | ||
88 | |||
89 | static struct resource davinci_sffsdr_nandflash_resource[] = { | ||
90 | { | ||
91 | .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, | ||
92 | .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, | ||
93 | .flags = IORESOURCE_MEM, | ||
94 | }, { | ||
95 | .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, | ||
96 | .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, | ||
97 | .flags = IORESOURCE_MEM, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | static struct platform_device davinci_sffsdr_nandflash_device = { | ||
102 | .name = "davinci_nand", /* Name of driver */ | ||
103 | .id = 0, | ||
104 | .dev = { | ||
105 | .platform_data = &davinci_sffsdr_nandflash_data, | ||
106 | }, | ||
107 | .num_resources = ARRAY_SIZE(davinci_sffsdr_nandflash_resource), | ||
108 | .resource = davinci_sffsdr_nandflash_resource, | ||
109 | }; | ||
110 | |||
111 | static struct emac_platform_data sffsdr_emac_pdata = { | ||
112 | .phy_mask = SFFSDR_PHY_MASK, | ||
113 | .mdio_max_freq = SFFSDR_MDIO_FREQUENCY, | ||
114 | }; | ||
115 | |||
116 | static struct at24_platform_data eeprom_info = { | ||
117 | .byte_len = (64*1024) / 8, | ||
118 | .page_size = 32, | ||
119 | .flags = AT24_FLAG_ADDR16, | ||
120 | }; | ||
121 | |||
122 | static struct i2c_board_info __initdata i2c_info[] = { | ||
123 | { | ||
124 | I2C_BOARD_INFO("24lc64", 0x50), | ||
125 | .platform_data = &eeprom_info, | ||
126 | }, | ||
127 | /* Other I2C devices: | ||
128 | * MSP430, addr 0x23 (not used) | ||
129 | * PCA9543, addr 0x70 (setup done by U-Boot) | ||
130 | * ADS7828, addr 0x48 (ADC for voltage monitoring.) | ||
131 | */ | ||
132 | }; | ||
133 | |||
134 | static struct davinci_i2c_platform_data i2c_pdata = { | ||
135 | .bus_freq = 20 /* kHz */, | ||
136 | .bus_delay = 100 /* usec */, | ||
137 | }; | ||
138 | |||
139 | static void __init sffsdr_init_i2c(void) | ||
140 | { | ||
141 | davinci_init_i2c(&i2c_pdata); | ||
142 | i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); | ||
143 | } | ||
144 | |||
145 | static struct platform_device *davinci_sffsdr_devices[] __initdata = { | ||
146 | &davinci_sffsdr_nandflash_device, | ||
147 | }; | ||
148 | |||
149 | static struct davinci_uart_config uart_config __initdata = { | ||
150 | .enabled_uarts = (1 << 0), | ||
151 | }; | ||
152 | |||
153 | static void __init davinci_sffsdr_map_io(void) | ||
154 | { | ||
155 | dm644x_init(); | ||
156 | } | ||
157 | |||
158 | static __init void davinci_sffsdr_init(void) | ||
159 | { | ||
160 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
161 | |||
162 | platform_add_devices(davinci_sffsdr_devices, | ||
163 | ARRAY_SIZE(davinci_sffsdr_devices)); | ||
164 | sffsdr_init_i2c(); | ||
165 | davinci_serial_init(&uart_config); | ||
166 | soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK; | ||
167 | soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY; | ||
168 | setup_usb(0, 0); /* We support only peripheral mode. */ | ||
169 | |||
170 | /* mux VLYNQ pins */ | ||
171 | davinci_cfg_reg(DM644X_VLYNQEN); | ||
172 | davinci_cfg_reg(DM644X_VLYNQWD); | ||
173 | } | ||
174 | |||
175 | static __init void davinci_sffsdr_irq_init(void) | ||
176 | { | ||
177 | davinci_irq_init(); | ||
178 | } | ||
179 | |||
180 | MACHINE_START(SFFSDR, "Lyrtech SFFSDR") | ||
181 | /* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */ | ||
182 | .phys_io = IO_PHYS, | ||
183 | .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, | ||
184 | .boot_params = (DAVINCI_DDR_BASE + 0x100), | ||
185 | .map_io = davinci_sffsdr_map_io, | ||
186 | .init_irq = davinci_sffsdr_irq_init, | ||
187 | .timer = &davinci_timer, | ||
188 | .init_machine = davinci_sffsdr_init, | ||
189 | MACHINE_END | ||
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index f0baaa15a57e..39bf321d70a2 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c | |||
@@ -42,7 +42,8 @@ static void __clk_enable(struct clk *clk) | |||
42 | if (clk->parent) | 42 | if (clk->parent) |
43 | __clk_enable(clk->parent); | 43 | __clk_enable(clk->parent); |
44 | if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) | 44 | if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) |
45 | davinci_psc_config(psc_domain(clk), clk->lpsc, 1); | 45 | davinci_psc_config(psc_domain(clk), clk->psc_ctlr, |
46 | clk->lpsc, 1); | ||
46 | } | 47 | } |
47 | 48 | ||
48 | static void __clk_disable(struct clk *clk) | 49 | static void __clk_disable(struct clk *clk) |
@@ -50,7 +51,8 @@ static void __clk_disable(struct clk *clk) | |||
50 | if (WARN_ON(clk->usecount == 0)) | 51 | if (WARN_ON(clk->usecount == 0)) |
51 | return; | 52 | return; |
52 | if (--clk->usecount == 0 && !(clk->flags & CLK_PLL)) | 53 | if (--clk->usecount == 0 && !(clk->flags & CLK_PLL)) |
53 | davinci_psc_config(psc_domain(clk), clk->lpsc, 0); | 54 | davinci_psc_config(psc_domain(clk), clk->psc_ctlr, |
55 | clk->lpsc, 0); | ||
54 | if (clk->parent) | 56 | if (clk->parent) |
55 | __clk_disable(clk->parent); | 57 | __clk_disable(clk->parent); |
56 | } | 58 | } |
@@ -164,11 +166,11 @@ static int __init clk_disable_unused(void) | |||
164 | continue; | 166 | continue; |
165 | 167 | ||
166 | /* ignore if in Disabled or SwRstDisable states */ | 168 | /* ignore if in Disabled or SwRstDisable states */ |
167 | if (!davinci_psc_is_clk_active(ck->lpsc)) | 169 | if (!davinci_psc_is_clk_active(ck->psc_ctlr, ck->lpsc)) |
168 | continue; | 170 | continue; |
169 | 171 | ||
170 | pr_info("Clocks: disable unused %s\n", ck->name); | 172 | pr_info("Clocks: disable unused %s\n", ck->name); |
171 | davinci_psc_config(psc_domain(ck), ck->lpsc, 0); | 173 | davinci_psc_config(psc_domain(ck), ck->psc_ctlr, ck->lpsc, 0); |
172 | } | 174 | } |
173 | spin_unlock_irq(&clockfw_lock); | 175 | spin_unlock_irq(&clockfw_lock); |
174 | 176 | ||
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 35736ec202f8..27233cb4a2fb 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h | |||
@@ -67,6 +67,7 @@ struct clk { | |||
67 | u8 usecount; | 67 | u8 usecount; |
68 | u8 flags; | 68 | u8 flags; |
69 | u8 lpsc; | 69 | u8 lpsc; |
70 | u8 psc_ctlr; | ||
70 | struct clk *parent; | 71 | struct clk *parent; |
71 | struct pll_data *pll_data; | 72 | struct pll_data *pll_data; |
72 | u32 div_reg; | 73 | u32 div_reg; |
@@ -93,4 +94,7 @@ struct davinci_clk { | |||
93 | } | 94 | } |
94 | 95 | ||
95 | int davinci_clk_init(struct davinci_clk *clocks); | 96 | int davinci_clk_init(struct davinci_clk *clocks); |
97 | |||
98 | extern struct platform_device davinci_wdt_device; | ||
99 | |||
96 | #endif | 100 | #endif |
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c new file mode 100644 index 000000000000..61ede19c6b54 --- /dev/null +++ b/arch/arm/mach-davinci/common.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | * Code commons to all DaVinci SoCs. | ||
3 | * | ||
4 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
5 | * | ||
6 | * 2009 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/etherdevice.h> | ||
14 | |||
15 | #include <asm/tlb.h> | ||
16 | #include <asm/mach/map.h> | ||
17 | |||
18 | #include <mach/common.h> | ||
19 | #include <mach/cputype.h> | ||
20 | #include <mach/emac.h> | ||
21 | |||
22 | #include "clock.h" | ||
23 | |||
24 | struct davinci_soc_info davinci_soc_info; | ||
25 | EXPORT_SYMBOL(davinci_soc_info); | ||
26 | |||
27 | void __iomem *davinci_intc_base; | ||
28 | int davinci_intc_type; | ||
29 | |||
30 | void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context) | ||
31 | { | ||
32 | char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; | ||
33 | off_t offset = (off_t)context; | ||
34 | |||
35 | /* Read MAC addr from EEPROM */ | ||
36 | if (mem_acc->read(mem_acc, mac_addr, offset, ETH_ALEN) == ETH_ALEN) | ||
37 | pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); | ||
38 | } | ||
39 | |||
40 | static struct davinci_id * __init davinci_get_id(u32 jtag_id) | ||
41 | { | ||
42 | int i; | ||
43 | struct davinci_id *dip; | ||
44 | u8 variant = (jtag_id & 0xf0000000) >> 28; | ||
45 | u16 part_no = (jtag_id & 0x0ffff000) >> 12; | ||
46 | |||
47 | for (i = 0, dip = davinci_soc_info.ids; i < davinci_soc_info.ids_num; | ||
48 | i++, dip++) | ||
49 | /* Don't care about the manufacturer right now */ | ||
50 | if ((dip->part_no == part_no) && (dip->variant == variant)) | ||
51 | return dip; | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | void __init davinci_common_init(struct davinci_soc_info *soc_info) | ||
57 | { | ||
58 | int ret; | ||
59 | struct davinci_id *dip; | ||
60 | |||
61 | if (!soc_info) { | ||
62 | ret = -EINVAL; | ||
63 | goto err; | ||
64 | } | ||
65 | |||
66 | memcpy(&davinci_soc_info, soc_info, sizeof(struct davinci_soc_info)); | ||
67 | |||
68 | if (davinci_soc_info.io_desc && (davinci_soc_info.io_desc_num > 0)) | ||
69 | iotable_init(davinci_soc_info.io_desc, | ||
70 | davinci_soc_info.io_desc_num); | ||
71 | |||
72 | /* | ||
73 | * Normally devicemaps_init() would flush caches and tlb after | ||
74 | * mdesc->map_io(), but we must also do it here because of the CPU | ||
75 | * revision check below. | ||
76 | */ | ||
77 | local_flush_tlb_all(); | ||
78 | flush_cache_all(); | ||
79 | |||
80 | /* | ||
81 | * We want to check CPU revision early for cpu_is_xxxx() macros. | ||
82 | * IO space mapping must be initialized before we can do that. | ||
83 | */ | ||
84 | davinci_soc_info.jtag_id = __raw_readl(davinci_soc_info.jtag_id_base); | ||
85 | |||
86 | dip = davinci_get_id(davinci_soc_info.jtag_id); | ||
87 | if (!dip) { | ||
88 | ret = -EINVAL; | ||
89 | goto err; | ||
90 | } | ||
91 | |||
92 | davinci_soc_info.cpu_id = dip->cpu_id; | ||
93 | pr_info("DaVinci %s variant 0x%x\n", dip->name, dip->variant); | ||
94 | |||
95 | if (davinci_soc_info.cpu_clks) { | ||
96 | ret = davinci_clk_init(davinci_soc_info.cpu_clks); | ||
97 | |||
98 | if (ret != 0) | ||
99 | goto err; | ||
100 | } | ||
101 | |||
102 | davinci_intc_base = davinci_soc_info.intc_base; | ||
103 | davinci_intc_type = davinci_soc_info.intc_type; | ||
104 | return; | ||
105 | |||
106 | err: | ||
107 | pr_err("davinci_common_init: SoC Initialization failed\n"); | ||
108 | } | ||
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c new file mode 100644 index 000000000000..96c8e97a7deb --- /dev/null +++ b/arch/arm/mach-davinci/cp_intc.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * TI Common Platform Interrupt Controller (cp_intc) driver | ||
3 | * | ||
4 | * Author: Steve Chen <schen@mvista.com> | ||
5 | * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public License | ||
8 | * version 2. This program is licensed "as is" without any warranty of any | ||
9 | * kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <mach/cp_intc.h> | ||
20 | |||
21 | static void __iomem *cp_intc_base; | ||
22 | |||
23 | static inline unsigned int cp_intc_read(unsigned offset) | ||
24 | { | ||
25 | return __raw_readl(cp_intc_base + offset); | ||
26 | } | ||
27 | |||
28 | static inline void cp_intc_write(unsigned long value, unsigned offset) | ||
29 | { | ||
30 | __raw_writel(value, cp_intc_base + offset); | ||
31 | } | ||
32 | |||
33 | static void cp_intc_ack_irq(unsigned int irq) | ||
34 | { | ||
35 | cp_intc_write(irq, CP_INTC_SYS_STAT_IDX_CLR); | ||
36 | } | ||
37 | |||
38 | /* Disable interrupt */ | ||
39 | static void cp_intc_mask_irq(unsigned int irq) | ||
40 | { | ||
41 | /* XXX don't know why we need to disable nIRQ here... */ | ||
42 | cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR); | ||
43 | cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_CLR); | ||
44 | cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET); | ||
45 | } | ||
46 | |||
47 | /* Enable interrupt */ | ||
48 | static void cp_intc_unmask_irq(unsigned int irq) | ||
49 | { | ||
50 | cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_SET); | ||
51 | } | ||
52 | |||
53 | static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type) | ||
54 | { | ||
55 | unsigned reg = BIT_WORD(irq); | ||
56 | unsigned mask = BIT_MASK(irq); | ||
57 | unsigned polarity = cp_intc_read(CP_INTC_SYS_POLARITY(reg)); | ||
58 | unsigned type = cp_intc_read(CP_INTC_SYS_TYPE(reg)); | ||
59 | |||
60 | switch (flow_type) { | ||
61 | case IRQ_TYPE_EDGE_RISING: | ||
62 | polarity |= mask; | ||
63 | type |= mask; | ||
64 | break; | ||
65 | case IRQ_TYPE_EDGE_FALLING: | ||
66 | polarity &= ~mask; | ||
67 | type |= mask; | ||
68 | break; | ||
69 | case IRQ_TYPE_LEVEL_HIGH: | ||
70 | polarity |= mask; | ||
71 | type &= ~mask; | ||
72 | break; | ||
73 | case IRQ_TYPE_LEVEL_LOW: | ||
74 | polarity &= ~mask; | ||
75 | type &= ~mask; | ||
76 | break; | ||
77 | default: | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | |||
81 | cp_intc_write(polarity, CP_INTC_SYS_POLARITY(reg)); | ||
82 | cp_intc_write(type, CP_INTC_SYS_TYPE(reg)); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static struct irq_chip cp_intc_irq_chip = { | ||
88 | .name = "cp_intc", | ||
89 | .ack = cp_intc_ack_irq, | ||
90 | .mask = cp_intc_mask_irq, | ||
91 | .unmask = cp_intc_unmask_irq, | ||
92 | .set_type = cp_intc_set_irq_type, | ||
93 | }; | ||
94 | |||
95 | void __init cp_intc_init(void __iomem *base, unsigned short num_irq, | ||
96 | u8 *irq_prio) | ||
97 | { | ||
98 | unsigned num_reg = BITS_TO_LONGS(num_irq); | ||
99 | int i; | ||
100 | |||
101 | cp_intc_base = base; | ||
102 | |||
103 | cp_intc_write(0, CP_INTC_GLOBAL_ENABLE); | ||
104 | |||
105 | /* Disable all host interrupts */ | ||
106 | cp_intc_write(0, CP_INTC_HOST_ENABLE(0)); | ||
107 | |||
108 | /* Disable system interrupts */ | ||
109 | for (i = 0; i < num_reg; i++) | ||
110 | cp_intc_write(~0, CP_INTC_SYS_ENABLE_CLR(i)); | ||
111 | |||
112 | /* Set to normal mode, no nesting, no priority hold */ | ||
113 | cp_intc_write(0, CP_INTC_CTRL); | ||
114 | cp_intc_write(0, CP_INTC_HOST_CTRL); | ||
115 | |||
116 | /* Clear system interrupt status */ | ||
117 | for (i = 0; i < num_reg; i++) | ||
118 | cp_intc_write(~0, CP_INTC_SYS_STAT_CLR(i)); | ||
119 | |||
120 | /* Enable nIRQ (what about nFIQ?) */ | ||
121 | cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET); | ||
122 | |||
123 | /* | ||
124 | * Priority is determined by host channel: lower channel number has | ||
125 | * higher priority i.e. channel 0 has highest priority and channel 31 | ||
126 | * had the lowest priority. | ||
127 | */ | ||
128 | num_reg = (num_irq + 3) >> 2; /* 4 channels per register */ | ||
129 | if (irq_prio) { | ||
130 | unsigned j, k; | ||
131 | u32 val; | ||
132 | |||
133 | for (k = i = 0; i < num_reg; i++) { | ||
134 | for (val = j = 0; j < 4; j++, k++) { | ||
135 | val >>= 8; | ||
136 | if (k < num_irq) | ||
137 | val |= irq_prio[k] << 24; | ||
138 | } | ||
139 | |||
140 | cp_intc_write(val, CP_INTC_CHAN_MAP(i)); | ||
141 | } | ||
142 | } else { | ||
143 | /* | ||
144 | * Default everything to channel 15 if priority not specified. | ||
145 | * Note that channel 0-1 are mapped to nFIQ and channels 2-31 | ||
146 | * are mapped to nIRQ. | ||
147 | */ | ||
148 | for (i = 0; i < num_reg; i++) | ||
149 | cp_intc_write(0x0f0f0f0f, CP_INTC_CHAN_MAP(i)); | ||
150 | } | ||
151 | |||
152 | /* Set up genirq dispatching for cp_intc */ | ||
153 | for (i = 0; i < num_irq; i++) { | ||
154 | set_irq_chip(i, &cp_intc_irq_chip); | ||
155 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
156 | set_irq_handler(i, handle_edge_irq); | ||
157 | } | ||
158 | |||
159 | /* Enable global interrupt */ | ||
160 | cp_intc_write(1, CP_INTC_GLOBAL_ENABLE); | ||
161 | } | ||
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index a31370b93dd2..c85091c25d11 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c | |||
@@ -23,8 +23,14 @@ | |||
23 | #include <mach/irqs.h> | 23 | #include <mach/irqs.h> |
24 | #include <mach/cputype.h> | 24 | #include <mach/cputype.h> |
25 | #include <mach/mux.h> | 25 | #include <mach/mux.h> |
26 | #include <mach/edma.h> | ||
27 | #include <mach/mmc.h> | ||
28 | #include <mach/time.h> | ||
26 | 29 | ||
27 | #define DAVINCI_I2C_BASE 0x01C21000 | 30 | #define DAVINCI_I2C_BASE 0x01C21000 |
31 | #define DAVINCI_MMCSD0_BASE 0x01E10000 | ||
32 | #define DM355_MMCSD0_BASE 0x01E11000 | ||
33 | #define DM355_MMCSD1_BASE 0x01E00000 | ||
28 | 34 | ||
29 | static struct resource i2c_resources[] = { | 35 | static struct resource i2c_resources[] = { |
30 | { | 36 | { |
@@ -54,3 +60,208 @@ void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata) | |||
54 | (void) platform_device_register(&davinci_i2c_device); | 60 | (void) platform_device_register(&davinci_i2c_device); |
55 | } | 61 | } |
56 | 62 | ||
63 | #if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE) | ||
64 | |||
65 | static u64 mmcsd0_dma_mask = DMA_32BIT_MASK; | ||
66 | |||
67 | static struct resource mmcsd0_resources[] = { | ||
68 | { | ||
69 | /* different on dm355 */ | ||
70 | .start = DAVINCI_MMCSD0_BASE, | ||
71 | .end = DAVINCI_MMCSD0_BASE + SZ_4K - 1, | ||
72 | .flags = IORESOURCE_MEM, | ||
73 | }, | ||
74 | /* IRQs: MMC/SD, then SDIO */ | ||
75 | { | ||
76 | .start = IRQ_MMCINT, | ||
77 | .flags = IORESOURCE_IRQ, | ||
78 | }, { | ||
79 | /* different on dm355 */ | ||
80 | .start = IRQ_SDIOINT, | ||
81 | .flags = IORESOURCE_IRQ, | ||
82 | }, | ||
83 | /* DMA channels: RX, then TX */ | ||
84 | { | ||
85 | .start = DAVINCI_DMA_MMCRXEVT, | ||
86 | .flags = IORESOURCE_DMA, | ||
87 | }, { | ||
88 | .start = DAVINCI_DMA_MMCTXEVT, | ||
89 | .flags = IORESOURCE_DMA, | ||
90 | }, | ||
91 | }; | ||
92 | |||
93 | static struct platform_device davinci_mmcsd0_device = { | ||
94 | .name = "davinci_mmc", | ||
95 | .id = 0, | ||
96 | .dev = { | ||
97 | .dma_mask = &mmcsd0_dma_mask, | ||
98 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
99 | }, | ||
100 | .num_resources = ARRAY_SIZE(mmcsd0_resources), | ||
101 | .resource = mmcsd0_resources, | ||
102 | }; | ||
103 | |||
104 | static u64 mmcsd1_dma_mask = DMA_32BIT_MASK; | ||
105 | |||
106 | static struct resource mmcsd1_resources[] = { | ||
107 | { | ||
108 | .start = DM355_MMCSD1_BASE, | ||
109 | .end = DM355_MMCSD1_BASE + SZ_4K - 1, | ||
110 | .flags = IORESOURCE_MEM, | ||
111 | }, | ||
112 | /* IRQs: MMC/SD, then SDIO */ | ||
113 | { | ||
114 | .start = IRQ_DM355_MMCINT1, | ||
115 | .flags = IORESOURCE_IRQ, | ||
116 | }, { | ||
117 | .start = IRQ_DM355_SDIOINT1, | ||
118 | .flags = IORESOURCE_IRQ, | ||
119 | }, | ||
120 | /* DMA channels: RX, then TX */ | ||
121 | { | ||
122 | .start = 30, /* rx */ | ||
123 | .flags = IORESOURCE_DMA, | ||
124 | }, { | ||
125 | .start = 31, /* tx */ | ||
126 | .flags = IORESOURCE_DMA, | ||
127 | }, | ||
128 | }; | ||
129 | |||
130 | static struct platform_device davinci_mmcsd1_device = { | ||
131 | .name = "davinci_mmc", | ||
132 | .id = 1, | ||
133 | .dev = { | ||
134 | .dma_mask = &mmcsd1_dma_mask, | ||
135 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
136 | }, | ||
137 | .num_resources = ARRAY_SIZE(mmcsd1_resources), | ||
138 | .resource = mmcsd1_resources, | ||
139 | }; | ||
140 | |||
141 | |||
142 | void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) | ||
143 | { | ||
144 | struct platform_device *pdev = NULL; | ||
145 | |||
146 | if (WARN_ON(cpu_is_davinci_dm646x())) | ||
147 | return; | ||
148 | |||
149 | /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too; | ||
150 | * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused. | ||
151 | * | ||
152 | * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are | ||
153 | * not handled right here ... | ||
154 | */ | ||
155 | switch (module) { | ||
156 | case 1: | ||
157 | if (!cpu_is_davinci_dm355()) | ||
158 | break; | ||
159 | |||
160 | /* REVISIT we may not need all these pins if e.g. this | ||
161 | * is a hard-wired SDIO device... | ||
162 | */ | ||
163 | davinci_cfg_reg(DM355_SD1_CMD); | ||
164 | davinci_cfg_reg(DM355_SD1_CLK); | ||
165 | davinci_cfg_reg(DM355_SD1_DATA0); | ||
166 | davinci_cfg_reg(DM355_SD1_DATA1); | ||
167 | davinci_cfg_reg(DM355_SD1_DATA2); | ||
168 | davinci_cfg_reg(DM355_SD1_DATA3); | ||
169 | |||
170 | pdev = &davinci_mmcsd1_device; | ||
171 | break; | ||
172 | case 0: | ||
173 | if (cpu_is_davinci_dm355()) { | ||
174 | mmcsd0_resources[0].start = DM355_MMCSD0_BASE; | ||
175 | mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1; | ||
176 | mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0; | ||
177 | |||
178 | /* expose all 6 MMC0 signals: CLK, CMD, DATA[0..3] */ | ||
179 | davinci_cfg_reg(DM355_MMCSD0); | ||
180 | |||
181 | /* enable RX EDMA */ | ||
182 | davinci_cfg_reg(DM355_EVT26_MMC0_RX); | ||
183 | } | ||
184 | |||
185 | else if (cpu_is_davinci_dm644x()) { | ||
186 | /* REVISIT: should this be in board-init code? */ | ||
187 | void __iomem *base = | ||
188 | IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); | ||
189 | |||
190 | /* Power-on 3.3V IO cells */ | ||
191 | __raw_writel(0, base + DM64XX_VDD3P3V_PWDN); | ||
192 | /*Set up the pull regiter for MMC */ | ||
193 | davinci_cfg_reg(DM644X_MSTK); | ||
194 | } | ||
195 | |||
196 | pdev = &davinci_mmcsd0_device; | ||
197 | break; | ||
198 | } | ||
199 | |||
200 | if (WARN_ON(!pdev)) | ||
201 | return; | ||
202 | |||
203 | pdev->dev.platform_data = config; | ||
204 | platform_device_register(pdev); | ||
205 | } | ||
206 | |||
207 | #else | ||
208 | |||
209 | void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) | ||
210 | { | ||
211 | } | ||
212 | |||
213 | #endif | ||
214 | |||
215 | /*-------------------------------------------------------------------------*/ | ||
216 | |||
217 | static struct resource wdt_resources[] = { | ||
218 | { | ||
219 | .flags = IORESOURCE_MEM, | ||
220 | }, | ||
221 | }; | ||
222 | |||
223 | struct platform_device davinci_wdt_device = { | ||
224 | .name = "watchdog", | ||
225 | .id = -1, | ||
226 | .num_resources = ARRAY_SIZE(wdt_resources), | ||
227 | .resource = wdt_resources, | ||
228 | }; | ||
229 | |||
230 | static void davinci_init_wdt(void) | ||
231 | { | ||
232 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
233 | |||
234 | wdt_resources[0].start = (resource_size_t)soc_info->wdt_base; | ||
235 | wdt_resources[0].end = (resource_size_t)soc_info->wdt_base + SZ_1K - 1; | ||
236 | |||
237 | platform_device_register(&davinci_wdt_device); | ||
238 | } | ||
239 | |||
240 | /*-------------------------------------------------------------------------*/ | ||
241 | |||
242 | struct davinci_timer_instance davinci_timer_instance[2] = { | ||
243 | { | ||
244 | .base = IO_ADDRESS(DAVINCI_TIMER0_BASE), | ||
245 | .bottom_irq = IRQ_TINT0_TINT12, | ||
246 | .top_irq = IRQ_TINT0_TINT34, | ||
247 | }, | ||
248 | { | ||
249 | .base = IO_ADDRESS(DAVINCI_TIMER1_BASE), | ||
250 | .bottom_irq = IRQ_TINT1_TINT12, | ||
251 | .top_irq = IRQ_TINT1_TINT34, | ||
252 | }, | ||
253 | }; | ||
254 | |||
255 | /*-------------------------------------------------------------------------*/ | ||
256 | |||
257 | static int __init davinci_init_devices(void) | ||
258 | { | ||
259 | /* please keep these calls, and their implementations above, | ||
260 | * in alphabetical order so they're easier to sort through. | ||
261 | */ | ||
262 | davinci_init_wdt(); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | arch_initcall(davinci_init_devices); | ||
267 | |||
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c new file mode 100644 index 000000000000..baaaf328de2e --- /dev/null +++ b/arch/arm/mach-davinci/dm355.c | |||
@@ -0,0 +1,730 @@ | |||
1 | /* | ||
2 | * TI DaVinci DM355 chip specific setup | ||
3 | * | ||
4 | * Author: Kevin Hilman, Deep Root Systems, LLC | ||
5 | * | ||
6 | * 2007 (c) Deep Root Systems, LLC. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/serial_8250.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <linux/spi/spi.h> | ||
20 | |||
21 | #include <asm/mach/map.h> | ||
22 | |||
23 | #include <mach/dm355.h> | ||
24 | #include <mach/clock.h> | ||
25 | #include <mach/cputype.h> | ||
26 | #include <mach/edma.h> | ||
27 | #include <mach/psc.h> | ||
28 | #include <mach/mux.h> | ||
29 | #include <mach/irqs.h> | ||
30 | #include <mach/time.h> | ||
31 | #include <mach/serial.h> | ||
32 | #include <mach/common.h> | ||
33 | |||
34 | #include "clock.h" | ||
35 | #include "mux.h" | ||
36 | |||
37 | #define DM355_UART2_BASE (IO_PHYS + 0x206000) | ||
38 | |||
39 | /* | ||
40 | * Device specific clocks | ||
41 | */ | ||
42 | #define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */ | ||
43 | |||
44 | static struct pll_data pll1_data = { | ||
45 | .num = 1, | ||
46 | .phys_base = DAVINCI_PLL1_BASE, | ||
47 | .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV, | ||
48 | }; | ||
49 | |||
50 | static struct pll_data pll2_data = { | ||
51 | .num = 2, | ||
52 | .phys_base = DAVINCI_PLL2_BASE, | ||
53 | .flags = PLL_HAS_PREDIV, | ||
54 | }; | ||
55 | |||
56 | static struct clk ref_clk = { | ||
57 | .name = "ref_clk", | ||
58 | /* FIXME -- crystal rate is board-specific */ | ||
59 | .rate = DM355_REF_FREQ, | ||
60 | }; | ||
61 | |||
62 | static struct clk pll1_clk = { | ||
63 | .name = "pll1", | ||
64 | .parent = &ref_clk, | ||
65 | .flags = CLK_PLL, | ||
66 | .pll_data = &pll1_data, | ||
67 | }; | ||
68 | |||
69 | static struct clk pll1_aux_clk = { | ||
70 | .name = "pll1_aux_clk", | ||
71 | .parent = &pll1_clk, | ||
72 | .flags = CLK_PLL | PRE_PLL, | ||
73 | }; | ||
74 | |||
75 | static struct clk pll1_sysclk1 = { | ||
76 | .name = "pll1_sysclk1", | ||
77 | .parent = &pll1_clk, | ||
78 | .flags = CLK_PLL, | ||
79 | .div_reg = PLLDIV1, | ||
80 | }; | ||
81 | |||
82 | static struct clk pll1_sysclk2 = { | ||
83 | .name = "pll1_sysclk2", | ||
84 | .parent = &pll1_clk, | ||
85 | .flags = CLK_PLL, | ||
86 | .div_reg = PLLDIV2, | ||
87 | }; | ||
88 | |||
89 | static struct clk pll1_sysclk3 = { | ||
90 | .name = "pll1_sysclk3", | ||
91 | .parent = &pll1_clk, | ||
92 | .flags = CLK_PLL, | ||
93 | .div_reg = PLLDIV3, | ||
94 | }; | ||
95 | |||
96 | static struct clk pll1_sysclk4 = { | ||
97 | .name = "pll1_sysclk4", | ||
98 | .parent = &pll1_clk, | ||
99 | .flags = CLK_PLL, | ||
100 | .div_reg = PLLDIV4, | ||
101 | }; | ||
102 | |||
103 | static struct clk pll1_sysclkbp = { | ||
104 | .name = "pll1_sysclkbp", | ||
105 | .parent = &pll1_clk, | ||
106 | .flags = CLK_PLL | PRE_PLL, | ||
107 | .div_reg = BPDIV | ||
108 | }; | ||
109 | |||
110 | static struct clk vpss_dac_clk = { | ||
111 | .name = "vpss_dac", | ||
112 | .parent = &pll1_sysclk3, | ||
113 | .lpsc = DM355_LPSC_VPSS_DAC, | ||
114 | }; | ||
115 | |||
116 | static struct clk vpss_master_clk = { | ||
117 | .name = "vpss_master", | ||
118 | .parent = &pll1_sysclk4, | ||
119 | .lpsc = DAVINCI_LPSC_VPSSMSTR, | ||
120 | .flags = CLK_PSC, | ||
121 | }; | ||
122 | |||
123 | static struct clk vpss_slave_clk = { | ||
124 | .name = "vpss_slave", | ||
125 | .parent = &pll1_sysclk4, | ||
126 | .lpsc = DAVINCI_LPSC_VPSSSLV, | ||
127 | }; | ||
128 | |||
129 | |||
130 | static struct clk clkout1_clk = { | ||
131 | .name = "clkout1", | ||
132 | .parent = &pll1_aux_clk, | ||
133 | /* NOTE: clkout1 can be externally gated by muxing GPIO-18 */ | ||
134 | }; | ||
135 | |||
136 | static struct clk clkout2_clk = { | ||
137 | .name = "clkout2", | ||
138 | .parent = &pll1_sysclkbp, | ||
139 | }; | ||
140 | |||
141 | static struct clk pll2_clk = { | ||
142 | .name = "pll2", | ||
143 | .parent = &ref_clk, | ||
144 | .flags = CLK_PLL, | ||
145 | .pll_data = &pll2_data, | ||
146 | }; | ||
147 | |||
148 | static struct clk pll2_sysclk1 = { | ||
149 | .name = "pll2_sysclk1", | ||
150 | .parent = &pll2_clk, | ||
151 | .flags = CLK_PLL, | ||
152 | .div_reg = PLLDIV1, | ||
153 | }; | ||
154 | |||
155 | static struct clk pll2_sysclkbp = { | ||
156 | .name = "pll2_sysclkbp", | ||
157 | .parent = &pll2_clk, | ||
158 | .flags = CLK_PLL | PRE_PLL, | ||
159 | .div_reg = BPDIV | ||
160 | }; | ||
161 | |||
162 | static struct clk clkout3_clk = { | ||
163 | .name = "clkout3", | ||
164 | .parent = &pll2_sysclkbp, | ||
165 | /* NOTE: clkout3 can be externally gated by muxing GPIO-16 */ | ||
166 | }; | ||
167 | |||
168 | static struct clk arm_clk = { | ||
169 | .name = "arm_clk", | ||
170 | .parent = &pll1_sysclk1, | ||
171 | .lpsc = DAVINCI_LPSC_ARM, | ||
172 | .flags = ALWAYS_ENABLED, | ||
173 | }; | ||
174 | |||
175 | /* | ||
176 | * NOT LISTED below, and not touched by Linux | ||
177 | * - in SyncReset state by default | ||
178 | * .lpsc = DAVINCI_LPSC_TPCC, | ||
179 | * .lpsc = DAVINCI_LPSC_TPTC0, | ||
180 | * .lpsc = DAVINCI_LPSC_TPTC1, | ||
181 | * .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk, | ||
182 | * .lpsc = DAVINCI_LPSC_MEMSTICK, | ||
183 | * - in Enabled state by default | ||
184 | * .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS, | ||
185 | * .lpsc = DAVINCI_LPSC_SCR2, // "bus" | ||
186 | * .lpsc = DAVINCI_LPSC_SCR3, // "bus" | ||
187 | * .lpsc = DAVINCI_LPSC_SCR4, // "bus" | ||
188 | * .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation" | ||
189 | * .lpsc = DAVINCI_LPSC_CFG27, // "test" | ||
190 | * .lpsc = DAVINCI_LPSC_CFG3, // "test" | ||
191 | * .lpsc = DAVINCI_LPSC_CFG5, // "test" | ||
192 | */ | ||
193 | |||
194 | static struct clk mjcp_clk = { | ||
195 | .name = "mjcp", | ||
196 | .parent = &pll1_sysclk1, | ||
197 | .lpsc = DAVINCI_LPSC_IMCOP, | ||
198 | }; | ||
199 | |||
200 | static struct clk uart0_clk = { | ||
201 | .name = "uart0", | ||
202 | .parent = &pll1_aux_clk, | ||
203 | .lpsc = DAVINCI_LPSC_UART0, | ||
204 | }; | ||
205 | |||
206 | static struct clk uart1_clk = { | ||
207 | .name = "uart1", | ||
208 | .parent = &pll1_aux_clk, | ||
209 | .lpsc = DAVINCI_LPSC_UART1, | ||
210 | }; | ||
211 | |||
212 | static struct clk uart2_clk = { | ||
213 | .name = "uart2", | ||
214 | .parent = &pll1_sysclk2, | ||
215 | .lpsc = DAVINCI_LPSC_UART2, | ||
216 | }; | ||
217 | |||
218 | static struct clk i2c_clk = { | ||
219 | .name = "i2c", | ||
220 | .parent = &pll1_aux_clk, | ||
221 | .lpsc = DAVINCI_LPSC_I2C, | ||
222 | }; | ||
223 | |||
224 | static struct clk asp0_clk = { | ||
225 | .name = "asp0", | ||
226 | .parent = &pll1_sysclk2, | ||
227 | .lpsc = DAVINCI_LPSC_McBSP, | ||
228 | }; | ||
229 | |||
230 | static struct clk asp1_clk = { | ||
231 | .name = "asp1", | ||
232 | .parent = &pll1_sysclk2, | ||
233 | .lpsc = DM355_LPSC_McBSP1, | ||
234 | }; | ||
235 | |||
236 | static struct clk mmcsd0_clk = { | ||
237 | .name = "mmcsd0", | ||
238 | .parent = &pll1_sysclk2, | ||
239 | .lpsc = DAVINCI_LPSC_MMC_SD, | ||
240 | }; | ||
241 | |||
242 | static struct clk mmcsd1_clk = { | ||
243 | .name = "mmcsd1", | ||
244 | .parent = &pll1_sysclk2, | ||
245 | .lpsc = DM355_LPSC_MMC_SD1, | ||
246 | }; | ||
247 | |||
248 | static struct clk spi0_clk = { | ||
249 | .name = "spi0", | ||
250 | .parent = &pll1_sysclk2, | ||
251 | .lpsc = DAVINCI_LPSC_SPI, | ||
252 | }; | ||
253 | |||
254 | static struct clk spi1_clk = { | ||
255 | .name = "spi1", | ||
256 | .parent = &pll1_sysclk2, | ||
257 | .lpsc = DM355_LPSC_SPI1, | ||
258 | }; | ||
259 | |||
260 | static struct clk spi2_clk = { | ||
261 | .name = "spi2", | ||
262 | .parent = &pll1_sysclk2, | ||
263 | .lpsc = DM355_LPSC_SPI2, | ||
264 | }; | ||
265 | |||
266 | static struct clk gpio_clk = { | ||
267 | .name = "gpio", | ||
268 | .parent = &pll1_sysclk2, | ||
269 | .lpsc = DAVINCI_LPSC_GPIO, | ||
270 | }; | ||
271 | |||
272 | static struct clk aemif_clk = { | ||
273 | .name = "aemif", | ||
274 | .parent = &pll1_sysclk2, | ||
275 | .lpsc = DAVINCI_LPSC_AEMIF, | ||
276 | }; | ||
277 | |||
278 | static struct clk pwm0_clk = { | ||
279 | .name = "pwm0", | ||
280 | .parent = &pll1_aux_clk, | ||
281 | .lpsc = DAVINCI_LPSC_PWM0, | ||
282 | }; | ||
283 | |||
284 | static struct clk pwm1_clk = { | ||
285 | .name = "pwm1", | ||
286 | .parent = &pll1_aux_clk, | ||
287 | .lpsc = DAVINCI_LPSC_PWM1, | ||
288 | }; | ||
289 | |||
290 | static struct clk pwm2_clk = { | ||
291 | .name = "pwm2", | ||
292 | .parent = &pll1_aux_clk, | ||
293 | .lpsc = DAVINCI_LPSC_PWM2, | ||
294 | }; | ||
295 | |||
296 | static struct clk pwm3_clk = { | ||
297 | .name = "pwm3", | ||
298 | .parent = &pll1_aux_clk, | ||
299 | .lpsc = DM355_LPSC_PWM3, | ||
300 | }; | ||
301 | |||
302 | static struct clk timer0_clk = { | ||
303 | .name = "timer0", | ||
304 | .parent = &pll1_aux_clk, | ||
305 | .lpsc = DAVINCI_LPSC_TIMER0, | ||
306 | }; | ||
307 | |||
308 | static struct clk timer1_clk = { | ||
309 | .name = "timer1", | ||
310 | .parent = &pll1_aux_clk, | ||
311 | .lpsc = DAVINCI_LPSC_TIMER1, | ||
312 | }; | ||
313 | |||
314 | static struct clk timer2_clk = { | ||
315 | .name = "timer2", | ||
316 | .parent = &pll1_aux_clk, | ||
317 | .lpsc = DAVINCI_LPSC_TIMER2, | ||
318 | .usecount = 1, /* REVISIT: why cant' this be disabled? */ | ||
319 | }; | ||
320 | |||
321 | static struct clk timer3_clk = { | ||
322 | .name = "timer3", | ||
323 | .parent = &pll1_aux_clk, | ||
324 | .lpsc = DM355_LPSC_TIMER3, | ||
325 | }; | ||
326 | |||
327 | static struct clk rto_clk = { | ||
328 | .name = "rto", | ||
329 | .parent = &pll1_aux_clk, | ||
330 | .lpsc = DM355_LPSC_RTO, | ||
331 | }; | ||
332 | |||
333 | static struct clk usb_clk = { | ||
334 | .name = "usb", | ||
335 | .parent = &pll1_sysclk2, | ||
336 | .lpsc = DAVINCI_LPSC_USB, | ||
337 | }; | ||
338 | |||
339 | static struct davinci_clk dm355_clks[] = { | ||
340 | CLK(NULL, "ref", &ref_clk), | ||
341 | CLK(NULL, "pll1", &pll1_clk), | ||
342 | CLK(NULL, "pll1_sysclk1", &pll1_sysclk1), | ||
343 | CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), | ||
344 | CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), | ||
345 | CLK(NULL, "pll1_sysclk4", &pll1_sysclk4), | ||
346 | CLK(NULL, "pll1_aux", &pll1_aux_clk), | ||
347 | CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp), | ||
348 | CLK(NULL, "vpss_dac", &vpss_dac_clk), | ||
349 | CLK(NULL, "vpss_master", &vpss_master_clk), | ||
350 | CLK(NULL, "vpss_slave", &vpss_slave_clk), | ||
351 | CLK(NULL, "clkout1", &clkout1_clk), | ||
352 | CLK(NULL, "clkout2", &clkout2_clk), | ||
353 | CLK(NULL, "pll2", &pll2_clk), | ||
354 | CLK(NULL, "pll2_sysclk1", &pll2_sysclk1), | ||
355 | CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp), | ||
356 | CLK(NULL, "clkout3", &clkout3_clk), | ||
357 | CLK(NULL, "arm", &arm_clk), | ||
358 | CLK(NULL, "mjcp", &mjcp_clk), | ||
359 | CLK(NULL, "uart0", &uart0_clk), | ||
360 | CLK(NULL, "uart1", &uart1_clk), | ||
361 | CLK(NULL, "uart2", &uart2_clk), | ||
362 | CLK("i2c_davinci.1", NULL, &i2c_clk), | ||
363 | CLK("soc-audio.0", NULL, &asp0_clk), | ||
364 | CLK("soc-audio.1", NULL, &asp1_clk), | ||
365 | CLK("davinci_mmc.0", NULL, &mmcsd0_clk), | ||
366 | CLK("davinci_mmc.1", NULL, &mmcsd1_clk), | ||
367 | CLK(NULL, "spi0", &spi0_clk), | ||
368 | CLK(NULL, "spi1", &spi1_clk), | ||
369 | CLK(NULL, "spi2", &spi2_clk), | ||
370 | CLK(NULL, "gpio", &gpio_clk), | ||
371 | CLK(NULL, "aemif", &aemif_clk), | ||
372 | CLK(NULL, "pwm0", &pwm0_clk), | ||
373 | CLK(NULL, "pwm1", &pwm1_clk), | ||
374 | CLK(NULL, "pwm2", &pwm2_clk), | ||
375 | CLK(NULL, "pwm3", &pwm3_clk), | ||
376 | CLK(NULL, "timer0", &timer0_clk), | ||
377 | CLK(NULL, "timer1", &timer1_clk), | ||
378 | CLK("watchdog", NULL, &timer2_clk), | ||
379 | CLK(NULL, "timer3", &timer3_clk), | ||
380 | CLK(NULL, "rto", &rto_clk), | ||
381 | CLK(NULL, "usb", &usb_clk), | ||
382 | CLK(NULL, NULL, NULL), | ||
383 | }; | ||
384 | |||
385 | /*----------------------------------------------------------------------*/ | ||
386 | |||
387 | static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32); | ||
388 | |||
389 | static struct resource dm355_spi0_resources[] = { | ||
390 | { | ||
391 | .start = 0x01c66000, | ||
392 | .end = 0x01c667ff, | ||
393 | .flags = IORESOURCE_MEM, | ||
394 | }, | ||
395 | { | ||
396 | .start = IRQ_DM355_SPINT0_1, | ||
397 | .flags = IORESOURCE_IRQ, | ||
398 | }, | ||
399 | /* Not yet used, so not included: | ||
400 | * IORESOURCE_IRQ: | ||
401 | * - IRQ_DM355_SPINT0_0 | ||
402 | * IORESOURCE_DMA: | ||
403 | * - DAVINCI_DMA_SPI_SPIX | ||
404 | * - DAVINCI_DMA_SPI_SPIR | ||
405 | */ | ||
406 | }; | ||
407 | |||
408 | static struct platform_device dm355_spi0_device = { | ||
409 | .name = "spi_davinci", | ||
410 | .id = 0, | ||
411 | .dev = { | ||
412 | .dma_mask = &dm355_spi0_dma_mask, | ||
413 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
414 | }, | ||
415 | .num_resources = ARRAY_SIZE(dm355_spi0_resources), | ||
416 | .resource = dm355_spi0_resources, | ||
417 | }; | ||
418 | |||
419 | void __init dm355_init_spi0(unsigned chipselect_mask, | ||
420 | struct spi_board_info *info, unsigned len) | ||
421 | { | ||
422 | /* for now, assume we need MISO */ | ||
423 | davinci_cfg_reg(DM355_SPI0_SDI); | ||
424 | |||
425 | /* not all slaves will be wired up */ | ||
426 | if (chipselect_mask & BIT(0)) | ||
427 | davinci_cfg_reg(DM355_SPI0_SDENA0); | ||
428 | if (chipselect_mask & BIT(1)) | ||
429 | davinci_cfg_reg(DM355_SPI0_SDENA1); | ||
430 | |||
431 | spi_register_board_info(info, len); | ||
432 | |||
433 | platform_device_register(&dm355_spi0_device); | ||
434 | } | ||
435 | |||
436 | /*----------------------------------------------------------------------*/ | ||
437 | |||
438 | #define PINMUX0 0x00 | ||
439 | #define PINMUX1 0x04 | ||
440 | #define PINMUX2 0x08 | ||
441 | #define PINMUX3 0x0c | ||
442 | #define PINMUX4 0x10 | ||
443 | #define INTMUX 0x18 | ||
444 | #define EVTMUX 0x1c | ||
445 | |||
446 | /* | ||
447 | * Device specific mux setup | ||
448 | * | ||
449 | * soc description mux mode mode mux dbg | ||
450 | * reg offset mask mode | ||
451 | */ | ||
452 | static const struct mux_config dm355_pins[] = { | ||
453 | #ifdef CONFIG_DAVINCI_MUX | ||
454 | MUX_CFG(DM355, MMCSD0, 4, 2, 1, 0, false) | ||
455 | |||
456 | MUX_CFG(DM355, SD1_CLK, 3, 6, 1, 1, false) | ||
457 | MUX_CFG(DM355, SD1_CMD, 3, 7, 1, 1, false) | ||
458 | MUX_CFG(DM355, SD1_DATA3, 3, 8, 3, 1, false) | ||
459 | MUX_CFG(DM355, SD1_DATA2, 3, 10, 3, 1, false) | ||
460 | MUX_CFG(DM355, SD1_DATA1, 3, 12, 3, 1, false) | ||
461 | MUX_CFG(DM355, SD1_DATA0, 3, 14, 3, 1, false) | ||
462 | |||
463 | MUX_CFG(DM355, I2C_SDA, 3, 19, 1, 1, false) | ||
464 | MUX_CFG(DM355, I2C_SCL, 3, 20, 1, 1, false) | ||
465 | |||
466 | MUX_CFG(DM355, MCBSP0_BDX, 3, 0, 1, 1, false) | ||
467 | MUX_CFG(DM355, MCBSP0_X, 3, 1, 1, 1, false) | ||
468 | MUX_CFG(DM355, MCBSP0_BFSX, 3, 2, 1, 1, false) | ||
469 | MUX_CFG(DM355, MCBSP0_BDR, 3, 3, 1, 1, false) | ||
470 | MUX_CFG(DM355, MCBSP0_R, 3, 4, 1, 1, false) | ||
471 | MUX_CFG(DM355, MCBSP0_BFSR, 3, 5, 1, 1, false) | ||
472 | |||
473 | MUX_CFG(DM355, SPI0_SDI, 4, 1, 1, 0, false) | ||
474 | MUX_CFG(DM355, SPI0_SDENA0, 4, 0, 1, 0, false) | ||
475 | MUX_CFG(DM355, SPI0_SDENA1, 3, 28, 1, 1, false) | ||
476 | |||
477 | INT_CFG(DM355, INT_EDMA_CC, 2, 1, 1, false) | ||
478 | INT_CFG(DM355, INT_EDMA_TC0_ERR, 3, 1, 1, false) | ||
479 | INT_CFG(DM355, INT_EDMA_TC1_ERR, 4, 1, 1, false) | ||
480 | |||
481 | EVT_CFG(DM355, EVT8_ASP1_TX, 0, 1, 0, false) | ||
482 | EVT_CFG(DM355, EVT9_ASP1_RX, 1, 1, 0, false) | ||
483 | EVT_CFG(DM355, EVT26_MMC0_RX, 2, 1, 0, false) | ||
484 | #endif | ||
485 | }; | ||
486 | |||
487 | static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = { | ||
488 | [IRQ_DM355_CCDC_VDINT0] = 2, | ||
489 | [IRQ_DM355_CCDC_VDINT1] = 6, | ||
490 | [IRQ_DM355_CCDC_VDINT2] = 6, | ||
491 | [IRQ_DM355_IPIPE_HST] = 6, | ||
492 | [IRQ_DM355_H3AINT] = 6, | ||
493 | [IRQ_DM355_IPIPE_SDR] = 6, | ||
494 | [IRQ_DM355_IPIPEIFINT] = 6, | ||
495 | [IRQ_DM355_OSDINT] = 7, | ||
496 | [IRQ_DM355_VENCINT] = 6, | ||
497 | [IRQ_ASQINT] = 6, | ||
498 | [IRQ_IMXINT] = 6, | ||
499 | [IRQ_USBINT] = 4, | ||
500 | [IRQ_DM355_RTOINT] = 4, | ||
501 | [IRQ_DM355_UARTINT2] = 7, | ||
502 | [IRQ_DM355_TINT6] = 7, | ||
503 | [IRQ_CCINT0] = 5, /* dma */ | ||
504 | [IRQ_CCERRINT] = 5, /* dma */ | ||
505 | [IRQ_TCERRINT0] = 5, /* dma */ | ||
506 | [IRQ_TCERRINT] = 5, /* dma */ | ||
507 | [IRQ_DM355_SPINT2_1] = 7, | ||
508 | [IRQ_DM355_TINT7] = 4, | ||
509 | [IRQ_DM355_SDIOINT0] = 7, | ||
510 | [IRQ_MBXINT] = 7, | ||
511 | [IRQ_MBRINT] = 7, | ||
512 | [IRQ_MMCINT] = 7, | ||
513 | [IRQ_DM355_MMCINT1] = 7, | ||
514 | [IRQ_DM355_PWMINT3] = 7, | ||
515 | [IRQ_DDRINT] = 7, | ||
516 | [IRQ_AEMIFINT] = 7, | ||
517 | [IRQ_DM355_SDIOINT1] = 4, | ||
518 | [IRQ_TINT0_TINT12] = 2, /* clockevent */ | ||
519 | [IRQ_TINT0_TINT34] = 2, /* clocksource */ | ||
520 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | ||
521 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | ||
522 | [IRQ_PWMINT0] = 7, | ||
523 | [IRQ_PWMINT1] = 7, | ||
524 | [IRQ_PWMINT2] = 7, | ||
525 | [IRQ_I2C] = 3, | ||
526 | [IRQ_UARTINT0] = 3, | ||
527 | [IRQ_UARTINT1] = 3, | ||
528 | [IRQ_DM355_SPINT0_0] = 3, | ||
529 | [IRQ_DM355_SPINT0_1] = 3, | ||
530 | [IRQ_DM355_GPIO0] = 3, | ||
531 | [IRQ_DM355_GPIO1] = 7, | ||
532 | [IRQ_DM355_GPIO2] = 4, | ||
533 | [IRQ_DM355_GPIO3] = 4, | ||
534 | [IRQ_DM355_GPIO4] = 7, | ||
535 | [IRQ_DM355_GPIO5] = 7, | ||
536 | [IRQ_DM355_GPIO6] = 7, | ||
537 | [IRQ_DM355_GPIO7] = 7, | ||
538 | [IRQ_DM355_GPIO8] = 7, | ||
539 | [IRQ_DM355_GPIO9] = 7, | ||
540 | [IRQ_DM355_GPIOBNK0] = 7, | ||
541 | [IRQ_DM355_GPIOBNK1] = 7, | ||
542 | [IRQ_DM355_GPIOBNK2] = 7, | ||
543 | [IRQ_DM355_GPIOBNK3] = 7, | ||
544 | [IRQ_DM355_GPIOBNK4] = 7, | ||
545 | [IRQ_DM355_GPIOBNK5] = 7, | ||
546 | [IRQ_DM355_GPIOBNK6] = 7, | ||
547 | [IRQ_COMMTX] = 7, | ||
548 | [IRQ_COMMRX] = 7, | ||
549 | [IRQ_EMUINT] = 7, | ||
550 | }; | ||
551 | |||
552 | /*----------------------------------------------------------------------*/ | ||
553 | |||
554 | static const s8 dma_chan_dm355_no_event[] = { | ||
555 | 12, 13, 24, 56, 57, | ||
556 | 58, 59, 60, 61, 62, | ||
557 | 63, | ||
558 | -1 | ||
559 | }; | ||
560 | |||
561 | static struct edma_soc_info dm355_edma_info = { | ||
562 | .n_channel = 64, | ||
563 | .n_region = 4, | ||
564 | .n_slot = 128, | ||
565 | .n_tc = 2, | ||
566 | .noevent = dma_chan_dm355_no_event, | ||
567 | }; | ||
568 | |||
569 | static struct resource edma_resources[] = { | ||
570 | { | ||
571 | .name = "edma_cc", | ||
572 | .start = 0x01c00000, | ||
573 | .end = 0x01c00000 + SZ_64K - 1, | ||
574 | .flags = IORESOURCE_MEM, | ||
575 | }, | ||
576 | { | ||
577 | .name = "edma_tc0", | ||
578 | .start = 0x01c10000, | ||
579 | .end = 0x01c10000 + SZ_1K - 1, | ||
580 | .flags = IORESOURCE_MEM, | ||
581 | }, | ||
582 | { | ||
583 | .name = "edma_tc1", | ||
584 | .start = 0x01c10400, | ||
585 | .end = 0x01c10400 + SZ_1K - 1, | ||
586 | .flags = IORESOURCE_MEM, | ||
587 | }, | ||
588 | { | ||
589 | .start = IRQ_CCINT0, | ||
590 | .flags = IORESOURCE_IRQ, | ||
591 | }, | ||
592 | { | ||
593 | .start = IRQ_CCERRINT, | ||
594 | .flags = IORESOURCE_IRQ, | ||
595 | }, | ||
596 | /* not using (or muxing) TC*_ERR */ | ||
597 | }; | ||
598 | |||
599 | static struct platform_device dm355_edma_device = { | ||
600 | .name = "edma", | ||
601 | .id = -1, | ||
602 | .dev.platform_data = &dm355_edma_info, | ||
603 | .num_resources = ARRAY_SIZE(edma_resources), | ||
604 | .resource = edma_resources, | ||
605 | }; | ||
606 | |||
607 | /*----------------------------------------------------------------------*/ | ||
608 | |||
609 | static struct map_desc dm355_io_desc[] = { | ||
610 | { | ||
611 | .virtual = IO_VIRT, | ||
612 | .pfn = __phys_to_pfn(IO_PHYS), | ||
613 | .length = IO_SIZE, | ||
614 | .type = MT_DEVICE | ||
615 | }, | ||
616 | { | ||
617 | .virtual = SRAM_VIRT, | ||
618 | .pfn = __phys_to_pfn(0x00010000), | ||
619 | .length = SZ_32K, | ||
620 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | ||
621 | .type = MT_DEVICE, | ||
622 | }, | ||
623 | }; | ||
624 | |||
625 | /* Contents of JTAG ID register used to identify exact cpu type */ | ||
626 | static struct davinci_id dm355_ids[] = { | ||
627 | { | ||
628 | .variant = 0x0, | ||
629 | .part_no = 0xb73b, | ||
630 | .manufacturer = 0x00f, | ||
631 | .cpu_id = DAVINCI_CPU_ID_DM355, | ||
632 | .name = "dm355", | ||
633 | }, | ||
634 | }; | ||
635 | |||
636 | static void __iomem *dm355_psc_bases[] = { | ||
637 | IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), | ||
638 | }; | ||
639 | |||
640 | /* | ||
641 | * T0_BOT: Timer 0, bottom: clockevent source for hrtimers | ||
642 | * T0_TOP: Timer 0, top : clocksource for generic timekeeping | ||
643 | * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) | ||
644 | * T1_TOP: Timer 1, top : <unused> | ||
645 | */ | ||
646 | struct davinci_timer_info dm355_timer_info = { | ||
647 | .timers = davinci_timer_instance, | ||
648 | .clockevent_id = T0_BOT, | ||
649 | .clocksource_id = T0_TOP, | ||
650 | }; | ||
651 | |||
652 | static struct plat_serial8250_port dm355_serial_platform_data[] = { | ||
653 | { | ||
654 | .mapbase = DAVINCI_UART0_BASE, | ||
655 | .irq = IRQ_UARTINT0, | ||
656 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
657 | UPF_IOREMAP, | ||
658 | .iotype = UPIO_MEM, | ||
659 | .regshift = 2, | ||
660 | }, | ||
661 | { | ||
662 | .mapbase = DAVINCI_UART1_BASE, | ||
663 | .irq = IRQ_UARTINT1, | ||
664 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
665 | UPF_IOREMAP, | ||
666 | .iotype = UPIO_MEM, | ||
667 | .regshift = 2, | ||
668 | }, | ||
669 | { | ||
670 | .mapbase = DM355_UART2_BASE, | ||
671 | .irq = IRQ_DM355_UARTINT2, | ||
672 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
673 | UPF_IOREMAP, | ||
674 | .iotype = UPIO_MEM, | ||
675 | .regshift = 2, | ||
676 | }, | ||
677 | { | ||
678 | .flags = 0 | ||
679 | }, | ||
680 | }; | ||
681 | |||
682 | static struct platform_device dm355_serial_device = { | ||
683 | .name = "serial8250", | ||
684 | .id = PLAT8250_DEV_PLATFORM, | ||
685 | .dev = { | ||
686 | .platform_data = dm355_serial_platform_data, | ||
687 | }, | ||
688 | }; | ||
689 | |||
690 | static struct davinci_soc_info davinci_soc_info_dm355 = { | ||
691 | .io_desc = dm355_io_desc, | ||
692 | .io_desc_num = ARRAY_SIZE(dm355_io_desc), | ||
693 | .jtag_id_base = IO_ADDRESS(0x01c40028), | ||
694 | .ids = dm355_ids, | ||
695 | .ids_num = ARRAY_SIZE(dm355_ids), | ||
696 | .cpu_clks = dm355_clks, | ||
697 | .psc_bases = dm355_psc_bases, | ||
698 | .psc_bases_num = ARRAY_SIZE(dm355_psc_bases), | ||
699 | .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), | ||
700 | .pinmux_pins = dm355_pins, | ||
701 | .pinmux_pins_num = ARRAY_SIZE(dm355_pins), | ||
702 | .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), | ||
703 | .intc_type = DAVINCI_INTC_TYPE_AINTC, | ||
704 | .intc_irq_prios = dm355_default_priorities, | ||
705 | .intc_irq_num = DAVINCI_N_AINTC_IRQ, | ||
706 | .timer_info = &dm355_timer_info, | ||
707 | .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), | ||
708 | .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), | ||
709 | .gpio_num = 104, | ||
710 | .gpio_irq = IRQ_DM355_GPIOBNK0, | ||
711 | .serial_dev = &dm355_serial_device, | ||
712 | .sram_dma = 0x00010000, | ||
713 | .sram_len = SZ_32K, | ||
714 | }; | ||
715 | |||
716 | void __init dm355_init(void) | ||
717 | { | ||
718 | davinci_common_init(&davinci_soc_info_dm355); | ||
719 | } | ||
720 | |||
721 | static int __init dm355_init_devices(void) | ||
722 | { | ||
723 | if (!cpu_is_davinci_dm355()) | ||
724 | return 0; | ||
725 | |||
726 | davinci_cfg_reg(DM355_INT_EDMA_CC); | ||
727 | platform_device_register(&dm355_edma_device); | ||
728 | return 0; | ||
729 | } | ||
730 | postcore_initcall(dm355_init_devices); | ||
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index d428ef192eac..fb5449b3c97b 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c | |||
@@ -11,7 +11,11 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/serial_8250.h> | ||
14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/gpio.h> | ||
17 | |||
18 | #include <asm/mach/map.h> | ||
15 | 19 | ||
16 | #include <mach/dm644x.h> | 20 | #include <mach/dm644x.h> |
17 | #include <mach/clock.h> | 21 | #include <mach/clock.h> |
@@ -20,6 +24,9 @@ | |||
20 | #include <mach/irqs.h> | 24 | #include <mach/irqs.h> |
21 | #include <mach/psc.h> | 25 | #include <mach/psc.h> |
22 | #include <mach/mux.h> | 26 | #include <mach/mux.h> |
27 | #include <mach/time.h> | ||
28 | #include <mach/serial.h> | ||
29 | #include <mach/common.h> | ||
23 | 30 | ||
24 | #include "clock.h" | 31 | #include "clock.h" |
25 | #include "mux.h" | 32 | #include "mux.h" |
@@ -312,7 +319,14 @@ struct davinci_clk dm644x_clks[] = { | |||
312 | CLK(NULL, NULL, NULL), | 319 | CLK(NULL, NULL, NULL), |
313 | }; | 320 | }; |
314 | 321 | ||
315 | #if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) | 322 | static struct emac_platform_data dm644x_emac_pdata = { |
323 | .ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET, | ||
324 | .ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET, | ||
325 | .ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET, | ||
326 | .mdio_reg_offset = DM644X_EMAC_MDIO_OFFSET, | ||
327 | .ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE, | ||
328 | .version = EMAC_VERSION_1, | ||
329 | }; | ||
316 | 330 | ||
317 | static struct resource dm644x_emac_resources[] = { | 331 | static struct resource dm644x_emac_resources[] = { |
318 | { | 332 | { |
@@ -330,11 +344,15 @@ static struct resource dm644x_emac_resources[] = { | |||
330 | static struct platform_device dm644x_emac_device = { | 344 | static struct platform_device dm644x_emac_device = { |
331 | .name = "davinci_emac", | 345 | .name = "davinci_emac", |
332 | .id = 1, | 346 | .id = 1, |
347 | .dev = { | ||
348 | .platform_data = &dm644x_emac_pdata, | ||
349 | }, | ||
333 | .num_resources = ARRAY_SIZE(dm644x_emac_resources), | 350 | .num_resources = ARRAY_SIZE(dm644x_emac_resources), |
334 | .resource = dm644x_emac_resources, | 351 | .resource = dm644x_emac_resources, |
335 | }; | 352 | }; |
336 | 353 | ||
337 | #endif | 354 | #define PINMUX0 0x00 |
355 | #define PINMUX1 0x04 | ||
338 | 356 | ||
339 | /* | 357 | /* |
340 | * Device specific mux setup | 358 | * Device specific mux setup |
@@ -343,6 +361,7 @@ static struct platform_device dm644x_emac_device = { | |||
343 | * reg offset mask mode | 361 | * reg offset mask mode |
344 | */ | 362 | */ |
345 | static const struct mux_config dm644x_pins[] = { | 363 | static const struct mux_config dm644x_pins[] = { |
364 | #ifdef CONFIG_DAVINCI_MUX | ||
346 | MUX_CFG(DM644X, HDIREN, 0, 16, 1, 1, true) | 365 | MUX_CFG(DM644X, HDIREN, 0, 16, 1, 1, true) |
347 | MUX_CFG(DM644X, ATAEN, 0, 17, 1, 1, true) | 366 | MUX_CFG(DM644X, ATAEN, 0, 17, 1, 1, true) |
348 | MUX_CFG(DM644X, ATAEN_DISABLE, 0, 17, 1, 0, true) | 367 | MUX_CFG(DM644X, ATAEN_DISABLE, 0, 17, 1, 0, true) |
@@ -383,8 +402,76 @@ MUX_CFG(DM644X, RGB666, 0, 22, 1, 1, true) | |||
383 | 402 | ||
384 | MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true) | 403 | MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true) |
385 | MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false) | 404 | MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false) |
405 | #endif | ||
386 | }; | 406 | }; |
387 | 407 | ||
408 | /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ | ||
409 | static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = { | ||
410 | [IRQ_VDINT0] = 2, | ||
411 | [IRQ_VDINT1] = 6, | ||
412 | [IRQ_VDINT2] = 6, | ||
413 | [IRQ_HISTINT] = 6, | ||
414 | [IRQ_H3AINT] = 6, | ||
415 | [IRQ_PRVUINT] = 6, | ||
416 | [IRQ_RSZINT] = 6, | ||
417 | [7] = 7, | ||
418 | [IRQ_VENCINT] = 6, | ||
419 | [IRQ_ASQINT] = 6, | ||
420 | [IRQ_IMXINT] = 6, | ||
421 | [IRQ_VLCDINT] = 6, | ||
422 | [IRQ_USBINT] = 4, | ||
423 | [IRQ_EMACINT] = 4, | ||
424 | [14] = 7, | ||
425 | [15] = 7, | ||
426 | [IRQ_CCINT0] = 5, /* dma */ | ||
427 | [IRQ_CCERRINT] = 5, /* dma */ | ||
428 | [IRQ_TCERRINT0] = 5, /* dma */ | ||
429 | [IRQ_TCERRINT] = 5, /* dma */ | ||
430 | [IRQ_PSCIN] = 7, | ||
431 | [21] = 7, | ||
432 | [IRQ_IDE] = 4, | ||
433 | [23] = 7, | ||
434 | [IRQ_MBXINT] = 7, | ||
435 | [IRQ_MBRINT] = 7, | ||
436 | [IRQ_MMCINT] = 7, | ||
437 | [IRQ_SDIOINT] = 7, | ||
438 | [28] = 7, | ||
439 | [IRQ_DDRINT] = 7, | ||
440 | [IRQ_AEMIFINT] = 7, | ||
441 | [IRQ_VLQINT] = 4, | ||
442 | [IRQ_TINT0_TINT12] = 2, /* clockevent */ | ||
443 | [IRQ_TINT0_TINT34] = 2, /* clocksource */ | ||
444 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | ||
445 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | ||
446 | [IRQ_PWMINT0] = 7, | ||
447 | [IRQ_PWMINT1] = 7, | ||
448 | [IRQ_PWMINT2] = 7, | ||
449 | [IRQ_I2C] = 3, | ||
450 | [IRQ_UARTINT0] = 3, | ||
451 | [IRQ_UARTINT1] = 3, | ||
452 | [IRQ_UARTINT2] = 3, | ||
453 | [IRQ_SPINT0] = 3, | ||
454 | [IRQ_SPINT1] = 3, | ||
455 | [45] = 7, | ||
456 | [IRQ_DSP2ARM0] = 4, | ||
457 | [IRQ_DSP2ARM1] = 4, | ||
458 | [IRQ_GPIO0] = 7, | ||
459 | [IRQ_GPIO1] = 7, | ||
460 | [IRQ_GPIO2] = 7, | ||
461 | [IRQ_GPIO3] = 7, | ||
462 | [IRQ_GPIO4] = 7, | ||
463 | [IRQ_GPIO5] = 7, | ||
464 | [IRQ_GPIO6] = 7, | ||
465 | [IRQ_GPIO7] = 7, | ||
466 | [IRQ_GPIOBNK0] = 7, | ||
467 | [IRQ_GPIOBNK1] = 7, | ||
468 | [IRQ_GPIOBNK2] = 7, | ||
469 | [IRQ_GPIOBNK3] = 7, | ||
470 | [IRQ_GPIOBNK4] = 7, | ||
471 | [IRQ_COMMTX] = 7, | ||
472 | [IRQ_COMMRX] = 7, | ||
473 | [IRQ_EMUINT] = 7, | ||
474 | }; | ||
388 | 475 | ||
389 | /*----------------------------------------------------------------------*/ | 476 | /*----------------------------------------------------------------------*/ |
390 | 477 | ||
@@ -444,10 +531,118 @@ static struct platform_device dm644x_edma_device = { | |||
444 | }; | 531 | }; |
445 | 532 | ||
446 | /*----------------------------------------------------------------------*/ | 533 | /*----------------------------------------------------------------------*/ |
534 | |||
535 | static struct map_desc dm644x_io_desc[] = { | ||
536 | { | ||
537 | .virtual = IO_VIRT, | ||
538 | .pfn = __phys_to_pfn(IO_PHYS), | ||
539 | .length = IO_SIZE, | ||
540 | .type = MT_DEVICE | ||
541 | }, | ||
542 | { | ||
543 | .virtual = SRAM_VIRT, | ||
544 | .pfn = __phys_to_pfn(0x00008000), | ||
545 | .length = SZ_16K, | ||
546 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | ||
547 | .type = MT_DEVICE, | ||
548 | }, | ||
549 | }; | ||
550 | |||
551 | /* Contents of JTAG ID register used to identify exact cpu type */ | ||
552 | static struct davinci_id dm644x_ids[] = { | ||
553 | { | ||
554 | .variant = 0x0, | ||
555 | .part_no = 0xb700, | ||
556 | .manufacturer = 0x017, | ||
557 | .cpu_id = DAVINCI_CPU_ID_DM6446, | ||
558 | .name = "dm6446", | ||
559 | }, | ||
560 | }; | ||
561 | |||
562 | static void __iomem *dm644x_psc_bases[] = { | ||
563 | IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), | ||
564 | }; | ||
565 | |||
566 | /* | ||
567 | * T0_BOT: Timer 0, bottom: clockevent source for hrtimers | ||
568 | * T0_TOP: Timer 0, top : clocksource for generic timekeeping | ||
569 | * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) | ||
570 | * T1_TOP: Timer 1, top : <unused> | ||
571 | */ | ||
572 | struct davinci_timer_info dm644x_timer_info = { | ||
573 | .timers = davinci_timer_instance, | ||
574 | .clockevent_id = T0_BOT, | ||
575 | .clocksource_id = T0_TOP, | ||
576 | }; | ||
577 | |||
578 | static struct plat_serial8250_port dm644x_serial_platform_data[] = { | ||
579 | { | ||
580 | .mapbase = DAVINCI_UART0_BASE, | ||
581 | .irq = IRQ_UARTINT0, | ||
582 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
583 | UPF_IOREMAP, | ||
584 | .iotype = UPIO_MEM, | ||
585 | .regshift = 2, | ||
586 | }, | ||
587 | { | ||
588 | .mapbase = DAVINCI_UART1_BASE, | ||
589 | .irq = IRQ_UARTINT1, | ||
590 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
591 | UPF_IOREMAP, | ||
592 | .iotype = UPIO_MEM, | ||
593 | .regshift = 2, | ||
594 | }, | ||
595 | { | ||
596 | .mapbase = DAVINCI_UART2_BASE, | ||
597 | .irq = IRQ_UARTINT2, | ||
598 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
599 | UPF_IOREMAP, | ||
600 | .iotype = UPIO_MEM, | ||
601 | .regshift = 2, | ||
602 | }, | ||
603 | { | ||
604 | .flags = 0 | ||
605 | }, | ||
606 | }; | ||
607 | |||
608 | static struct platform_device dm644x_serial_device = { | ||
609 | .name = "serial8250", | ||
610 | .id = PLAT8250_DEV_PLATFORM, | ||
611 | .dev = { | ||
612 | .platform_data = dm644x_serial_platform_data, | ||
613 | }, | ||
614 | }; | ||
615 | |||
616 | static struct davinci_soc_info davinci_soc_info_dm644x = { | ||
617 | .io_desc = dm644x_io_desc, | ||
618 | .io_desc_num = ARRAY_SIZE(dm644x_io_desc), | ||
619 | .jtag_id_base = IO_ADDRESS(0x01c40028), | ||
620 | .ids = dm644x_ids, | ||
621 | .ids_num = ARRAY_SIZE(dm644x_ids), | ||
622 | .cpu_clks = dm644x_clks, | ||
623 | .psc_bases = dm644x_psc_bases, | ||
624 | .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases), | ||
625 | .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), | ||
626 | .pinmux_pins = dm644x_pins, | ||
627 | .pinmux_pins_num = ARRAY_SIZE(dm644x_pins), | ||
628 | .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), | ||
629 | .intc_type = DAVINCI_INTC_TYPE_AINTC, | ||
630 | .intc_irq_prios = dm644x_default_priorities, | ||
631 | .intc_irq_num = DAVINCI_N_AINTC_IRQ, | ||
632 | .timer_info = &dm644x_timer_info, | ||
633 | .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), | ||
634 | .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), | ||
635 | .gpio_num = 71, | ||
636 | .gpio_irq = IRQ_GPIOBNK0, | ||
637 | .serial_dev = &dm644x_serial_device, | ||
638 | .emac_pdata = &dm644x_emac_pdata, | ||
639 | .sram_dma = 0x00008000, | ||
640 | .sram_len = SZ_16K, | ||
641 | }; | ||
642 | |||
447 | void __init dm644x_init(void) | 643 | void __init dm644x_init(void) |
448 | { | 644 | { |
449 | davinci_clk_init(dm644x_clks); | 645 | davinci_common_init(&davinci_soc_info_dm644x); |
450 | davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins)); | ||
451 | } | 646 | } |
452 | 647 | ||
453 | static int __init dm644x_init_devices(void) | 648 | static int __init dm644x_init_devices(void) |
@@ -456,6 +651,7 @@ static int __init dm644x_init_devices(void) | |||
456 | return 0; | 651 | return 0; |
457 | 652 | ||
458 | platform_device_register(&dm644x_edma_device); | 653 | platform_device_register(&dm644x_edma_device); |
654 | platform_device_register(&dm644x_emac_device); | ||
459 | return 0; | 655 | return 0; |
460 | } | 656 | } |
461 | postcore_initcall(dm644x_init_devices); | 657 | postcore_initcall(dm644x_init_devices); |
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c new file mode 100644 index 000000000000..334f0711e0f5 --- /dev/null +++ b/arch/arm/mach-davinci/dm646x.c | |||
@@ -0,0 +1,636 @@ | |||
1 | /* | ||
2 | * TI DaVinci DM644x chip specific setup | ||
3 | * | ||
4 | * Author: Kevin Hilman, Deep Root Systems, LLC | ||
5 | * | ||
6 | * 2007 (c) Deep Root Systems, LLC. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/serial_8250.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/gpio.h> | ||
17 | |||
18 | #include <asm/mach/map.h> | ||
19 | |||
20 | #include <mach/dm646x.h> | ||
21 | #include <mach/clock.h> | ||
22 | #include <mach/cputype.h> | ||
23 | #include <mach/edma.h> | ||
24 | #include <mach/irqs.h> | ||
25 | #include <mach/psc.h> | ||
26 | #include <mach/mux.h> | ||
27 | #include <mach/time.h> | ||
28 | #include <mach/serial.h> | ||
29 | #include <mach/common.h> | ||
30 | |||
31 | #include "clock.h" | ||
32 | #include "mux.h" | ||
33 | |||
34 | /* | ||
35 | * Device specific clocks | ||
36 | */ | ||
37 | #define DM646X_REF_FREQ 27000000 | ||
38 | #define DM646X_AUX_FREQ 24000000 | ||
39 | |||
40 | static struct pll_data pll1_data = { | ||
41 | .num = 1, | ||
42 | .phys_base = DAVINCI_PLL1_BASE, | ||
43 | }; | ||
44 | |||
45 | static struct pll_data pll2_data = { | ||
46 | .num = 2, | ||
47 | .phys_base = DAVINCI_PLL2_BASE, | ||
48 | }; | ||
49 | |||
50 | static struct clk ref_clk = { | ||
51 | .name = "ref_clk", | ||
52 | .rate = DM646X_REF_FREQ, | ||
53 | }; | ||
54 | |||
55 | static struct clk aux_clkin = { | ||
56 | .name = "aux_clkin", | ||
57 | .rate = DM646X_AUX_FREQ, | ||
58 | }; | ||
59 | |||
60 | static struct clk pll1_clk = { | ||
61 | .name = "pll1", | ||
62 | .parent = &ref_clk, | ||
63 | .pll_data = &pll1_data, | ||
64 | .flags = CLK_PLL, | ||
65 | }; | ||
66 | |||
67 | static struct clk pll1_sysclk1 = { | ||
68 | .name = "pll1_sysclk1", | ||
69 | .parent = &pll1_clk, | ||
70 | .flags = CLK_PLL, | ||
71 | .div_reg = PLLDIV1, | ||
72 | }; | ||
73 | |||
74 | static struct clk pll1_sysclk2 = { | ||
75 | .name = "pll1_sysclk2", | ||
76 | .parent = &pll1_clk, | ||
77 | .flags = CLK_PLL, | ||
78 | .div_reg = PLLDIV2, | ||
79 | }; | ||
80 | |||
81 | static struct clk pll1_sysclk3 = { | ||
82 | .name = "pll1_sysclk3", | ||
83 | .parent = &pll1_clk, | ||
84 | .flags = CLK_PLL, | ||
85 | .div_reg = PLLDIV3, | ||
86 | }; | ||
87 | |||
88 | static struct clk pll1_sysclk4 = { | ||
89 | .name = "pll1_sysclk4", | ||
90 | .parent = &pll1_clk, | ||
91 | .flags = CLK_PLL, | ||
92 | .div_reg = PLLDIV4, | ||
93 | }; | ||
94 | |||
95 | static struct clk pll1_sysclk5 = { | ||
96 | .name = "pll1_sysclk5", | ||
97 | .parent = &pll1_clk, | ||
98 | .flags = CLK_PLL, | ||
99 | .div_reg = PLLDIV5, | ||
100 | }; | ||
101 | |||
102 | static struct clk pll1_sysclk6 = { | ||
103 | .name = "pll1_sysclk6", | ||
104 | .parent = &pll1_clk, | ||
105 | .flags = CLK_PLL, | ||
106 | .div_reg = PLLDIV6, | ||
107 | }; | ||
108 | |||
109 | static struct clk pll1_sysclk8 = { | ||
110 | .name = "pll1_sysclk8", | ||
111 | .parent = &pll1_clk, | ||
112 | .flags = CLK_PLL, | ||
113 | .div_reg = PLLDIV8, | ||
114 | }; | ||
115 | |||
116 | static struct clk pll1_sysclk9 = { | ||
117 | .name = "pll1_sysclk9", | ||
118 | .parent = &pll1_clk, | ||
119 | .flags = CLK_PLL, | ||
120 | .div_reg = PLLDIV9, | ||
121 | }; | ||
122 | |||
123 | static struct clk pll1_sysclkbp = { | ||
124 | .name = "pll1_sysclkbp", | ||
125 | .parent = &pll1_clk, | ||
126 | .flags = CLK_PLL | PRE_PLL, | ||
127 | .div_reg = BPDIV, | ||
128 | }; | ||
129 | |||
130 | static struct clk pll1_aux_clk = { | ||
131 | .name = "pll1_aux_clk", | ||
132 | .parent = &pll1_clk, | ||
133 | .flags = CLK_PLL | PRE_PLL, | ||
134 | }; | ||
135 | |||
136 | static struct clk pll2_clk = { | ||
137 | .name = "pll2_clk", | ||
138 | .parent = &ref_clk, | ||
139 | .pll_data = &pll2_data, | ||
140 | .flags = CLK_PLL, | ||
141 | }; | ||
142 | |||
143 | static struct clk pll2_sysclk1 = { | ||
144 | .name = "pll2_sysclk1", | ||
145 | .parent = &pll2_clk, | ||
146 | .flags = CLK_PLL, | ||
147 | .div_reg = PLLDIV1, | ||
148 | }; | ||
149 | |||
150 | static struct clk dsp_clk = { | ||
151 | .name = "dsp", | ||
152 | .parent = &pll1_sysclk1, | ||
153 | .lpsc = DM646X_LPSC_C64X_CPU, | ||
154 | .flags = PSC_DSP, | ||
155 | .usecount = 1, /* REVISIT how to disable? */ | ||
156 | }; | ||
157 | |||
158 | static struct clk arm_clk = { | ||
159 | .name = "arm", | ||
160 | .parent = &pll1_sysclk2, | ||
161 | .lpsc = DM646X_LPSC_ARM, | ||
162 | .flags = ALWAYS_ENABLED, | ||
163 | }; | ||
164 | |||
165 | static struct clk uart0_clk = { | ||
166 | .name = "uart0", | ||
167 | .parent = &aux_clkin, | ||
168 | .lpsc = DM646X_LPSC_UART0, | ||
169 | }; | ||
170 | |||
171 | static struct clk uart1_clk = { | ||
172 | .name = "uart1", | ||
173 | .parent = &aux_clkin, | ||
174 | .lpsc = DM646X_LPSC_UART1, | ||
175 | }; | ||
176 | |||
177 | static struct clk uart2_clk = { | ||
178 | .name = "uart2", | ||
179 | .parent = &aux_clkin, | ||
180 | .lpsc = DM646X_LPSC_UART2, | ||
181 | }; | ||
182 | |||
183 | static struct clk i2c_clk = { | ||
184 | .name = "I2CCLK", | ||
185 | .parent = &pll1_sysclk3, | ||
186 | .lpsc = DM646X_LPSC_I2C, | ||
187 | }; | ||
188 | |||
189 | static struct clk gpio_clk = { | ||
190 | .name = "gpio", | ||
191 | .parent = &pll1_sysclk3, | ||
192 | .lpsc = DM646X_LPSC_GPIO, | ||
193 | }; | ||
194 | |||
195 | static struct clk aemif_clk = { | ||
196 | .name = "aemif", | ||
197 | .parent = &pll1_sysclk3, | ||
198 | .lpsc = DM646X_LPSC_AEMIF, | ||
199 | .flags = ALWAYS_ENABLED, | ||
200 | }; | ||
201 | |||
202 | static struct clk emac_clk = { | ||
203 | .name = "emac", | ||
204 | .parent = &pll1_sysclk3, | ||
205 | .lpsc = DM646X_LPSC_EMAC, | ||
206 | }; | ||
207 | |||
208 | static struct clk pwm0_clk = { | ||
209 | .name = "pwm0", | ||
210 | .parent = &pll1_sysclk3, | ||
211 | .lpsc = DM646X_LPSC_PWM0, | ||
212 | .usecount = 1, /* REVIST: disabling hangs system */ | ||
213 | }; | ||
214 | |||
215 | static struct clk pwm1_clk = { | ||
216 | .name = "pwm1", | ||
217 | .parent = &pll1_sysclk3, | ||
218 | .lpsc = DM646X_LPSC_PWM1, | ||
219 | .usecount = 1, /* REVIST: disabling hangs system */ | ||
220 | }; | ||
221 | |||
222 | static struct clk timer0_clk = { | ||
223 | .name = "timer0", | ||
224 | .parent = &pll1_sysclk3, | ||
225 | .lpsc = DM646X_LPSC_TIMER0, | ||
226 | }; | ||
227 | |||
228 | static struct clk timer1_clk = { | ||
229 | .name = "timer1", | ||
230 | .parent = &pll1_sysclk3, | ||
231 | .lpsc = DM646X_LPSC_TIMER1, | ||
232 | }; | ||
233 | |||
234 | static struct clk timer2_clk = { | ||
235 | .name = "timer2", | ||
236 | .parent = &pll1_sysclk3, | ||
237 | .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */ | ||
238 | }; | ||
239 | |||
240 | static struct clk vpif0_clk = { | ||
241 | .name = "vpif0", | ||
242 | .parent = &ref_clk, | ||
243 | .lpsc = DM646X_LPSC_VPSSMSTR, | ||
244 | .flags = ALWAYS_ENABLED, | ||
245 | }; | ||
246 | |||
247 | static struct clk vpif1_clk = { | ||
248 | .name = "vpif1", | ||
249 | .parent = &ref_clk, | ||
250 | .lpsc = DM646X_LPSC_VPSSSLV, | ||
251 | .flags = ALWAYS_ENABLED, | ||
252 | }; | ||
253 | |||
254 | struct davinci_clk dm646x_clks[] = { | ||
255 | CLK(NULL, "ref", &ref_clk), | ||
256 | CLK(NULL, "aux", &aux_clkin), | ||
257 | CLK(NULL, "pll1", &pll1_clk), | ||
258 | CLK(NULL, "pll1_sysclk", &pll1_sysclk1), | ||
259 | CLK(NULL, "pll1_sysclk", &pll1_sysclk2), | ||
260 | CLK(NULL, "pll1_sysclk", &pll1_sysclk3), | ||
261 | CLK(NULL, "pll1_sysclk", &pll1_sysclk4), | ||
262 | CLK(NULL, "pll1_sysclk", &pll1_sysclk5), | ||
263 | CLK(NULL, "pll1_sysclk", &pll1_sysclk6), | ||
264 | CLK(NULL, "pll1_sysclk", &pll1_sysclk8), | ||
265 | CLK(NULL, "pll1_sysclk", &pll1_sysclk9), | ||
266 | CLK(NULL, "pll1_sysclk", &pll1_sysclkbp), | ||
267 | CLK(NULL, "pll1_aux", &pll1_aux_clk), | ||
268 | CLK(NULL, "pll2", &pll2_clk), | ||
269 | CLK(NULL, "pll2_sysclk1", &pll2_sysclk1), | ||
270 | CLK(NULL, "dsp", &dsp_clk), | ||
271 | CLK(NULL, "arm", &arm_clk), | ||
272 | CLK(NULL, "uart0", &uart0_clk), | ||
273 | CLK(NULL, "uart1", &uart1_clk), | ||
274 | CLK(NULL, "uart2", &uart2_clk), | ||
275 | CLK("i2c_davinci.1", NULL, &i2c_clk), | ||
276 | CLK(NULL, "gpio", &gpio_clk), | ||
277 | CLK(NULL, "aemif", &aemif_clk), | ||
278 | CLK("davinci_emac.1", NULL, &emac_clk), | ||
279 | CLK(NULL, "pwm0", &pwm0_clk), | ||
280 | CLK(NULL, "pwm1", &pwm1_clk), | ||
281 | CLK(NULL, "timer0", &timer0_clk), | ||
282 | CLK(NULL, "timer1", &timer1_clk), | ||
283 | CLK("watchdog", NULL, &timer2_clk), | ||
284 | CLK(NULL, "vpif0", &vpif0_clk), | ||
285 | CLK(NULL, "vpif1", &vpif1_clk), | ||
286 | CLK(NULL, NULL, NULL), | ||
287 | }; | ||
288 | |||
289 | static struct emac_platform_data dm646x_emac_pdata = { | ||
290 | .ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET, | ||
291 | .ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET, | ||
292 | .ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET, | ||
293 | .mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET, | ||
294 | .ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE, | ||
295 | .version = EMAC_VERSION_2, | ||
296 | }; | ||
297 | |||
298 | static struct resource dm646x_emac_resources[] = { | ||
299 | { | ||
300 | .start = DM646X_EMAC_BASE, | ||
301 | .end = DM646X_EMAC_BASE + 0x47ff, | ||
302 | .flags = IORESOURCE_MEM, | ||
303 | }, | ||
304 | { | ||
305 | .start = IRQ_DM646X_EMACRXTHINT, | ||
306 | .end = IRQ_DM646X_EMACRXTHINT, | ||
307 | .flags = IORESOURCE_IRQ, | ||
308 | }, | ||
309 | { | ||
310 | .start = IRQ_DM646X_EMACRXINT, | ||
311 | .end = IRQ_DM646X_EMACRXINT, | ||
312 | .flags = IORESOURCE_IRQ, | ||
313 | }, | ||
314 | { | ||
315 | .start = IRQ_DM646X_EMACTXINT, | ||
316 | .end = IRQ_DM646X_EMACTXINT, | ||
317 | .flags = IORESOURCE_IRQ, | ||
318 | }, | ||
319 | { | ||
320 | .start = IRQ_DM646X_EMACMISCINT, | ||
321 | .end = IRQ_DM646X_EMACMISCINT, | ||
322 | .flags = IORESOURCE_IRQ, | ||
323 | }, | ||
324 | }; | ||
325 | |||
326 | static struct platform_device dm646x_emac_device = { | ||
327 | .name = "davinci_emac", | ||
328 | .id = 1, | ||
329 | .dev = { | ||
330 | .platform_data = &dm646x_emac_pdata, | ||
331 | }, | ||
332 | .num_resources = ARRAY_SIZE(dm646x_emac_resources), | ||
333 | .resource = dm646x_emac_resources, | ||
334 | }; | ||
335 | |||
336 | #define PINMUX0 0x00 | ||
337 | #define PINMUX1 0x04 | ||
338 | |||
339 | /* | ||
340 | * Device specific mux setup | ||
341 | * | ||
342 | * soc description mux mode mode mux dbg | ||
343 | * reg offset mask mode | ||
344 | */ | ||
345 | static const struct mux_config dm646x_pins[] = { | ||
346 | #ifdef CONFIG_DAVINCI_MUX | ||
347 | MUX_CFG(DM646X, ATAEN, 0, 0, 1, 1, true) | ||
348 | |||
349 | MUX_CFG(DM646X, AUDCK1, 0, 29, 1, 0, false) | ||
350 | |||
351 | MUX_CFG(DM646X, AUDCK0, 0, 28, 1, 0, false) | ||
352 | |||
353 | MUX_CFG(DM646X, CRGMUX, 0, 24, 7, 5, true) | ||
354 | |||
355 | MUX_CFG(DM646X, STSOMUX_DISABLE, 0, 22, 3, 0, true) | ||
356 | |||
357 | MUX_CFG(DM646X, STSIMUX_DISABLE, 0, 20, 3, 0, true) | ||
358 | |||
359 | MUX_CFG(DM646X, PTSOMUX_DISABLE, 0, 18, 3, 0, true) | ||
360 | |||
361 | MUX_CFG(DM646X, PTSIMUX_DISABLE, 0, 16, 3, 0, true) | ||
362 | |||
363 | MUX_CFG(DM646X, STSOMUX, 0, 22, 3, 2, true) | ||
364 | |||
365 | MUX_CFG(DM646X, STSIMUX, 0, 20, 3, 2, true) | ||
366 | |||
367 | MUX_CFG(DM646X, PTSOMUX_PARALLEL, 0, 18, 3, 2, true) | ||
368 | |||
369 | MUX_CFG(DM646X, PTSIMUX_PARALLEL, 0, 16, 3, 2, true) | ||
370 | |||
371 | MUX_CFG(DM646X, PTSOMUX_SERIAL, 0, 18, 3, 3, true) | ||
372 | |||
373 | MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true) | ||
374 | #endif | ||
375 | }; | ||
376 | |||
377 | static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = { | ||
378 | [IRQ_DM646X_VP_VERTINT0] = 7, | ||
379 | [IRQ_DM646X_VP_VERTINT1] = 7, | ||
380 | [IRQ_DM646X_VP_VERTINT2] = 7, | ||
381 | [IRQ_DM646X_VP_VERTINT3] = 7, | ||
382 | [IRQ_DM646X_VP_ERRINT] = 7, | ||
383 | [IRQ_DM646X_RESERVED_1] = 7, | ||
384 | [IRQ_DM646X_RESERVED_2] = 7, | ||
385 | [IRQ_DM646X_WDINT] = 7, | ||
386 | [IRQ_DM646X_CRGENINT0] = 7, | ||
387 | [IRQ_DM646X_CRGENINT1] = 7, | ||
388 | [IRQ_DM646X_TSIFINT0] = 7, | ||
389 | [IRQ_DM646X_TSIFINT1] = 7, | ||
390 | [IRQ_DM646X_VDCEINT] = 7, | ||
391 | [IRQ_DM646X_USBINT] = 7, | ||
392 | [IRQ_DM646X_USBDMAINT] = 7, | ||
393 | [IRQ_DM646X_PCIINT] = 7, | ||
394 | [IRQ_CCINT0] = 7, /* dma */ | ||
395 | [IRQ_CCERRINT] = 7, /* dma */ | ||
396 | [IRQ_TCERRINT0] = 7, /* dma */ | ||
397 | [IRQ_TCERRINT] = 7, /* dma */ | ||
398 | [IRQ_DM646X_TCERRINT2] = 7, | ||
399 | [IRQ_DM646X_TCERRINT3] = 7, | ||
400 | [IRQ_DM646X_IDE] = 7, | ||
401 | [IRQ_DM646X_HPIINT] = 7, | ||
402 | [IRQ_DM646X_EMACRXTHINT] = 7, | ||
403 | [IRQ_DM646X_EMACRXINT] = 7, | ||
404 | [IRQ_DM646X_EMACTXINT] = 7, | ||
405 | [IRQ_DM646X_EMACMISCINT] = 7, | ||
406 | [IRQ_DM646X_MCASP0TXINT] = 7, | ||
407 | [IRQ_DM646X_MCASP0RXINT] = 7, | ||
408 | [IRQ_AEMIFINT] = 7, | ||
409 | [IRQ_DM646X_RESERVED_3] = 7, | ||
410 | [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */ | ||
411 | [IRQ_TINT0_TINT34] = 7, /* clocksource */ | ||
412 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | ||
413 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | ||
414 | [IRQ_PWMINT0] = 7, | ||
415 | [IRQ_PWMINT1] = 7, | ||
416 | [IRQ_DM646X_VLQINT] = 7, | ||
417 | [IRQ_I2C] = 7, | ||
418 | [IRQ_UARTINT0] = 7, | ||
419 | [IRQ_UARTINT1] = 7, | ||
420 | [IRQ_DM646X_UARTINT2] = 7, | ||
421 | [IRQ_DM646X_SPINT0] = 7, | ||
422 | [IRQ_DM646X_SPINT1] = 7, | ||
423 | [IRQ_DM646X_DSP2ARMINT] = 7, | ||
424 | [IRQ_DM646X_RESERVED_4] = 7, | ||
425 | [IRQ_DM646X_PSCINT] = 7, | ||
426 | [IRQ_DM646X_GPIO0] = 7, | ||
427 | [IRQ_DM646X_GPIO1] = 7, | ||
428 | [IRQ_DM646X_GPIO2] = 7, | ||
429 | [IRQ_DM646X_GPIO3] = 7, | ||
430 | [IRQ_DM646X_GPIO4] = 7, | ||
431 | [IRQ_DM646X_GPIO5] = 7, | ||
432 | [IRQ_DM646X_GPIO6] = 7, | ||
433 | [IRQ_DM646X_GPIO7] = 7, | ||
434 | [IRQ_DM646X_GPIOBNK0] = 7, | ||
435 | [IRQ_DM646X_GPIOBNK1] = 7, | ||
436 | [IRQ_DM646X_GPIOBNK2] = 7, | ||
437 | [IRQ_DM646X_DDRINT] = 7, | ||
438 | [IRQ_DM646X_AEMIFINT] = 7, | ||
439 | [IRQ_COMMTX] = 7, | ||
440 | [IRQ_COMMRX] = 7, | ||
441 | [IRQ_EMUINT] = 7, | ||
442 | }; | ||
443 | |||
444 | /*----------------------------------------------------------------------*/ | ||
445 | |||
446 | static const s8 dma_chan_dm646x_no_event[] = { | ||
447 | 0, 1, 2, 3, 13, | ||
448 | 14, 15, 24, 25, 26, | ||
449 | 27, 30, 31, 54, 55, | ||
450 | 56, | ||
451 | -1 | ||
452 | }; | ||
453 | |||
454 | static struct edma_soc_info dm646x_edma_info = { | ||
455 | .n_channel = 64, | ||
456 | .n_region = 6, /* 0-1, 4-7 */ | ||
457 | .n_slot = 512, | ||
458 | .n_tc = 4, | ||
459 | .noevent = dma_chan_dm646x_no_event, | ||
460 | }; | ||
461 | |||
462 | static struct resource edma_resources[] = { | ||
463 | { | ||
464 | .name = "edma_cc", | ||
465 | .start = 0x01c00000, | ||
466 | .end = 0x01c00000 + SZ_64K - 1, | ||
467 | .flags = IORESOURCE_MEM, | ||
468 | }, | ||
469 | { | ||
470 | .name = "edma_tc0", | ||
471 | .start = 0x01c10000, | ||
472 | .end = 0x01c10000 + SZ_1K - 1, | ||
473 | .flags = IORESOURCE_MEM, | ||
474 | }, | ||
475 | { | ||
476 | .name = "edma_tc1", | ||
477 | .start = 0x01c10400, | ||
478 | .end = 0x01c10400 + SZ_1K - 1, | ||
479 | .flags = IORESOURCE_MEM, | ||
480 | }, | ||
481 | { | ||
482 | .name = "edma_tc2", | ||
483 | .start = 0x01c10800, | ||
484 | .end = 0x01c10800 + SZ_1K - 1, | ||
485 | .flags = IORESOURCE_MEM, | ||
486 | }, | ||
487 | { | ||
488 | .name = "edma_tc3", | ||
489 | .start = 0x01c10c00, | ||
490 | .end = 0x01c10c00 + SZ_1K - 1, | ||
491 | .flags = IORESOURCE_MEM, | ||
492 | }, | ||
493 | { | ||
494 | .start = IRQ_CCINT0, | ||
495 | .flags = IORESOURCE_IRQ, | ||
496 | }, | ||
497 | { | ||
498 | .start = IRQ_CCERRINT, | ||
499 | .flags = IORESOURCE_IRQ, | ||
500 | }, | ||
501 | /* not using TC*_ERR */ | ||
502 | }; | ||
503 | |||
504 | static struct platform_device dm646x_edma_device = { | ||
505 | .name = "edma", | ||
506 | .id = -1, | ||
507 | .dev.platform_data = &dm646x_edma_info, | ||
508 | .num_resources = ARRAY_SIZE(edma_resources), | ||
509 | .resource = edma_resources, | ||
510 | }; | ||
511 | |||
512 | /*----------------------------------------------------------------------*/ | ||
513 | |||
514 | static struct map_desc dm646x_io_desc[] = { | ||
515 | { | ||
516 | .virtual = IO_VIRT, | ||
517 | .pfn = __phys_to_pfn(IO_PHYS), | ||
518 | .length = IO_SIZE, | ||
519 | .type = MT_DEVICE | ||
520 | }, | ||
521 | { | ||
522 | .virtual = SRAM_VIRT, | ||
523 | .pfn = __phys_to_pfn(0x00010000), | ||
524 | .length = SZ_32K, | ||
525 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | ||
526 | .type = MT_DEVICE, | ||
527 | }, | ||
528 | }; | ||
529 | |||
530 | /* Contents of JTAG ID register used to identify exact cpu type */ | ||
531 | static struct davinci_id dm646x_ids[] = { | ||
532 | { | ||
533 | .variant = 0x0, | ||
534 | .part_no = 0xb770, | ||
535 | .manufacturer = 0x017, | ||
536 | .cpu_id = DAVINCI_CPU_ID_DM6467, | ||
537 | .name = "dm6467", | ||
538 | }, | ||
539 | }; | ||
540 | |||
541 | static void __iomem *dm646x_psc_bases[] = { | ||
542 | IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), | ||
543 | }; | ||
544 | |||
545 | /* | ||
546 | * T0_BOT: Timer 0, bottom: clockevent source for hrtimers | ||
547 | * T0_TOP: Timer 0, top : clocksource for generic timekeeping | ||
548 | * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) | ||
549 | * T1_TOP: Timer 1, top : <unused> | ||
550 | */ | ||
551 | struct davinci_timer_info dm646x_timer_info = { | ||
552 | .timers = davinci_timer_instance, | ||
553 | .clockevent_id = T0_BOT, | ||
554 | .clocksource_id = T0_TOP, | ||
555 | }; | ||
556 | |||
557 | static struct plat_serial8250_port dm646x_serial_platform_data[] = { | ||
558 | { | ||
559 | .mapbase = DAVINCI_UART0_BASE, | ||
560 | .irq = IRQ_UARTINT0, | ||
561 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
562 | UPF_IOREMAP, | ||
563 | .iotype = UPIO_MEM32, | ||
564 | .regshift = 2, | ||
565 | }, | ||
566 | { | ||
567 | .mapbase = DAVINCI_UART1_BASE, | ||
568 | .irq = IRQ_UARTINT1, | ||
569 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
570 | UPF_IOREMAP, | ||
571 | .iotype = UPIO_MEM32, | ||
572 | .regshift = 2, | ||
573 | }, | ||
574 | { | ||
575 | .mapbase = DAVINCI_UART2_BASE, | ||
576 | .irq = IRQ_DM646X_UARTINT2, | ||
577 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
578 | UPF_IOREMAP, | ||
579 | .iotype = UPIO_MEM32, | ||
580 | .regshift = 2, | ||
581 | }, | ||
582 | { | ||
583 | .flags = 0 | ||
584 | }, | ||
585 | }; | ||
586 | |||
587 | static struct platform_device dm646x_serial_device = { | ||
588 | .name = "serial8250", | ||
589 | .id = PLAT8250_DEV_PLATFORM, | ||
590 | .dev = { | ||
591 | .platform_data = dm646x_serial_platform_data, | ||
592 | }, | ||
593 | }; | ||
594 | |||
595 | static struct davinci_soc_info davinci_soc_info_dm646x = { | ||
596 | .io_desc = dm646x_io_desc, | ||
597 | .io_desc_num = ARRAY_SIZE(dm646x_io_desc), | ||
598 | .jtag_id_base = IO_ADDRESS(0x01c40028), | ||
599 | .ids = dm646x_ids, | ||
600 | .ids_num = ARRAY_SIZE(dm646x_ids), | ||
601 | .cpu_clks = dm646x_clks, | ||
602 | .psc_bases = dm646x_psc_bases, | ||
603 | .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases), | ||
604 | .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), | ||
605 | .pinmux_pins = dm646x_pins, | ||
606 | .pinmux_pins_num = ARRAY_SIZE(dm646x_pins), | ||
607 | .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), | ||
608 | .intc_type = DAVINCI_INTC_TYPE_AINTC, | ||
609 | .intc_irq_prios = dm646x_default_priorities, | ||
610 | .intc_irq_num = DAVINCI_N_AINTC_IRQ, | ||
611 | .timer_info = &dm646x_timer_info, | ||
612 | .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), | ||
613 | .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), | ||
614 | .gpio_num = 43, /* Only 33 usable */ | ||
615 | .gpio_irq = IRQ_DM646X_GPIOBNK0, | ||
616 | .serial_dev = &dm646x_serial_device, | ||
617 | .emac_pdata = &dm646x_emac_pdata, | ||
618 | .sram_dma = 0x10010000, | ||
619 | .sram_len = SZ_32K, | ||
620 | }; | ||
621 | |||
622 | void __init dm646x_init(void) | ||
623 | { | ||
624 | davinci_common_init(&davinci_soc_info_dm646x); | ||
625 | } | ||
626 | |||
627 | static int __init dm646x_init_devices(void) | ||
628 | { | ||
629 | if (!cpu_is_davinci_dm646x()) | ||
630 | return 0; | ||
631 | |||
632 | platform_device_register(&dm646x_edma_device); | ||
633 | platform_device_register(&dm646x_emac_device); | ||
634 | return 0; | ||
635 | } | ||
636 | postcore_initcall(dm646x_init_devices); | ||
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 1aba41c6351e..1b6532159c58 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <mach/cputype.h> | 23 | #include <mach/cputype.h> |
24 | #include <mach/irqs.h> | 24 | #include <mach/irqs.h> |
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | #include <mach/common.h> | ||
26 | #include <mach/gpio.h> | 27 | #include <mach/gpio.h> |
27 | 28 | ||
28 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
@@ -37,14 +38,13 @@ struct davinci_gpio { | |||
37 | 38 | ||
38 | static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | 39 | static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; |
39 | 40 | ||
40 | static unsigned __initdata ngpio; | ||
41 | |||
42 | /* create a non-inlined version */ | 41 | /* create a non-inlined version */ |
43 | static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) | 42 | static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) |
44 | { | 43 | { |
45 | return __gpio_to_controller(gpio); | 44 | return __gpio_to_controller(gpio); |
46 | } | 45 | } |
47 | 46 | ||
47 | static int __init davinci_gpio_irq_setup(void); | ||
48 | 48 | ||
49 | /*--------------------------------------------------------------------------*/ | 49 | /*--------------------------------------------------------------------------*/ |
50 | 50 | ||
@@ -115,23 +115,16 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
115 | static int __init davinci_gpio_setup(void) | 115 | static int __init davinci_gpio_setup(void) |
116 | { | 116 | { |
117 | int i, base; | 117 | int i, base; |
118 | unsigned ngpio; | ||
119 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
118 | 120 | ||
119 | /* The gpio banks conceptually expose a segmented bitmap, | 121 | /* |
122 | * The gpio banks conceptually expose a segmented bitmap, | ||
120 | * and "ngpio" is one more than the largest zero-based | 123 | * and "ngpio" is one more than the largest zero-based |
121 | * bit index that's valid. | 124 | * bit index that's valid. |
122 | */ | 125 | */ |
123 | if (cpu_is_davinci_dm355()) { /* or dm335() */ | 126 | ngpio = soc_info->gpio_num; |
124 | ngpio = 104; | 127 | if (ngpio == 0) { |
125 | } else if (cpu_is_davinci_dm644x()) { /* or dm337() */ | ||
126 | ngpio = 71; | ||
127 | } else if (cpu_is_davinci_dm646x()) { | ||
128 | /* NOTE: each bank has several "reserved" bits, | ||
129 | * unusable as GPIOs. Only 33 of the GPIO numbers | ||
130 | * are usable, and we're not rejecting the others. | ||
131 | */ | ||
132 | ngpio = 43; | ||
133 | } else { | ||
134 | /* if cpu_is_davinci_dm643x() ngpio = 111 */ | ||
135 | pr_err("GPIO setup: how many GPIOs?\n"); | 128 | pr_err("GPIO setup: how many GPIOs?\n"); |
136 | return -EINVAL; | 129 | return -EINVAL; |
137 | } | 130 | } |
@@ -157,6 +150,7 @@ static int __init davinci_gpio_setup(void) | |||
157 | gpiochip_add(&chips[i].chip); | 150 | gpiochip_add(&chips[i].chip); |
158 | } | 151 | } |
159 | 152 | ||
153 | davinci_gpio_irq_setup(); | ||
160 | return 0; | 154 | return 0; |
161 | } | 155 | } |
162 | pure_initcall(davinci_gpio_setup); | 156 | pure_initcall(davinci_gpio_setup); |
@@ -187,10 +181,15 @@ static void gpio_irq_enable(unsigned irq) | |||
187 | { | 181 | { |
188 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); | 182 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); |
189 | u32 mask = __gpio_mask(irq_to_gpio(irq)); | 183 | u32 mask = __gpio_mask(irq_to_gpio(irq)); |
184 | unsigned status = irq_desc[irq].status; | ||
185 | |||
186 | status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | ||
187 | if (!status) | ||
188 | status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | ||
190 | 189 | ||
191 | if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING) | 190 | if (status & IRQ_TYPE_EDGE_FALLING) |
192 | __raw_writel(mask, &g->set_falling); | 191 | __raw_writel(mask, &g->set_falling); |
193 | if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING) | 192 | if (status & IRQ_TYPE_EDGE_RISING) |
194 | __raw_writel(mask, &g->set_rising); | 193 | __raw_writel(mask, &g->set_rising); |
195 | } | 194 | } |
196 | 195 | ||
@@ -205,10 +204,13 @@ static int gpio_irq_type(unsigned irq, unsigned trigger) | |||
205 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; | 204 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; |
206 | irq_desc[irq].status |= trigger; | 205 | irq_desc[irq].status |= trigger; |
207 | 206 | ||
208 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) | 207 | /* don't enable the IRQ if it's currently disabled */ |
209 | ? &g->set_falling : &g->clr_falling); | 208 | if (irq_desc[irq].depth == 0) { |
210 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) | 209 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) |
211 | ? &g->set_rising : &g->clr_rising); | 210 | ? &g->set_falling : &g->clr_falling); |
211 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) | ||
212 | ? &g->set_rising : &g->clr_rising); | ||
213 | } | ||
212 | return 0; | 214 | return 0; |
213 | } | 215 | } |
214 | 216 | ||
@@ -230,6 +232,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
230 | mask <<= 16; | 232 | mask <<= 16; |
231 | 233 | ||
232 | /* temporarily mask (level sensitive) parent IRQ */ | 234 | /* temporarily mask (level sensitive) parent IRQ */ |
235 | desc->chip->mask(irq); | ||
233 | desc->chip->ack(irq); | 236 | desc->chip->ack(irq); |
234 | while (1) { | 237 | while (1) { |
235 | u32 status; | 238 | u32 status; |
@@ -268,17 +271,15 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
268 | static int __init davinci_gpio_irq_setup(void) | 271 | static int __init davinci_gpio_irq_setup(void) |
269 | { | 272 | { |
270 | unsigned gpio, irq, bank; | 273 | unsigned gpio, irq, bank; |
271 | unsigned bank_irq; | ||
272 | struct clk *clk; | 274 | struct clk *clk; |
273 | u32 binten = 0; | 275 | u32 binten = 0; |
276 | unsigned ngpio, bank_irq; | ||
277 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
278 | |||
279 | ngpio = soc_info->gpio_num; | ||
274 | 280 | ||
275 | if (cpu_is_davinci_dm355()) { /* or dm335() */ | 281 | bank_irq = soc_info->gpio_irq; |
276 | bank_irq = IRQ_DM355_GPIOBNK0; | 282 | if (bank_irq == 0) { |
277 | } else if (cpu_is_davinci_dm644x()) { | ||
278 | bank_irq = IRQ_GPIOBNK0; | ||
279 | } else if (cpu_is_davinci_dm646x()) { | ||
280 | bank_irq = IRQ_DM646X_GPIOBNK0; | ||
281 | } else { | ||
282 | printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); | 283 | printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); |
283 | return -EINVAL; | 284 | return -EINVAL; |
284 | } | 285 | } |
@@ -318,11 +319,9 @@ static int __init davinci_gpio_irq_setup(void) | |||
318 | /* BINTEN -- per-bank interrupt enable. genirq would also let these | 319 | /* BINTEN -- per-bank interrupt enable. genirq would also let these |
319 | * bits be set/cleared dynamically. | 320 | * bits be set/cleared dynamically. |
320 | */ | 321 | */ |
321 | __raw_writel(binten, (void *__iomem) | 322 | __raw_writel(binten, soc_info->gpio_base + 0x08); |
322 | IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08)); | ||
323 | 323 | ||
324 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); | 324 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); |
325 | 325 | ||
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | arch_initcall(davinci_gpio_irq_setup); | ||
diff --git a/arch/arm/mach-davinci/id.c b/arch/arm/mach-davinci/id.c deleted file mode 100644 index 018b994cd794..000000000000 --- a/arch/arm/mach-davinci/id.c +++ /dev/null | |||
@@ -1,116 +0,0 @@ | |||
1 | /* | ||
2 | * Davinci CPU identification code | ||
3 | * | ||
4 | * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com> | ||
5 | * | ||
6 | * Derived from OMAP1 CPU identification code. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #define JTAG_ID_BASE IO_ADDRESS(0x01c40028) | ||
19 | |||
20 | static unsigned int davinci_revision; | ||
21 | |||
22 | struct davinci_id { | ||
23 | u8 variant; /* JTAG ID bits 31:28 */ | ||
24 | u16 part_no; /* JTAG ID bits 27:12 */ | ||
25 | u32 manufacturer; /* JTAG ID bits 11:1 */ | ||
26 | u32 type; /* Cpu id bits [31:8], cpu class bits [7:0] */ | ||
27 | }; | ||
28 | |||
29 | /* Register values to detect the DaVinci version */ | ||
30 | static struct davinci_id davinci_ids[] __initdata = { | ||
31 | { | ||
32 | /* DM6446 */ | ||
33 | .part_no = 0xb700, | ||
34 | .variant = 0x0, | ||
35 | .manufacturer = 0x017, | ||
36 | .type = 0x64460000, | ||
37 | }, | ||
38 | { | ||
39 | /* DM646X */ | ||
40 | .part_no = 0xb770, | ||
41 | .variant = 0x0, | ||
42 | .manufacturer = 0x017, | ||
43 | .type = 0x64670000, | ||
44 | }, | ||
45 | { | ||
46 | /* DM355 */ | ||
47 | .part_no = 0xb73b, | ||
48 | .variant = 0x0, | ||
49 | .manufacturer = 0x00f, | ||
50 | .type = 0x03550000, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | /* | ||
55 | * Get Device Part No. from JTAG ID register | ||
56 | */ | ||
57 | static u16 __init davinci_get_part_no(void) | ||
58 | { | ||
59 | u32 dev_id, part_no; | ||
60 | |||
61 | dev_id = __raw_readl(JTAG_ID_BASE); | ||
62 | |||
63 | part_no = ((dev_id >> 12) & 0xffff); | ||
64 | |||
65 | return part_no; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Get Device Revision from JTAG ID register | ||
70 | */ | ||
71 | static u8 __init davinci_get_variant(void) | ||
72 | { | ||
73 | u32 variant; | ||
74 | |||
75 | variant = __raw_readl(JTAG_ID_BASE); | ||
76 | |||
77 | variant = (variant >> 28) & 0xf; | ||
78 | |||
79 | return variant; | ||
80 | } | ||
81 | |||
82 | unsigned int davinci_rev(void) | ||
83 | { | ||
84 | return davinci_revision >> 16; | ||
85 | } | ||
86 | EXPORT_SYMBOL(davinci_rev); | ||
87 | |||
88 | void __init davinci_check_revision(void) | ||
89 | { | ||
90 | int i; | ||
91 | u16 part_no; | ||
92 | u8 variant; | ||
93 | |||
94 | part_no = davinci_get_part_no(); | ||
95 | variant = davinci_get_variant(); | ||
96 | |||
97 | /* First check only the major version in a safe way */ | ||
98 | for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) { | ||
99 | if (part_no == (davinci_ids[i].part_no)) { | ||
100 | davinci_revision = davinci_ids[i].type; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /* Check if we can find the dev revision */ | ||
106 | for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) { | ||
107 | if (part_no == davinci_ids[i].part_no && | ||
108 | variant == davinci_ids[i].variant) { | ||
109 | davinci_revision = davinci_ids[i].type; | ||
110 | break; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | printk(KERN_INFO "DaVinci DM%04x variant 0x%x\n", | ||
115 | davinci_rev(), variant); | ||
116 | } | ||
diff --git a/arch/arm/mach-davinci/include/mach/board-dm6446evm.h b/arch/arm/mach-davinci/include/mach/board-dm6446evm.h deleted file mode 100644 index 3216f21c1238..000000000000 --- a/arch/arm/mach-davinci/include/mach/board-dm6446evm.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * DaVinci DM6446 EVM board specific headers | ||
3 | * | ||
4 | * Author: Kevin Hilman, Deep Root Systems, LLC | ||
5 | * | ||
6 | * 2007 (c) Deep Root Systems, LLC. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or ifndef. | ||
10 | */ | ||
11 | |||
12 | #ifndef _MACH_DAVINCI_DM6446EVM_H | ||
13 | #define _MACH_DAVINCI_DM6446EVM_H | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | int dm6446evm_eeprom_read(char *buf, off_t off, size_t count); | ||
18 | int dm6446evm_eeprom_write(char *buf, off_t off, size_t count); | ||
19 | |||
20 | #endif | ||
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 191770976250..a1f03b606d8f 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h | |||
@@ -17,7 +17,8 @@ struct sys_timer; | |||
17 | extern struct sys_timer davinci_timer; | 17 | extern struct sys_timer davinci_timer; |
18 | 18 | ||
19 | extern void davinci_irq_init(void); | 19 | extern void davinci_irq_init(void); |
20 | extern void davinci_map_common_io(void); | 20 | extern void __iomem *davinci_intc_base; |
21 | extern int davinci_intc_type; | ||
21 | 22 | ||
22 | /* parameters describe VBUS sourcing for host mode */ | 23 | /* parameters describe VBUS sourcing for host mode */ |
23 | extern void setup_usb(unsigned mA, unsigned potpgt_msec); | 24 | extern void setup_usb(unsigned mA, unsigned potpgt_msec); |
@@ -25,4 +26,56 @@ extern void setup_usb(unsigned mA, unsigned potpgt_msec); | |||
25 | /* parameters describe VBUS sourcing for host mode */ | 26 | /* parameters describe VBUS sourcing for host mode */ |
26 | extern void setup_usb(unsigned mA, unsigned potpgt_msec); | 27 | extern void setup_usb(unsigned mA, unsigned potpgt_msec); |
27 | 28 | ||
29 | struct davinci_timer_instance { | ||
30 | void __iomem *base; | ||
31 | u32 bottom_irq; | ||
32 | u32 top_irq; | ||
33 | unsigned long cmp_off; | ||
34 | unsigned int cmp_irq; | ||
35 | }; | ||
36 | |||
37 | struct davinci_timer_info { | ||
38 | struct davinci_timer_instance *timers; | ||
39 | unsigned int clockevent_id; | ||
40 | unsigned int clocksource_id; | ||
41 | }; | ||
42 | |||
43 | /* SoC specific init support */ | ||
44 | struct davinci_soc_info { | ||
45 | struct map_desc *io_desc; | ||
46 | unsigned long io_desc_num; | ||
47 | u32 cpu_id; | ||
48 | u32 jtag_id; | ||
49 | void __iomem *jtag_id_base; | ||
50 | struct davinci_id *ids; | ||
51 | unsigned long ids_num; | ||
52 | struct davinci_clk *cpu_clks; | ||
53 | void __iomem **psc_bases; | ||
54 | unsigned long psc_bases_num; | ||
55 | void __iomem *pinmux_base; | ||
56 | const struct mux_config *pinmux_pins; | ||
57 | unsigned long pinmux_pins_num; | ||
58 | void __iomem *intc_base; | ||
59 | int intc_type; | ||
60 | u8 *intc_irq_prios; | ||
61 | unsigned long intc_irq_num; | ||
62 | struct davinci_timer_info *timer_info; | ||
63 | void __iomem *wdt_base; | ||
64 | void __iomem *gpio_base; | ||
65 | unsigned gpio_num; | ||
66 | unsigned gpio_irq; | ||
67 | struct platform_device *serial_dev; | ||
68 | struct emac_platform_data *emac_pdata; | ||
69 | dma_addr_t sram_dma; | ||
70 | unsigned sram_len; | ||
71 | }; | ||
72 | |||
73 | extern struct davinci_soc_info davinci_soc_info; | ||
74 | |||
75 | extern void davinci_common_init(struct davinci_soc_info *soc_info); | ||
76 | |||
77 | /* standard place to map on-chip SRAMs; they *may* support DMA */ | ||
78 | #define SRAM_VIRT 0xfffe0000 | ||
79 | #define SRAM_SIZE SZ_128K | ||
80 | |||
28 | #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */ | 81 | #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */ |
diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/include/mach/cp_intc.h new file mode 100644 index 000000000000..c4d27eec8064 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/cp_intc.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * TI Common Platform Interrupt Controller (cp_intc) definitions | ||
3 | * | ||
4 | * Author: Steve Chen <schen@mvista.com> | ||
5 | * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public License | ||
8 | * version 2. This program is licensed "as is" without any warranty of any | ||
9 | * kind, whether express or implied. | ||
10 | */ | ||
11 | #ifndef __ASM_HARDWARE_CP_INTC_H | ||
12 | #define __ASM_HARDWARE_CP_INTC_H | ||
13 | |||
14 | #define CP_INTC_REV 0x00 | ||
15 | #define CP_INTC_CTRL 0x04 | ||
16 | #define CP_INTC_HOST_CTRL 0x0C | ||
17 | #define CP_INTC_GLOBAL_ENABLE 0x10 | ||
18 | #define CP_INTC_GLOBAL_NESTING_LEVEL 0x1C | ||
19 | #define CP_INTC_SYS_STAT_IDX_SET 0x20 | ||
20 | #define CP_INTC_SYS_STAT_IDX_CLR 0x24 | ||
21 | #define CP_INTC_SYS_ENABLE_IDX_SET 0x28 | ||
22 | #define CP_INTC_SYS_ENABLE_IDX_CLR 0x2C | ||
23 | #define CP_INTC_GLOBAL_WAKEUP_ENABLE 0x30 | ||
24 | #define CP_INTC_HOST_ENABLE_IDX_SET 0x34 | ||
25 | #define CP_INTC_HOST_ENABLE_IDX_CLR 0x38 | ||
26 | #define CP_INTC_PACING_PRESCALE 0x40 | ||
27 | #define CP_INTC_VECTOR_BASE 0x50 | ||
28 | #define CP_INTC_VECTOR_SIZE 0x54 | ||
29 | #define CP_INTC_VECTOR_NULL 0x58 | ||
30 | #define CP_INTC_PRIO_IDX 0x80 | ||
31 | #define CP_INTC_PRIO_VECTOR 0x84 | ||
32 | #define CP_INTC_SECURE_ENABLE 0x90 | ||
33 | #define CP_INTC_SECURE_PRIO_IDX 0x94 | ||
34 | #define CP_INTC_PACING_PARAM(n) (0x0100 + (n << 4)) | ||
35 | #define CP_INTC_PACING_DEC(n) (0x0104 + (n << 4)) | ||
36 | #define CP_INTC_PACING_MAP(n) (0x0108 + (n << 4)) | ||
37 | #define CP_INTC_SYS_RAW_STAT(n) (0x0200 + (n << 2)) | ||
38 | #define CP_INTC_SYS_STAT_CLR(n) (0x0280 + (n << 2)) | ||
39 | #define CP_INTC_SYS_ENABLE_SET(n) (0x0300 + (n << 2)) | ||
40 | #define CP_INTC_SYS_ENABLE_CLR(n) (0x0380 + (n << 2)) | ||
41 | #define CP_INTC_CHAN_MAP(n) (0x0400 + (n << 2)) | ||
42 | #define CP_INTC_HOST_MAP(n) (0x0800 + (n << 2)) | ||
43 | #define CP_INTC_HOST_PRIO_IDX(n) (0x0900 + (n << 2)) | ||
44 | #define CP_INTC_SYS_POLARITY(n) (0x0D00 + (n << 2)) | ||
45 | #define CP_INTC_SYS_TYPE(n) (0x0D80 + (n << 2)) | ||
46 | #define CP_INTC_WAKEUP_ENABLE(n) (0x0E00 + (n << 2)) | ||
47 | #define CP_INTC_DEBUG_SELECT(n) (0x0F00 + (n << 2)) | ||
48 | #define CP_INTC_SYS_SECURE_ENABLE(n) (0x1000 + (n << 2)) | ||
49 | #define CP_INTC_HOST_NESTING_LEVEL(n) (0x1100 + (n << 2)) | ||
50 | #define CP_INTC_HOST_ENABLE(n) (0x1500 + (n << 2)) | ||
51 | #define CP_INTC_HOST_PRIO_VECTOR(n) (0x1600 + (n << 2)) | ||
52 | #define CP_INTC_VECTOR_ADDR(n) (0x2000 + (n << 2)) | ||
53 | |||
54 | void __init cp_intc_init(void __iomem *base, unsigned short num_irq, | ||
55 | u8 *irq_prio); | ||
56 | |||
57 | #endif /* __ASM_HARDWARE_CP_INTC_H */ | ||
diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h index 27cfb1b3a662..d12a5ed2959a 100644 --- a/arch/arm/mach-davinci/include/mach/cputype.h +++ b/arch/arm/mach-davinci/include/mach/cputype.h | |||
@@ -16,17 +16,30 @@ | |||
16 | #ifndef _ASM_ARCH_CPU_H | 16 | #ifndef _ASM_ARCH_CPU_H |
17 | #define _ASM_ARCH_CPU_H | 17 | #define _ASM_ARCH_CPU_H |
18 | 18 | ||
19 | extern unsigned int davinci_rev(void); | 19 | #include <mach/common.h> |
20 | 20 | ||
21 | #define IS_DAVINCI_CPU(type, id) \ | 21 | struct davinci_id { |
22 | static inline int is_davinci_dm ##type(void) \ | 22 | u8 variant; /* JTAG ID bits 31:28 */ |
23 | { \ | 23 | u16 part_no; /* JTAG ID bits 27:12 */ |
24 | return (davinci_rev() == (id)) ? 1 : 0; \ | 24 | u16 manufacturer; /* JTAG ID bits 11:1 */ |
25 | u32 cpu_id; | ||
26 | char *name; | ||
27 | }; | ||
28 | |||
29 | /* Can use lower 16 bits of cpu id for a variant when required */ | ||
30 | #define DAVINCI_CPU_ID_DM6446 0x64460000 | ||
31 | #define DAVINCI_CPU_ID_DM6467 0x64670000 | ||
32 | #define DAVINCI_CPU_ID_DM355 0x03550000 | ||
33 | |||
34 | #define IS_DAVINCI_CPU(type, id) \ | ||
35 | static inline int is_davinci_ ##type(void) \ | ||
36 | { \ | ||
37 | return (davinci_soc_info.cpu_id == (id)); \ | ||
25 | } | 38 | } |
26 | 39 | ||
27 | IS_DAVINCI_CPU(644x, 0x6446) | 40 | IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446) |
28 | IS_DAVINCI_CPU(646x, 0x6467) | 41 | IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467) |
29 | IS_DAVINCI_CPU(355, 0x355) | 42 | IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355) |
30 | 43 | ||
31 | #ifdef CONFIG_ARCH_DAVINCI_DM644x | 44 | #ifdef CONFIG_ARCH_DAVINCI_DM644x |
32 | #define cpu_is_davinci_dm644x() is_davinci_dm644x() | 45 | #define cpu_is_davinci_dm644x() is_davinci_dm644x() |
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S index e6c0f0d5d062..de3fc2182b47 100644 --- a/arch/arm/mach-davinci/include/mach/debug-macro.S +++ b/arch/arm/mach-davinci/include/mach/debug-macro.S | |||
@@ -9,6 +9,16 @@ | |||
9 | * or implied. | 9 | * or implied. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* Modifications | ||
13 | * Jan 2009 Chaithrika U S Added senduart, busyuart, waituart | ||
14 | * macros, based on debug-8250.S file | ||
15 | * but using 32-bit accesses required for | ||
16 | * some davinci devices. | ||
17 | */ | ||
18 | |||
19 | #include <linux/serial_reg.h> | ||
20 | #define UART_SHIFT 2 | ||
21 | |||
12 | .macro addruart, rx | 22 | .macro addruart, rx |
13 | mrc p15, 0, \rx, c1, c0 | 23 | mrc p15, 0, \rx, c1, c0 |
14 | tst \rx, #1 @ MMU enabled? | 24 | tst \rx, #1 @ MMU enabled? |
@@ -17,5 +27,22 @@ | |||
17 | orr \rx, \rx, #0x00c20000 @ UART 0 | 27 | orr \rx, \rx, #0x00c20000 @ UART 0 |
18 | .endm | 28 | .endm |
19 | 29 | ||
20 | #define UART_SHIFT 2 | 30 | .macro senduart,rd,rx |
21 | #include <asm/hardware/debug-8250.S> | 31 | str \rd, [\rx, #UART_TX << UART_SHIFT] |
32 | .endm | ||
33 | |||
34 | .macro busyuart,rd,rx | ||
35 | 1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] | ||
36 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
37 | teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
38 | bne 1002b | ||
39 | .endm | ||
40 | |||
41 | .macro waituart,rd,rx | ||
42 | #ifdef FLOW_CONTROL | ||
43 | 1001: ldr \rd, [\rx, #UART_MSR << UART_SHIFT] | ||
44 | tst \rd, #UART_MSR_CTS | ||
45 | beq 1001b | ||
46 | #endif | ||
47 | .endm | ||
48 | |||
diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h new file mode 100644 index 000000000000..54903b72438e --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/dm355.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Chip specific defines for DM355 SoC | ||
3 | * | ||
4 | * Author: Kevin Hilman, Deep Root Systems, LLC | ||
5 | * | ||
6 | * 2007 (c) Deep Root Systems, LLC. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #ifndef __ASM_ARCH_DM355_H | ||
12 | #define __ASM_ARCH_DM355_H | ||
13 | |||
14 | #include <mach/hardware.h> | ||
15 | |||
16 | struct spi_board_info; | ||
17 | |||
18 | void __init dm355_init(void); | ||
19 | void dm355_init_spi0(unsigned chipselect_mask, | ||
20 | struct spi_board_info *info, unsigned len); | ||
21 | |||
22 | #endif /* __ASM_ARCH_DM355_H */ | ||
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h index 3dcb9f4e58b4..15d42b92a8c9 100644 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ b/arch/arm/mach-davinci/include/mach/dm644x.h | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
27 | #include <mach/emac.h> | ||
27 | 28 | ||
28 | #define DM644X_EMAC_BASE (0x01C80000) | 29 | #define DM644X_EMAC_BASE (0x01C80000) |
29 | #define DM644X_EMAC_CNTRL_OFFSET (0x0000) | 30 | #define DM644X_EMAC_CNTRL_OFFSET (0x0000) |
diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h new file mode 100644 index 000000000000..1fc764c8646e --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/dm646x.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Chip specific defines for DM646x SoC | ||
3 | * | ||
4 | * Author: Kevin Hilman, Deep Root Systems, LLC | ||
5 | * | ||
6 | * 2007 (c) Deep Root Systems, LLC. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #ifndef __ASM_ARCH_DM646X_H | ||
12 | #define __ASM_ARCH_DM646X_H | ||
13 | |||
14 | #include <mach/hardware.h> | ||
15 | #include <mach/emac.h> | ||
16 | |||
17 | #define DM646X_EMAC_BASE (0x01C80000) | ||
18 | #define DM646X_EMAC_CNTRL_OFFSET (0x0000) | ||
19 | #define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000) | ||
20 | #define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000) | ||
21 | #define DM646X_EMAC_MDIO_OFFSET (0x4000) | ||
22 | #define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000) | ||
23 | |||
24 | void __init dm646x_init(void); | ||
25 | |||
26 | #endif /* __ASM_ARCH_DM646X_H */ | ||
diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h index f6fc5396dafc..24a379239d7f 100644 --- a/arch/arm/mach-davinci/include/mach/edma.h +++ b/arch/arm/mach-davinci/include/mach/edma.h | |||
@@ -208,10 +208,6 @@ void edma_clear_event(unsigned channel); | |||
208 | void edma_pause(unsigned channel); | 208 | void edma_pause(unsigned channel); |
209 | void edma_resume(unsigned channel); | 209 | void edma_resume(unsigned channel); |
210 | 210 | ||
211 | /* UNRELATED TO DMA */ | ||
212 | int davinci_alloc_iram(unsigned size); | ||
213 | void davinci_free_iram(unsigned addr, unsigned size); | ||
214 | |||
215 | /* platform_data for EDMA driver */ | 211 | /* platform_data for EDMA driver */ |
216 | struct edma_soc_info { | 212 | struct edma_soc_info { |
217 | 213 | ||
diff --git a/arch/arm/mach-davinci/include/mach/emac.h b/arch/arm/mach-davinci/include/mach/emac.h new file mode 100644 index 000000000000..beff4fb7c845 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/emac.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * TI DaVinci EMAC platform support | ||
3 | * | ||
4 | * Author: Kevin Hilman, Deep Root Systems, LLC | ||
5 | * | ||
6 | * 2007 (c) Deep Root Systems, LLC. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #ifndef _MACH_DAVINCI_EMAC_H | ||
12 | #define _MACH_DAVINCI_EMAC_H | ||
13 | |||
14 | #include <linux/if_ether.h> | ||
15 | #include <linux/memory.h> | ||
16 | |||
17 | struct emac_platform_data { | ||
18 | char mac_addr[ETH_ALEN]; | ||
19 | u32 ctrl_reg_offset; | ||
20 | u32 ctrl_mod_reg_offset; | ||
21 | u32 ctrl_ram_offset; | ||
22 | u32 mdio_reg_offset; | ||
23 | u32 ctrl_ram_size; | ||
24 | u32 phy_mask; | ||
25 | u32 mdio_max_freq; | ||
26 | u8 rmii_en; | ||
27 | u8 version; | ||
28 | }; | ||
29 | |||
30 | enum { | ||
31 | EMAC_VERSION_1, /* DM644x */ | ||
32 | EMAC_VERSION_2, /* DM646x */ | ||
33 | }; | ||
34 | |||
35 | void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context); | ||
36 | #endif | ||
diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S index 039b84f933b3..fbdebc7cb409 100644 --- a/arch/arm/mach-davinci/include/mach/entry-macro.S +++ b/arch/arm/mach-davinci/include/mach/entry-macro.S | |||
@@ -15,17 +15,36 @@ | |||
15 | .endm | 15 | .endm |
16 | 16 | ||
17 | .macro get_irqnr_preamble, base, tmp | 17 | .macro get_irqnr_preamble, base, tmp |
18 | ldr \base, =IO_ADDRESS(DAVINCI_ARM_INTC_BASE) | 18 | ldr \base, =davinci_intc_base |
19 | ldr \base, [\base] | ||
19 | .endm | 20 | .endm |
20 | 21 | ||
21 | .macro arch_ret_to_user, tmp1, tmp2 | 22 | .macro arch_ret_to_user, tmp1, tmp2 |
22 | .endm | 23 | .endm |
23 | 24 | ||
24 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | 25 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp |
26 | #if defined(CONFIG_AINTC) && defined(CONFIG_CP_INTC) | ||
27 | ldr \tmp, =davinci_intc_type | ||
28 | ldr \tmp, [\tmp] | ||
29 | cmp \tmp, #DAVINCI_INTC_TYPE_CP_INTC | ||
30 | beq 1001f | ||
31 | #endif | ||
32 | #if defined(CONFIG_AINTC) | ||
25 | ldr \tmp, [\base, #0x14] | 33 | ldr \tmp, [\base, #0x14] |
26 | mov \tmp, \tmp, lsr #2 | 34 | movs \tmp, \tmp, lsr #2 |
27 | sub \irqnr, \tmp, #1 | 35 | sub \irqnr, \tmp, #1 |
28 | cmp \tmp, #0 | 36 | b 1002f |
37 | #endif | ||
38 | #if defined(CONFIG_CP_INTC) | ||
39 | 1001: ldr \irqnr, [\base, #0x80] /* get irq number */ | ||
40 | and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */ | ||
41 | mov \tmp, \irqnr, lsr #3 | ||
42 | and \tmp, \tmp, #0xfc | ||
43 | add \tmp, \tmp, #0x280 /* get the register offset */ | ||
44 | ldr \irqstat, [\base, \tmp] /* get the intc status */ | ||
45 | cmp \irqstat, #0x0 | ||
46 | #endif | ||
47 | 1002: | ||
29 | .endm | 48 | .endm |
30 | 49 | ||
31 | .macro irq_prio_table | 50 | .macro irq_prio_table |
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index efe3281364e6..ae0745568316 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm-generic/gpio.h> | 17 | #include <asm-generic/gpio.h> |
18 | 18 | ||
19 | #include <mach/irqs.h> | 19 | #include <mach/irqs.h> |
20 | #include <mach/common.h> | ||
20 | 21 | ||
21 | #define DAVINCI_GPIO_BASE 0x01C67000 | 22 | #define DAVINCI_GPIO_BASE 0x01C67000 |
22 | 23 | ||
@@ -67,15 +68,16 @@ static inline struct gpio_controller *__iomem | |||
67 | __gpio_to_controller(unsigned gpio) | 68 | __gpio_to_controller(unsigned gpio) |
68 | { | 69 | { |
69 | void *__iomem ptr; | 70 | void *__iomem ptr; |
71 | void __iomem *base = davinci_soc_info.gpio_base; | ||
70 | 72 | ||
71 | if (gpio < 32 * 1) | 73 | if (gpio < 32 * 1) |
72 | ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); | 74 | ptr = base + 0x10; |
73 | else if (gpio < 32 * 2) | 75 | else if (gpio < 32 * 2) |
74 | ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38); | 76 | ptr = base + 0x38; |
75 | else if (gpio < 32 * 3) | 77 | else if (gpio < 32 * 3) |
76 | ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60); | 78 | ptr = base + 0x60; |
77 | else if (gpio < 32 * 4) | 79 | else if (gpio < 32 * 4) |
78 | ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88); | 80 | ptr = base + 0x88; |
79 | else | 81 | else |
80 | ptr = NULL; | 82 | ptr = NULL; |
81 | return ptr; | 83 | return ptr; |
@@ -142,13 +144,13 @@ static inline int gpio_to_irq(unsigned gpio) | |||
142 | { | 144 | { |
143 | if (gpio >= DAVINCI_N_GPIO) | 145 | if (gpio >= DAVINCI_N_GPIO) |
144 | return -EINVAL; | 146 | return -EINVAL; |
145 | return DAVINCI_N_AINTC_IRQ + gpio; | 147 | return davinci_soc_info.intc_irq_num + gpio; |
146 | } | 148 | } |
147 | 149 | ||
148 | static inline int irq_to_gpio(unsigned irq) | 150 | static inline int irq_to_gpio(unsigned irq) |
149 | { | 151 | { |
150 | /* caller guarantees gpio_to_irq() succeeded */ | 152 | /* caller guarantees gpio_to_irq() succeeded */ |
151 | return irq - DAVINCI_N_AINTC_IRQ; | 153 | return irq - davinci_soc_info.intc_irq_num; |
152 | } | 154 | } |
153 | 155 | ||
154 | #endif /* __DAVINCI_GPIO_H */ | 156 | #endif /* __DAVINCI_GPIO_H */ |
diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h index 18066074c995..bc5d6aaa69a3 100644 --- a/arch/arm/mach-davinci/include/mach/irqs.h +++ b/arch/arm/mach-davinci/include/mach/irqs.h | |||
@@ -30,6 +30,9 @@ | |||
30 | /* Base address */ | 30 | /* Base address */ |
31 | #define DAVINCI_ARM_INTC_BASE 0x01C48000 | 31 | #define DAVINCI_ARM_INTC_BASE 0x01C48000 |
32 | 32 | ||
33 | #define DAVINCI_INTC_TYPE_AINTC 0 | ||
34 | #define DAVINCI_INTC_TYPE_CP_INTC 1 | ||
35 | |||
33 | /* Interrupt lines */ | 36 | /* Interrupt lines */ |
34 | #define IRQ_VDINT0 0 | 37 | #define IRQ_VDINT0 0 |
35 | #define IRQ_VDINT1 1 | 38 | #define IRQ_VDINT1 1 |
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h index 86c25c7f3ce3..c712c7cdf38f 100644 --- a/arch/arm/mach-davinci/include/mach/memory.h +++ b/arch/arm/mach-davinci/include/mach/memory.h | |||
@@ -21,7 +21,6 @@ | |||
21 | * Definitions | 21 | * Definitions |
22 | **************************************************************************/ | 22 | **************************************************************************/ |
23 | #define DAVINCI_DDR_BASE 0x80000000 | 23 | #define DAVINCI_DDR_BASE 0x80000000 |
24 | #define DAVINCI_IRAM_BASE 0x00008000 /* ARM Internal RAM */ | ||
25 | 24 | ||
26 | #define PHYS_OFFSET DAVINCI_DDR_BASE | 25 | #define PHYS_OFFSET DAVINCI_DDR_BASE |
27 | 26 | ||
diff --git a/arch/arm/mach-davinci/include/mach/mmc.h b/arch/arm/mach-davinci/include/mach/mmc.h new file mode 100644 index 000000000000..5a85e24f3673 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/mmc.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Board-specific MMC configuration | ||
3 | */ | ||
4 | |||
5 | #ifndef _DAVINCI_MMC_H | ||
6 | #define _DAVINCI_MMC_H | ||
7 | |||
8 | #include <linux/types.h> | ||
9 | #include <linux/mmc/host.h> | ||
10 | |||
11 | struct davinci_mmc_config { | ||
12 | /* get_cd()/get_wp() may sleep */ | ||
13 | int (*get_cd)(int module); | ||
14 | int (*get_ro)(int module); | ||
15 | /* wires == 0 is equivalent to wires == 4 (4-bit parallel) */ | ||
16 | u8 wires; | ||
17 | |||
18 | u32 max_freq; | ||
19 | |||
20 | /* any additional host capabilities: OR'd in to mmc->f_caps */ | ||
21 | u32 caps; | ||
22 | |||
23 | /* Version of the MMC/SD controller */ | ||
24 | u8 version; | ||
25 | }; | ||
26 | void davinci_setup_mmc(int module, struct davinci_mmc_config *config); | ||
27 | |||
28 | enum { | ||
29 | MMC_CTLR_VERSION_1 = 0, /* DM644x and DM355 */ | ||
30 | MMC_CTLR_VERSION_2, /* DA830 */ | ||
31 | }; | ||
32 | |||
33 | #endif | ||
diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index bae22cb3e27b..27378458542f 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h | |||
@@ -19,16 +19,6 @@ | |||
19 | #ifndef __INC_MACH_MUX_H | 19 | #ifndef __INC_MACH_MUX_H |
20 | #define __INC_MACH_MUX_H | 20 | #define __INC_MACH_MUX_H |
21 | 21 | ||
22 | /* System module registers */ | ||
23 | #define PINMUX0 0x00 | ||
24 | #define PINMUX1 0x04 | ||
25 | /* dm355 only */ | ||
26 | #define PINMUX2 0x08 | ||
27 | #define PINMUX3 0x0c | ||
28 | #define PINMUX4 0x10 | ||
29 | #define INTMUX 0x18 | ||
30 | #define EVTMUX 0x1c | ||
31 | |||
32 | struct mux_config { | 22 | struct mux_config { |
33 | const char *name; | 23 | const char *name; |
34 | const char *mux_reg_name; | 24 | const char *mux_reg_name; |
@@ -168,15 +158,9 @@ enum davinci_dm355_index { | |||
168 | 158 | ||
169 | #ifdef CONFIG_DAVINCI_MUX | 159 | #ifdef CONFIG_DAVINCI_MUX |
170 | /* setup pin muxing */ | 160 | /* setup pin muxing */ |
171 | extern void davinci_mux_init(void); | ||
172 | extern int davinci_mux_register(const struct mux_config *pins, | ||
173 | unsigned long size); | ||
174 | extern int davinci_cfg_reg(unsigned long reg_cfg); | 161 | extern int davinci_cfg_reg(unsigned long reg_cfg); |
175 | #else | 162 | #else |
176 | /* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */ | 163 | /* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */ |
177 | static inline void davinci_mux_init(void) {} | ||
178 | static inline int davinci_mux_register(const struct mux_config *pins, | ||
179 | unsigned long size) { return 0; } | ||
180 | static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; } | 164 | static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; } |
181 | #endif | 165 | #endif |
182 | 166 | ||
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 55a90d419fac..ab8a2586d1cc 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #ifndef __ASM_ARCH_PSC_H | 27 | #ifndef __ASM_ARCH_PSC_H |
28 | #define __ASM_ARCH_PSC_H | 28 | #define __ASM_ARCH_PSC_H |
29 | 29 | ||
30 | #define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000 | ||
31 | |||
30 | /* Power and Sleep Controller (PSC) Domains */ | 32 | /* Power and Sleep Controller (PSC) Domains */ |
31 | #define DAVINCI_GPSC_ARMDOMAIN 0 | 33 | #define DAVINCI_GPSC_ARMDOMAIN 0 |
32 | #define DAVINCI_GPSC_DSPDOMAIN 1 | 34 | #define DAVINCI_GPSC_DSPDOMAIN 1 |
@@ -116,8 +118,8 @@ | |||
116 | #define DM646X_LPSC_TIMER1 35 | 118 | #define DM646X_LPSC_TIMER1 35 |
117 | #define DM646X_LPSC_ARM_INTC 45 | 119 | #define DM646X_LPSC_ARM_INTC 45 |
118 | 120 | ||
119 | extern int davinci_psc_is_clk_active(unsigned int id); | 121 | extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); |
120 | extern void davinci_psc_config(unsigned int domain, unsigned int id, | 122 | extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, |
121 | char enable); | 123 | unsigned int id, char enable); |
122 | 124 | ||
123 | #endif /* __ASM_ARCH_PSC_H */ | 125 | #endif /* __ASM_ARCH_PSC_H */ |
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index 632847d74a1c..794fa5cf93c1 100644 --- a/arch/arm/mach-davinci/include/mach/serial.h +++ b/arch/arm/mach-davinci/include/mach/serial.h | |||
@@ -18,8 +18,6 @@ | |||
18 | #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) | 18 | #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) |
19 | #define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) | 19 | #define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) |
20 | 20 | ||
21 | #define DM355_UART2_BASE (IO_PHYS + 0x206000) | ||
22 | |||
23 | /* DaVinci UART register offsets */ | 21 | /* DaVinci UART register offsets */ |
24 | #define UART_DAVINCI_PWREMU 0x0c | 22 | #define UART_DAVINCI_PWREMU 0x0c |
25 | #define UART_DM646X_SCR 0x10 | 23 | #define UART_DM646X_SCR 0x10 |
@@ -30,6 +28,6 @@ struct davinci_uart_config { | |||
30 | unsigned int enabled_uarts; | 28 | unsigned int enabled_uarts; |
31 | }; | 29 | }; |
32 | 30 | ||
33 | extern void davinci_serial_init(struct davinci_uart_config *); | 31 | extern int davinci_serial_init(struct davinci_uart_config *); |
34 | 32 | ||
35 | #endif /* __ASM_ARCH_SERIAL_H */ | 33 | #endif /* __ASM_ARCH_SERIAL_H */ |
diff --git a/arch/arm/mach-davinci/include/mach/sram.h b/arch/arm/mach-davinci/include/mach/sram.h new file mode 100644 index 000000000000..111f7cc71e07 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/sram.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * mach/sram.h - DaVinci simple SRAM allocator | ||
3 | * | ||
4 | * Copyright (C) 2009 David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef __MACH_SRAM_H | ||
11 | #define __MACH_SRAM_H | ||
12 | |||
13 | /* ARBITRARY: SRAM allocations are multiples of this 2^N size */ | ||
14 | #define SRAM_GRANULARITY 512 | ||
15 | |||
16 | /* | ||
17 | * SRAM allocations return a CPU virtual address, or NULL on error. | ||
18 | * If a DMA address is requested and the SRAM supports DMA, its | ||
19 | * mapped address is also returned. | ||
20 | * | ||
21 | * Errors include SRAM memory not being available, and requesting | ||
22 | * DMA mapped SRAM on systems which don't allow that. | ||
23 | */ | ||
24 | extern void *sram_alloc(size_t len, dma_addr_t *dma); | ||
25 | extern void sram_free(void *addr, size_t len); | ||
26 | |||
27 | #endif /* __MACH_SRAM_H */ | ||
diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h new file mode 100644 index 000000000000..1c971d8d8ba8 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/time.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Local header file for DaVinci time code. | ||
3 | * | ||
4 | * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> | ||
5 | * | ||
6 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H | ||
12 | #define __ARCH_ARM_MACH_DAVINCI_TIME_H | ||
13 | |||
14 | #define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400) | ||
15 | #define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) | ||
16 | #define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00) | ||
17 | |||
18 | enum { | ||
19 | T0_BOT, | ||
20 | T0_TOP, | ||
21 | T1_BOT, | ||
22 | T1_TOP, | ||
23 | NUM_TIMERS | ||
24 | }; | ||
25 | |||
26 | #define IS_TIMER1(id) (id & 0x2) | ||
27 | #define IS_TIMER0(id) (!IS_TIMER1(id)) | ||
28 | #define IS_TIMER_TOP(id) ((id & 0x1)) | ||
29 | #define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id)) | ||
30 | |||
31 | #define ID_TO_TIMER(id) (IS_TIMER1(id) != 0) | ||
32 | |||
33 | extern struct davinci_timer_instance davinci_timer_instance[]; | ||
34 | |||
35 | #endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ | ||
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index 8c165def37b6..1e27475f9a23 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h | |||
@@ -13,11 +13,24 @@ | |||
13 | #include <linux/serial_reg.h> | 13 | #include <linux/serial_reg.h> |
14 | #include <mach/serial.h> | 14 | #include <mach/serial.h> |
15 | 15 | ||
16 | #include <asm/mach-types.h> | ||
17 | |||
18 | extern unsigned int __machine_arch_type; | ||
19 | |||
20 | static u32 *uart; | ||
21 | |||
22 | static u32 *get_uart_base(void) | ||
23 | { | ||
24 | /* Add logic here for new platforms, using __macine_arch_type */ | ||
25 | return (u32 *)DAVINCI_UART0_BASE; | ||
26 | } | ||
27 | |||
16 | /* PORT_16C550A, in polled non-fifo mode */ | 28 | /* PORT_16C550A, in polled non-fifo mode */ |
17 | 29 | ||
18 | static void putc(char c) | 30 | static void putc(char c) |
19 | { | 31 | { |
20 | volatile u32 *uart = (volatile void *) DAVINCI_UART0_BASE; | 32 | if (!uart) |
33 | uart = get_uart_base(); | ||
21 | 34 | ||
22 | while (!(uart[UART_LSR] & UART_LSR_THRE)) | 35 | while (!(uart[UART_LSR] & UART_LSR_THRE)) |
23 | barrier(); | 36 | barrier(); |
@@ -26,7 +39,9 @@ static void putc(char c) | |||
26 | 39 | ||
27 | static inline void flush(void) | 40 | static inline void flush(void) |
28 | { | 41 | { |
29 | volatile u32 *uart = (volatile void *) DAVINCI_UART0_BASE; | 42 | if (!uart) |
43 | uart = get_uart_base(); | ||
44 | |||
30 | while (!(uart[UART_LSR] & UART_LSR_THRE)) | 45 | while (!(uart[UART_LSR] & UART_LSR_THRE)) |
31 | barrier(); | 46 | barrier(); |
32 | } | 47 | } |
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c index a548abb513e2..49912b48b1b0 100644 --- a/arch/arm/mach-davinci/io.c +++ b/arch/arm/mach-davinci/io.c | |||
@@ -9,47 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | 12 | #include <linux/io.h> |
15 | 13 | ||
16 | #include <asm/tlb.h> | 14 | #include <asm/tlb.h> |
17 | #include <asm/memory.h> | ||
18 | |||
19 | #include <asm/mach/map.h> | ||
20 | #include <mach/clock.h> | ||
21 | |||
22 | extern void davinci_check_revision(void); | ||
23 | |||
24 | /* | ||
25 | * The machine specific code may provide the extra mapping besides the | ||
26 | * default mapping provided here. | ||
27 | */ | ||
28 | static struct map_desc davinci_io_desc[] __initdata = { | ||
29 | { | ||
30 | .virtual = IO_VIRT, | ||
31 | .pfn = __phys_to_pfn(IO_PHYS), | ||
32 | .length = IO_SIZE, | ||
33 | .type = MT_DEVICE | ||
34 | }, | ||
35 | }; | ||
36 | |||
37 | void __init davinci_map_common_io(void) | ||
38 | { | ||
39 | iotable_init(davinci_io_desc, ARRAY_SIZE(davinci_io_desc)); | ||
40 | |||
41 | /* Normally devicemaps_init() would flush caches and tlb after | ||
42 | * mdesc->map_io(), but we must also do it here because of the CPU | ||
43 | * revision check below. | ||
44 | */ | ||
45 | local_flush_tlb_all(); | ||
46 | flush_cache_all(); | ||
47 | |||
48 | /* We want to check CPU revision early for cpu_is_xxxx() macros. | ||
49 | * IO space mapping must be initialized before we can do that. | ||
50 | */ | ||
51 | davinci_check_revision(); | ||
52 | } | ||
53 | 15 | ||
54 | #define BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) | 16 | #define BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) |
55 | #define XLATE(p, pst, vst) ((void __iomem *)((p) - (pst) + (vst))) | 17 | #define XLATE(p, pst, vst) ((void __iomem *)((p) - (pst) + (vst))) |
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c index 5a324c90e291..af92ffee8471 100644 --- a/arch/arm/mach-davinci/irq.c +++ b/arch/arm/mach-davinci/irq.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <mach/cputype.h> | 28 | #include <mach/cputype.h> |
29 | #include <mach/common.h> | ||
29 | #include <asm/mach/irq.h> | 30 | #include <asm/mach/irq.h> |
30 | 31 | ||
31 | #define IRQ_BIT(irq) ((irq) & 0x1f) | 32 | #define IRQ_BIT(irq) ((irq) & 0x1f) |
@@ -41,18 +42,14 @@ | |||
41 | #define IRQ_INTPRI0_REG_OFFSET 0x0030 | 42 | #define IRQ_INTPRI0_REG_OFFSET 0x0030 |
42 | #define IRQ_INTPRI7_REG_OFFSET 0x004C | 43 | #define IRQ_INTPRI7_REG_OFFSET 0x004C |
43 | 44 | ||
44 | const u8 *davinci_def_priorities; | ||
45 | |||
46 | #define INTC_BASE IO_ADDRESS(DAVINCI_ARM_INTC_BASE) | ||
47 | |||
48 | static inline unsigned int davinci_irq_readl(int offset) | 45 | static inline unsigned int davinci_irq_readl(int offset) |
49 | { | 46 | { |
50 | return __raw_readl(INTC_BASE + offset); | 47 | return __raw_readl(davinci_intc_base + offset); |
51 | } | 48 | } |
52 | 49 | ||
53 | static inline void davinci_irq_writel(unsigned long value, int offset) | 50 | static inline void davinci_irq_writel(unsigned long value, int offset) |
54 | { | 51 | { |
55 | __raw_writel(value, INTC_BASE + offset); | 52 | __raw_writel(value, davinci_intc_base + offset); |
56 | } | 53 | } |
57 | 54 | ||
58 | /* Disable interrupt */ | 55 | /* Disable interrupt */ |
@@ -113,217 +110,11 @@ static struct irq_chip davinci_irq_chip_0 = { | |||
113 | .unmask = davinci_unmask_irq, | 110 | .unmask = davinci_unmask_irq, |
114 | }; | 111 | }; |
115 | 112 | ||
116 | /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ | ||
117 | static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = { | ||
118 | [IRQ_VDINT0] = 2, | ||
119 | [IRQ_VDINT1] = 6, | ||
120 | [IRQ_VDINT2] = 6, | ||
121 | [IRQ_HISTINT] = 6, | ||
122 | [IRQ_H3AINT] = 6, | ||
123 | [IRQ_PRVUINT] = 6, | ||
124 | [IRQ_RSZINT] = 6, | ||
125 | [7] = 7, | ||
126 | [IRQ_VENCINT] = 6, | ||
127 | [IRQ_ASQINT] = 6, | ||
128 | [IRQ_IMXINT] = 6, | ||
129 | [IRQ_VLCDINT] = 6, | ||
130 | [IRQ_USBINT] = 4, | ||
131 | [IRQ_EMACINT] = 4, | ||
132 | [14] = 7, | ||
133 | [15] = 7, | ||
134 | [IRQ_CCINT0] = 5, /* dma */ | ||
135 | [IRQ_CCERRINT] = 5, /* dma */ | ||
136 | [IRQ_TCERRINT0] = 5, /* dma */ | ||
137 | [IRQ_TCERRINT] = 5, /* dma */ | ||
138 | [IRQ_PSCIN] = 7, | ||
139 | [21] = 7, | ||
140 | [IRQ_IDE] = 4, | ||
141 | [23] = 7, | ||
142 | [IRQ_MBXINT] = 7, | ||
143 | [IRQ_MBRINT] = 7, | ||
144 | [IRQ_MMCINT] = 7, | ||
145 | [IRQ_SDIOINT] = 7, | ||
146 | [28] = 7, | ||
147 | [IRQ_DDRINT] = 7, | ||
148 | [IRQ_AEMIFINT] = 7, | ||
149 | [IRQ_VLQINT] = 4, | ||
150 | [IRQ_TINT0_TINT12] = 2, /* clockevent */ | ||
151 | [IRQ_TINT0_TINT34] = 2, /* clocksource */ | ||
152 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | ||
153 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | ||
154 | [IRQ_PWMINT0] = 7, | ||
155 | [IRQ_PWMINT1] = 7, | ||
156 | [IRQ_PWMINT2] = 7, | ||
157 | [IRQ_I2C] = 3, | ||
158 | [IRQ_UARTINT0] = 3, | ||
159 | [IRQ_UARTINT1] = 3, | ||
160 | [IRQ_UARTINT2] = 3, | ||
161 | [IRQ_SPINT0] = 3, | ||
162 | [IRQ_SPINT1] = 3, | ||
163 | [45] = 7, | ||
164 | [IRQ_DSP2ARM0] = 4, | ||
165 | [IRQ_DSP2ARM1] = 4, | ||
166 | [IRQ_GPIO0] = 7, | ||
167 | [IRQ_GPIO1] = 7, | ||
168 | [IRQ_GPIO2] = 7, | ||
169 | [IRQ_GPIO3] = 7, | ||
170 | [IRQ_GPIO4] = 7, | ||
171 | [IRQ_GPIO5] = 7, | ||
172 | [IRQ_GPIO6] = 7, | ||
173 | [IRQ_GPIO7] = 7, | ||
174 | [IRQ_GPIOBNK0] = 7, | ||
175 | [IRQ_GPIOBNK1] = 7, | ||
176 | [IRQ_GPIOBNK2] = 7, | ||
177 | [IRQ_GPIOBNK3] = 7, | ||
178 | [IRQ_GPIOBNK4] = 7, | ||
179 | [IRQ_COMMTX] = 7, | ||
180 | [IRQ_COMMRX] = 7, | ||
181 | [IRQ_EMUINT] = 7, | ||
182 | }; | ||
183 | |||
184 | static const u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = { | ||
185 | [IRQ_DM646X_VP_VERTINT0] = 7, | ||
186 | [IRQ_DM646X_VP_VERTINT1] = 7, | ||
187 | [IRQ_DM646X_VP_VERTINT2] = 7, | ||
188 | [IRQ_DM646X_VP_VERTINT3] = 7, | ||
189 | [IRQ_DM646X_VP_ERRINT] = 7, | ||
190 | [IRQ_DM646X_RESERVED_1] = 7, | ||
191 | [IRQ_DM646X_RESERVED_2] = 7, | ||
192 | [IRQ_DM646X_WDINT] = 7, | ||
193 | [IRQ_DM646X_CRGENINT0] = 7, | ||
194 | [IRQ_DM646X_CRGENINT1] = 7, | ||
195 | [IRQ_DM646X_TSIFINT0] = 7, | ||
196 | [IRQ_DM646X_TSIFINT1] = 7, | ||
197 | [IRQ_DM646X_VDCEINT] = 7, | ||
198 | [IRQ_DM646X_USBINT] = 7, | ||
199 | [IRQ_DM646X_USBDMAINT] = 7, | ||
200 | [IRQ_DM646X_PCIINT] = 7, | ||
201 | [IRQ_CCINT0] = 7, /* dma */ | ||
202 | [IRQ_CCERRINT] = 7, /* dma */ | ||
203 | [IRQ_TCERRINT0] = 7, /* dma */ | ||
204 | [IRQ_TCERRINT] = 7, /* dma */ | ||
205 | [IRQ_DM646X_TCERRINT2] = 7, | ||
206 | [IRQ_DM646X_TCERRINT3] = 7, | ||
207 | [IRQ_DM646X_IDE] = 7, | ||
208 | [IRQ_DM646X_HPIINT] = 7, | ||
209 | [IRQ_DM646X_EMACRXTHINT] = 7, | ||
210 | [IRQ_DM646X_EMACRXINT] = 7, | ||
211 | [IRQ_DM646X_EMACTXINT] = 7, | ||
212 | [IRQ_DM646X_EMACMISCINT] = 7, | ||
213 | [IRQ_DM646X_MCASP0TXINT] = 7, | ||
214 | [IRQ_DM646X_MCASP0RXINT] = 7, | ||
215 | [IRQ_AEMIFINT] = 7, | ||
216 | [IRQ_DM646X_RESERVED_3] = 7, | ||
217 | [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */ | ||
218 | [IRQ_TINT0_TINT34] = 7, /* clocksource */ | ||
219 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | ||
220 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | ||
221 | [IRQ_PWMINT0] = 7, | ||
222 | [IRQ_PWMINT1] = 7, | ||
223 | [IRQ_DM646X_VLQINT] = 7, | ||
224 | [IRQ_I2C] = 7, | ||
225 | [IRQ_UARTINT0] = 7, | ||
226 | [IRQ_UARTINT1] = 7, | ||
227 | [IRQ_DM646X_UARTINT2] = 7, | ||
228 | [IRQ_DM646X_SPINT0] = 7, | ||
229 | [IRQ_DM646X_SPINT1] = 7, | ||
230 | [IRQ_DM646X_DSP2ARMINT] = 7, | ||
231 | [IRQ_DM646X_RESERVED_4] = 7, | ||
232 | [IRQ_DM646X_PSCINT] = 7, | ||
233 | [IRQ_DM646X_GPIO0] = 7, | ||
234 | [IRQ_DM646X_GPIO1] = 7, | ||
235 | [IRQ_DM646X_GPIO2] = 7, | ||
236 | [IRQ_DM646X_GPIO3] = 7, | ||
237 | [IRQ_DM646X_GPIO4] = 7, | ||
238 | [IRQ_DM646X_GPIO5] = 7, | ||
239 | [IRQ_DM646X_GPIO6] = 7, | ||
240 | [IRQ_DM646X_GPIO7] = 7, | ||
241 | [IRQ_DM646X_GPIOBNK0] = 7, | ||
242 | [IRQ_DM646X_GPIOBNK1] = 7, | ||
243 | [IRQ_DM646X_GPIOBNK2] = 7, | ||
244 | [IRQ_DM646X_DDRINT] = 7, | ||
245 | [IRQ_DM646X_AEMIFINT] = 7, | ||
246 | [IRQ_COMMTX] = 7, | ||
247 | [IRQ_COMMRX] = 7, | ||
248 | [IRQ_EMUINT] = 7, | ||
249 | }; | ||
250 | |||
251 | static const u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = { | ||
252 | [IRQ_DM355_CCDC_VDINT0] = 2, | ||
253 | [IRQ_DM355_CCDC_VDINT1] = 6, | ||
254 | [IRQ_DM355_CCDC_VDINT2] = 6, | ||
255 | [IRQ_DM355_IPIPE_HST] = 6, | ||
256 | [IRQ_DM355_H3AINT] = 6, | ||
257 | [IRQ_DM355_IPIPE_SDR] = 6, | ||
258 | [IRQ_DM355_IPIPEIFINT] = 6, | ||
259 | [IRQ_DM355_OSDINT] = 7, | ||
260 | [IRQ_DM355_VENCINT] = 6, | ||
261 | [IRQ_ASQINT] = 6, | ||
262 | [IRQ_IMXINT] = 6, | ||
263 | [IRQ_USBINT] = 4, | ||
264 | [IRQ_DM355_RTOINT] = 4, | ||
265 | [IRQ_DM355_UARTINT2] = 7, | ||
266 | [IRQ_DM355_TINT6] = 7, | ||
267 | [IRQ_CCINT0] = 5, /* dma */ | ||
268 | [IRQ_CCERRINT] = 5, /* dma */ | ||
269 | [IRQ_TCERRINT0] = 5, /* dma */ | ||
270 | [IRQ_TCERRINT] = 5, /* dma */ | ||
271 | [IRQ_DM355_SPINT2_1] = 7, | ||
272 | [IRQ_DM355_TINT7] = 4, | ||
273 | [IRQ_DM355_SDIOINT0] = 7, | ||
274 | [IRQ_MBXINT] = 7, | ||
275 | [IRQ_MBRINT] = 7, | ||
276 | [IRQ_MMCINT] = 7, | ||
277 | [IRQ_DM355_MMCINT1] = 7, | ||
278 | [IRQ_DM355_PWMINT3] = 7, | ||
279 | [IRQ_DDRINT] = 7, | ||
280 | [IRQ_AEMIFINT] = 7, | ||
281 | [IRQ_DM355_SDIOINT1] = 4, | ||
282 | [IRQ_TINT0_TINT12] = 2, /* clockevent */ | ||
283 | [IRQ_TINT0_TINT34] = 2, /* clocksource */ | ||
284 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | ||
285 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | ||
286 | [IRQ_PWMINT0] = 7, | ||
287 | [IRQ_PWMINT1] = 7, | ||
288 | [IRQ_PWMINT2] = 7, | ||
289 | [IRQ_I2C] = 3, | ||
290 | [IRQ_UARTINT0] = 3, | ||
291 | [IRQ_UARTINT1] = 3, | ||
292 | [IRQ_DM355_SPINT0_0] = 3, | ||
293 | [IRQ_DM355_SPINT0_1] = 3, | ||
294 | [IRQ_DM355_GPIO0] = 3, | ||
295 | [IRQ_DM355_GPIO1] = 7, | ||
296 | [IRQ_DM355_GPIO2] = 4, | ||
297 | [IRQ_DM355_GPIO3] = 4, | ||
298 | [IRQ_DM355_GPIO4] = 7, | ||
299 | [IRQ_DM355_GPIO5] = 7, | ||
300 | [IRQ_DM355_GPIO6] = 7, | ||
301 | [IRQ_DM355_GPIO7] = 7, | ||
302 | [IRQ_DM355_GPIO8] = 7, | ||
303 | [IRQ_DM355_GPIO9] = 7, | ||
304 | [IRQ_DM355_GPIOBNK0] = 7, | ||
305 | [IRQ_DM355_GPIOBNK1] = 7, | ||
306 | [IRQ_DM355_GPIOBNK2] = 7, | ||
307 | [IRQ_DM355_GPIOBNK3] = 7, | ||
308 | [IRQ_DM355_GPIOBNK4] = 7, | ||
309 | [IRQ_DM355_GPIOBNK5] = 7, | ||
310 | [IRQ_DM355_GPIOBNK6] = 7, | ||
311 | [IRQ_COMMTX] = 7, | ||
312 | [IRQ_COMMRX] = 7, | ||
313 | [IRQ_EMUINT] = 7, | ||
314 | }; | ||
315 | |||
316 | /* ARM Interrupt Controller Initialization */ | 113 | /* ARM Interrupt Controller Initialization */ |
317 | void __init davinci_irq_init(void) | 114 | void __init davinci_irq_init(void) |
318 | { | 115 | { |
319 | unsigned i; | 116 | unsigned i; |
320 | 117 | const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios; | |
321 | if (cpu_is_davinci_dm644x()) | ||
322 | davinci_def_priorities = dm644x_default_priorities; | ||
323 | else if (cpu_is_davinci_dm646x()) | ||
324 | davinci_def_priorities = dm646x_default_priorities; | ||
325 | else if (cpu_is_davinci_dm355()) | ||
326 | davinci_def_priorities = dm355_default_priorities; | ||
327 | 118 | ||
328 | /* Clear all interrupt requests */ | 119 | /* Clear all interrupt requests */ |
329 | davinci_irq_writel(~0x0, FIQ_REG0_OFFSET); | 120 | davinci_irq_writel(~0x0, FIQ_REG0_OFFSET); |
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c index bbba0b247a44..d310f579aa85 100644 --- a/arch/arm/mach-davinci/mux.c +++ b/arch/arm/mach-davinci/mux.c | |||
@@ -21,18 +21,7 @@ | |||
21 | 21 | ||
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <mach/mux.h> | 23 | #include <mach/mux.h> |
24 | 24 | #include <mach/common.h> | |
25 | static const struct mux_config *mux_table; | ||
26 | static unsigned long pin_table_sz; | ||
27 | |||
28 | int __init davinci_mux_register(const struct mux_config *pins, | ||
29 | unsigned long size) | ||
30 | { | ||
31 | mux_table = pins; | ||
32 | pin_table_sz = size; | ||
33 | |||
34 | return 0; | ||
35 | } | ||
36 | 25 | ||
37 | /* | 26 | /* |
38 | * Sets the DAVINCI MUX register based on the table | 27 | * Sets the DAVINCI MUX register based on the table |
@@ -40,23 +29,24 @@ int __init davinci_mux_register(const struct mux_config *pins, | |||
40 | int __init_or_module davinci_cfg_reg(const unsigned long index) | 29 | int __init_or_module davinci_cfg_reg(const unsigned long index) |
41 | { | 30 | { |
42 | static DEFINE_SPINLOCK(mux_spin_lock); | 31 | static DEFINE_SPINLOCK(mux_spin_lock); |
43 | void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); | 32 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
33 | void __iomem *base = soc_info->pinmux_base; | ||
44 | unsigned long flags; | 34 | unsigned long flags; |
45 | const struct mux_config *cfg; | 35 | const struct mux_config *cfg; |
46 | unsigned int reg_orig = 0, reg = 0; | 36 | unsigned int reg_orig = 0, reg = 0; |
47 | unsigned int mask, warn = 0; | 37 | unsigned int mask, warn = 0; |
48 | 38 | ||
49 | if (!mux_table) | 39 | if (!soc_info->pinmux_pins) |
50 | BUG(); | 40 | BUG(); |
51 | 41 | ||
52 | if (index >= pin_table_sz) { | 42 | if (index >= soc_info->pinmux_pins_num) { |
53 | printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", | 43 | printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", |
54 | index, pin_table_sz); | 44 | index, soc_info->pinmux_pins_num); |
55 | dump_stack(); | 45 | dump_stack(); |
56 | return -ENODEV; | 46 | return -ENODEV; |
57 | } | 47 | } |
58 | 48 | ||
59 | cfg = &mux_table[index]; | 49 | cfg = &soc_info->pinmux_pins[index]; |
60 | 50 | ||
61 | if (cfg->name == NULL) { | 51 | if (cfg->name == NULL) { |
62 | printk(KERN_ERR "No entry for the specified index\n"); | 52 | printk(KERN_ERR "No entry for the specified index\n"); |
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index 84171abf5f7b..a78b657e916e 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c | |||
@@ -28,8 +28,6 @@ | |||
28 | #include <mach/psc.h> | 28 | #include <mach/psc.h> |
29 | #include <mach/mux.h> | 29 | #include <mach/mux.h> |
30 | 30 | ||
31 | #define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000 | ||
32 | |||
33 | /* PSC register offsets */ | 31 | /* PSC register offsets */ |
34 | #define EPCPR 0x070 | 32 | #define EPCPR 0x070 |
35 | #define PTCMD 0x120 | 33 | #define PTCMD 0x120 |
@@ -42,22 +40,42 @@ | |||
42 | #define MDSTAT_STATE_MASK 0x1f | 40 | #define MDSTAT_STATE_MASK 0x1f |
43 | 41 | ||
44 | /* Return nonzero iff the domain's clock is active */ | 42 | /* Return nonzero iff the domain's clock is active */ |
45 | int __init davinci_psc_is_clk_active(unsigned int id) | 43 | int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) |
46 | { | 44 | { |
47 | void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE); | 45 | void __iomem *psc_base; |
48 | u32 mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); | 46 | u32 mdstat; |
47 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
48 | |||
49 | if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { | ||
50 | pr_warning("PSC: Bad psc data: 0x%x[%d]\n", | ||
51 | (int)soc_info->psc_bases, ctlr); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | psc_base = soc_info->psc_bases[ctlr]; | ||
56 | mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); | ||
49 | 57 | ||
50 | /* if clocked, state can be "Enable" or "SyncReset" */ | 58 | /* if clocked, state can be "Enable" or "SyncReset" */ |
51 | return mdstat & BIT(12); | 59 | return mdstat & BIT(12); |
52 | } | 60 | } |
53 | 61 | ||
54 | /* Enable or disable a PSC domain */ | 62 | /* Enable or disable a PSC domain */ |
55 | void davinci_psc_config(unsigned int domain, unsigned int id, char enable) | 63 | void davinci_psc_config(unsigned int domain, unsigned int ctlr, |
64 | unsigned int id, char enable) | ||
56 | { | 65 | { |
57 | u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; | 66 | u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; |
58 | void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE); | 67 | void __iomem *psc_base; |
68 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
59 | u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */ | 69 | u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */ |
60 | 70 | ||
71 | if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { | ||
72 | pr_warning("PSC: Bad psc data: 0x%x[%d]\n", | ||
73 | (int)soc_info->psc_bases, ctlr); | ||
74 | return; | ||
75 | } | ||
76 | |||
77 | psc_base = soc_info->psc_bases[ctlr]; | ||
78 | |||
61 | mdctl = __raw_readl(psc_base + MDCTL + 4 * id); | 79 | mdctl = __raw_readl(psc_base + MDCTL + 4 * id); |
62 | mdctl &= ~MDSTAT_STATE_MASK; | 80 | mdctl &= ~MDSTAT_STATE_MASK; |
63 | mdctl |= next_state; | 81 | mdctl |= next_state; |
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c index 695075796522..c530c7333d0a 100644 --- a/arch/arm/mach-davinci/serial.c +++ b/arch/arm/mach-davinci/serial.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <mach/serial.h> | 33 | #include <mach/serial.h> |
34 | #include <mach/irqs.h> | 34 | #include <mach/irqs.h> |
35 | #include <mach/cputype.h> | 35 | #include <mach/cputype.h> |
36 | #include <mach/common.h> | ||
37 | |||
36 | #include "clock.h" | 38 | #include "clock.h" |
37 | 39 | ||
38 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, | 40 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, |
@@ -49,44 +51,6 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, | |||
49 | __raw_writel(value, IO_ADDRESS(p->mapbase) + offset); | 51 | __raw_writel(value, IO_ADDRESS(p->mapbase) + offset); |
50 | } | 52 | } |
51 | 53 | ||
52 | static struct plat_serial8250_port serial_platform_data[] = { | ||
53 | { | ||
54 | .mapbase = DAVINCI_UART0_BASE, | ||
55 | .irq = IRQ_UARTINT0, | ||
56 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
57 | UPF_IOREMAP, | ||
58 | .iotype = UPIO_MEM, | ||
59 | .regshift = 2, | ||
60 | }, | ||
61 | { | ||
62 | .mapbase = DAVINCI_UART1_BASE, | ||
63 | .irq = IRQ_UARTINT1, | ||
64 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
65 | UPF_IOREMAP, | ||
66 | .iotype = UPIO_MEM, | ||
67 | .regshift = 2, | ||
68 | }, | ||
69 | { | ||
70 | .mapbase = DAVINCI_UART2_BASE, | ||
71 | .irq = IRQ_UARTINT2, | ||
72 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
73 | UPF_IOREMAP, | ||
74 | .iotype = UPIO_MEM, | ||
75 | .regshift = 2, | ||
76 | }, | ||
77 | { | ||
78 | .flags = 0 | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | static struct platform_device serial_device = { | ||
83 | .name = "serial8250", | ||
84 | .id = PLAT8250_DEV_PLATFORM, | ||
85 | .dev = { | ||
86 | .platform_data = serial_platform_data, | ||
87 | }, | ||
88 | }; | ||
89 | |||
90 | static void __init davinci_serial_reset(struct plat_serial8250_port *p) | 54 | static void __init davinci_serial_reset(struct plat_serial8250_port *p) |
91 | { | 55 | { |
92 | unsigned int pwremu = 0; | 56 | unsigned int pwremu = 0; |
@@ -106,35 +70,22 @@ static void __init davinci_serial_reset(struct plat_serial8250_port *p) | |||
106 | UART_DM646X_SCR_TX_WATERMARK); | 70 | UART_DM646X_SCR_TX_WATERMARK); |
107 | } | 71 | } |
108 | 72 | ||
109 | void __init davinci_serial_init(struct davinci_uart_config *info) | 73 | int __init davinci_serial_init(struct davinci_uart_config *info) |
110 | { | 74 | { |
111 | int i; | 75 | int i; |
112 | char name[16]; | 76 | char name[16]; |
113 | struct clk *uart_clk; | 77 | struct clk *uart_clk; |
114 | struct device *dev = &serial_device.dev; | 78 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
79 | struct device *dev = &soc_info->serial_dev->dev; | ||
80 | struct plat_serial8250_port *p = dev->platform_data; | ||
115 | 81 | ||
116 | /* | 82 | /* |
117 | * Make sure the serial ports are muxed on at this point. | 83 | * Make sure the serial ports are muxed on at this point. |
118 | * You have to mux them off in device drivers later on | 84 | * You have to mux them off in device drivers later on if not needed. |
119 | * if not needed. | ||
120 | */ | 85 | */ |
121 | for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++) { | 86 | for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++, p++) { |
122 | struct plat_serial8250_port *p = serial_platform_data + i; | 87 | if (!(info->enabled_uarts & (1 << i))) |
123 | |||
124 | if (!(info->enabled_uarts & (1 << i))) { | ||
125 | p->flags = 0; | ||
126 | continue; | 88 | continue; |
127 | } | ||
128 | |||
129 | if (cpu_is_davinci_dm646x()) | ||
130 | p->iotype = UPIO_MEM32; | ||
131 | |||
132 | if (cpu_is_davinci_dm355()) { | ||
133 | if (i == 2) { | ||
134 | p->mapbase = (unsigned long)DM355_UART2_BASE; | ||
135 | p->irq = IRQ_DM355_UARTINT2; | ||
136 | } | ||
137 | } | ||
138 | 89 | ||
139 | sprintf(name, "uart%d", i); | 90 | sprintf(name, "uart%d", i); |
140 | uart_clk = clk_get(dev, name); | 91 | uart_clk = clk_get(dev, name); |
@@ -147,11 +98,6 @@ void __init davinci_serial_init(struct davinci_uart_config *info) | |||
147 | davinci_serial_reset(p); | 98 | davinci_serial_reset(p); |
148 | } | 99 | } |
149 | } | 100 | } |
150 | } | ||
151 | 101 | ||
152 | static int __init davinci_init(void) | 102 | return platform_device_register(soc_info->serial_dev); |
153 | { | ||
154 | return platform_device_register(&serial_device); | ||
155 | } | 103 | } |
156 | |||
157 | arch_initcall(davinci_init); | ||
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c new file mode 100644 index 000000000000..db54b2a66b4d --- /dev/null +++ b/arch/arm/mach-davinci/sram.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * mach-davinci/sram.c - DaVinci simple SRAM allocator | ||
3 | * | ||
4 | * Copyright (C) 2009 David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/genalloc.h> | ||
15 | |||
16 | #include <mach/common.h> | ||
17 | #include <mach/memory.h> | ||
18 | #include <mach/sram.h> | ||
19 | |||
20 | |||
21 | static struct gen_pool *sram_pool; | ||
22 | |||
23 | void *sram_alloc(size_t len, dma_addr_t *dma) | ||
24 | { | ||
25 | unsigned long vaddr; | ||
26 | dma_addr_t dma_base = davinci_soc_info.sram_dma; | ||
27 | |||
28 | if (dma) | ||
29 | *dma = 0; | ||
30 | if (!sram_pool || (dma && !dma_base)) | ||
31 | return NULL; | ||
32 | |||
33 | vaddr = gen_pool_alloc(sram_pool, len); | ||
34 | if (!vaddr) | ||
35 | return NULL; | ||
36 | |||
37 | if (dma) | ||
38 | *dma = dma_base + (vaddr - SRAM_VIRT); | ||
39 | return (void *)vaddr; | ||
40 | |||
41 | } | ||
42 | EXPORT_SYMBOL(sram_alloc); | ||
43 | |||
44 | void sram_free(void *addr, size_t len) | ||
45 | { | ||
46 | gen_pool_free(sram_pool, (unsigned long) addr, len); | ||
47 | } | ||
48 | EXPORT_SYMBOL(sram_free); | ||
49 | |||
50 | |||
51 | /* | ||
52 | * REVISIT This supports CPU and DMA access to/from SRAM, but it | ||
53 | * doesn't (yet?) support some other notable uses of SRAM: as TCM | ||
54 | * for data and/or instructions; and holding code needed to enter | ||
55 | * and exit suspend states (while DRAM can't be used). | ||
56 | */ | ||
57 | static int __init sram_init(void) | ||
58 | { | ||
59 | unsigned len = davinci_soc_info.sram_len; | ||
60 | int status = 0; | ||
61 | |||
62 | if (len) { | ||
63 | len = min(len, SRAM_SIZE); | ||
64 | sram_pool = gen_pool_create(ilog2(SRAM_GRANULARITY), -1); | ||
65 | if (!sram_pool) | ||
66 | status = -ENOMEM; | ||
67 | } | ||
68 | if (sram_pool) | ||
69 | status = gen_pool_add(sram_pool, SRAM_VIRT, len, -1); | ||
70 | WARN_ON(status < 0); | ||
71 | return status; | ||
72 | } | ||
73 | core_initcall(sram_init); | ||
74 | |||
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 494e01bff5c3..0884ca57bfb0 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/platform_device.h> | ||
22 | 23 | ||
23 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
24 | #include <asm/system.h> | 25 | #include <asm/system.h> |
@@ -28,52 +29,41 @@ | |||
28 | #include <asm/errno.h> | 29 | #include <asm/errno.h> |
29 | #include <mach/io.h> | 30 | #include <mach/io.h> |
30 | #include <mach/cputype.h> | 31 | #include <mach/cputype.h> |
32 | #include <mach/time.h> | ||
31 | #include "clock.h" | 33 | #include "clock.h" |
32 | 34 | ||
33 | static struct clock_event_device clockevent_davinci; | 35 | static struct clock_event_device clockevent_davinci; |
34 | static unsigned int davinci_clock_tick_rate; | 36 | static unsigned int davinci_clock_tick_rate; |
35 | 37 | ||
36 | #define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400) | ||
37 | #define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) | ||
38 | #define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00) | ||
39 | |||
40 | enum { | ||
41 | T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS, | ||
42 | }; | ||
43 | |||
44 | #define IS_TIMER1(id) (id & 0x2) | ||
45 | #define IS_TIMER0(id) (!IS_TIMER1(id)) | ||
46 | #define IS_TIMER_TOP(id) ((id & 0x1)) | ||
47 | #define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id)) | ||
48 | |||
49 | static int timer_irqs[NUM_TIMERS] = { | ||
50 | IRQ_TINT0_TINT12, | ||
51 | IRQ_TINT0_TINT34, | ||
52 | IRQ_TINT1_TINT12, | ||
53 | IRQ_TINT1_TINT34, | ||
54 | }; | ||
55 | |||
56 | /* | 38 | /* |
57 | * This driver configures the 2 64-bit count-up timers as 4 independent | 39 | * This driver configures the 2 64-bit count-up timers as 4 independent |
58 | * 32-bit count-up timers used as follows: | 40 | * 32-bit count-up timers used as follows: |
59 | * | ||
60 | * T0_BOT: Timer 0, bottom: clockevent source for hrtimers | ||
61 | * T0_TOP: Timer 0, top : clocksource for generic timekeeping | ||
62 | * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) | ||
63 | * T1_TOP: Timer 1, top : <unused> | ||
64 | */ | 41 | */ |
65 | #define TID_CLOCKEVENT T0_BOT | 42 | |
66 | #define TID_CLOCKSOURCE T0_TOP | 43 | enum { |
44 | TID_CLOCKEVENT, | ||
45 | TID_CLOCKSOURCE, | ||
46 | }; | ||
67 | 47 | ||
68 | /* Timer register offsets */ | 48 | /* Timer register offsets */ |
69 | #define PID12 0x0 | 49 | #define PID12 0x0 |
70 | #define TIM12 0x10 | 50 | #define TIM12 0x10 |
71 | #define TIM34 0x14 | 51 | #define TIM34 0x14 |
72 | #define PRD12 0x18 | 52 | #define PRD12 0x18 |
73 | #define PRD34 0x1c | 53 | #define PRD34 0x1c |
74 | #define TCR 0x20 | 54 | #define TCR 0x20 |
75 | #define TGCR 0x24 | 55 | #define TGCR 0x24 |
76 | #define WDTCR 0x28 | 56 | #define WDTCR 0x28 |
57 | |||
58 | /* Offsets of the 8 compare registers */ | ||
59 | #define CMP12_0 0x60 | ||
60 | #define CMP12_1 0x64 | ||
61 | #define CMP12_2 0x68 | ||
62 | #define CMP12_3 0x6c | ||
63 | #define CMP12_4 0x70 | ||
64 | #define CMP12_5 0x74 | ||
65 | #define CMP12_6 0x78 | ||
66 | #define CMP12_7 0x7c | ||
77 | 67 | ||
78 | /* Timer register bitfields */ | 68 | /* Timer register bitfields */ |
79 | #define TCR_ENAMODE_DISABLE 0x0 | 69 | #define TCR_ENAMODE_DISABLE 0x0 |
@@ -105,6 +95,7 @@ struct timer_s { | |||
105 | unsigned int id; | 95 | unsigned int id; |
106 | unsigned long period; | 96 | unsigned long period; |
107 | unsigned long opts; | 97 | unsigned long opts; |
98 | unsigned long flags; | ||
108 | void __iomem *base; | 99 | void __iomem *base; |
109 | unsigned long tim_off; | 100 | unsigned long tim_off; |
110 | unsigned long prd_off; | 101 | unsigned long prd_off; |
@@ -114,30 +105,58 @@ struct timer_s { | |||
114 | static struct timer_s timers[]; | 105 | static struct timer_s timers[]; |
115 | 106 | ||
116 | /* values for 'opts' field of struct timer_s */ | 107 | /* values for 'opts' field of struct timer_s */ |
117 | #define TIMER_OPTS_DISABLED 0x00 | 108 | #define TIMER_OPTS_DISABLED 0x01 |
118 | #define TIMER_OPTS_ONESHOT 0x01 | 109 | #define TIMER_OPTS_ONESHOT 0x02 |
119 | #define TIMER_OPTS_PERIODIC 0x02 | 110 | #define TIMER_OPTS_PERIODIC 0x04 |
111 | #define TIMER_OPTS_STATE_MASK 0x07 | ||
112 | |||
113 | #define TIMER_OPTS_USE_COMPARE 0x80000000 | ||
114 | #define USING_COMPARE(t) ((t)->opts & TIMER_OPTS_USE_COMPARE) | ||
115 | |||
116 | static char *id_to_name[] = { | ||
117 | [T0_BOT] = "timer0_0", | ||
118 | [T0_TOP] = "timer0_1", | ||
119 | [T1_BOT] = "timer1_0", | ||
120 | [T1_TOP] = "timer1_1", | ||
121 | }; | ||
120 | 122 | ||
121 | static int timer32_config(struct timer_s *t) | 123 | static int timer32_config(struct timer_s *t) |
122 | { | 124 | { |
123 | u32 tcr = __raw_readl(t->base + TCR); | 125 | u32 tcr; |
124 | 126 | struct davinci_soc_info *soc_info = &davinci_soc_info; | |
125 | /* disable timer */ | 127 | |
126 | tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift); | 128 | if (USING_COMPARE(t)) { |
127 | __raw_writel(tcr, t->base + TCR); | 129 | struct davinci_timer_instance *dtip = |
128 | 130 | soc_info->timer_info->timers; | |
129 | /* reset counter to zero, set new period */ | 131 | int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id); |
130 | __raw_writel(0, t->base + t->tim_off); | 132 | |
131 | __raw_writel(t->period, t->base + t->prd_off); | 133 | /* |
132 | 134 | * Next interrupt should be the current time reg value plus | |
133 | /* Set enable mode */ | 135 | * the new period (using 32-bit unsigned addition/wrapping |
134 | if (t->opts & TIMER_OPTS_ONESHOT) { | 136 | * to 0 on overflow). This assumes that the clocksource |
135 | tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift; | 137 | * is setup to count to 2^32-1 before wrapping around to 0. |
136 | } else if (t->opts & TIMER_OPTS_PERIODIC) { | 138 | */ |
137 | tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift; | 139 | __raw_writel(__raw_readl(t->base + t->tim_off) + t->period, |
140 | t->base + dtip[event_timer].cmp_off); | ||
141 | } else { | ||
142 | tcr = __raw_readl(t->base + TCR); | ||
143 | |||
144 | /* disable timer */ | ||
145 | tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift); | ||
146 | __raw_writel(tcr, t->base + TCR); | ||
147 | |||
148 | /* reset counter to zero, set new period */ | ||
149 | __raw_writel(0, t->base + t->tim_off); | ||
150 | __raw_writel(t->period, t->base + t->prd_off); | ||
151 | |||
152 | /* Set enable mode */ | ||
153 | if (t->opts & TIMER_OPTS_ONESHOT) | ||
154 | tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift; | ||
155 | else if (t->opts & TIMER_OPTS_PERIODIC) | ||
156 | tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift; | ||
157 | |||
158 | __raw_writel(tcr, t->base + TCR); | ||
138 | } | 159 | } |
139 | |||
140 | __raw_writel(tcr, t->base + TCR); | ||
141 | return 0; | 160 | return 0; |
142 | } | 161 | } |
143 | 162 | ||
@@ -182,13 +201,14 @@ static struct timer_s timers[] = { | |||
182 | 201 | ||
183 | static void __init timer_init(void) | 202 | static void __init timer_init(void) |
184 | { | 203 | { |
185 | u32 phys_bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE}; | 204 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
205 | struct davinci_timer_instance *dtip = soc_info->timer_info->timers; | ||
186 | int i; | 206 | int i; |
187 | 207 | ||
188 | /* Global init of each 64-bit timer as a whole */ | 208 | /* Global init of each 64-bit timer as a whole */ |
189 | for(i=0; i<2; i++) { | 209 | for(i=0; i<2; i++) { |
190 | u32 tgcr; | 210 | u32 tgcr; |
191 | void __iomem *base = IO_ADDRESS(phys_bases[i]); | 211 | void __iomem *base = dtip[i].base; |
192 | 212 | ||
193 | /* Disabled, Internal clock source */ | 213 | /* Disabled, Internal clock source */ |
194 | __raw_writel(0, base + TCR); | 214 | __raw_writel(0, base + TCR); |
@@ -214,33 +234,33 @@ static void __init timer_init(void) | |||
214 | /* Init of each timer as a 32-bit timer */ | 234 | /* Init of each timer as a 32-bit timer */ |
215 | for (i=0; i< ARRAY_SIZE(timers); i++) { | 235 | for (i=0; i< ARRAY_SIZE(timers); i++) { |
216 | struct timer_s *t = &timers[i]; | 236 | struct timer_s *t = &timers[i]; |
217 | u32 phys_base; | 237 | int timer = ID_TO_TIMER(t->id); |
218 | 238 | u32 irq; | |
219 | if (t->name) { | 239 | |
220 | t->id = i; | 240 | t->base = dtip[timer].base; |
221 | phys_base = (IS_TIMER1(t->id) ? | 241 | |
222 | DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE); | 242 | if (IS_TIMER_BOT(t->id)) { |
223 | t->base = IO_ADDRESS(phys_base); | 243 | t->enamode_shift = 6; |
224 | 244 | t->tim_off = TIM12; | |
225 | if (IS_TIMER_BOT(t->id)) { | 245 | t->prd_off = PRD12; |
226 | t->enamode_shift = 6; | 246 | irq = dtip[timer].bottom_irq; |
227 | t->tim_off = TIM12; | 247 | } else { |
228 | t->prd_off = PRD12; | 248 | t->enamode_shift = 22; |
229 | } else { | 249 | t->tim_off = TIM34; |
230 | t->enamode_shift = 22; | 250 | t->prd_off = PRD34; |
231 | t->tim_off = TIM34; | 251 | irq = dtip[timer].top_irq; |
232 | t->prd_off = PRD34; | 252 | } |
233 | } | 253 | |
234 | 254 | /* Register interrupt */ | |
235 | /* Register interrupt */ | 255 | t->irqaction.name = t->name; |
236 | t->irqaction.name = t->name; | 256 | t->irqaction.dev_id = (void *)t; |
237 | t->irqaction.dev_id = (void *)t; | 257 | |
238 | if (t->irqaction.handler != NULL) { | 258 | if (t->irqaction.handler != NULL) { |
239 | setup_irq(timer_irqs[t->id], &t->irqaction); | 259 | irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; |
240 | } | 260 | setup_irq(irq, &t->irqaction); |
241 | |||
242 | timer32_config(&timers[i]); | ||
243 | } | 261 | } |
262 | |||
263 | timer32_config(&timers[i]); | ||
244 | } | 264 | } |
245 | } | 265 | } |
246 | 266 | ||
@@ -255,7 +275,6 @@ static cycle_t read_cycles(struct clocksource *cs) | |||
255 | } | 275 | } |
256 | 276 | ||
257 | static struct clocksource clocksource_davinci = { | 277 | static struct clocksource clocksource_davinci = { |
258 | .name = "timer0_1", | ||
259 | .rating = 300, | 278 | .rating = 300, |
260 | .read = read_cycles, | 279 | .read = read_cycles, |
261 | .mask = CLOCKSOURCE_MASK(32), | 280 | .mask = CLOCKSOURCE_MASK(32), |
@@ -284,15 +303,18 @@ static void davinci_set_mode(enum clock_event_mode mode, | |||
284 | switch (mode) { | 303 | switch (mode) { |
285 | case CLOCK_EVT_MODE_PERIODIC: | 304 | case CLOCK_EVT_MODE_PERIODIC: |
286 | t->period = davinci_clock_tick_rate / (HZ); | 305 | t->period = davinci_clock_tick_rate / (HZ); |
287 | t->opts = TIMER_OPTS_PERIODIC; | 306 | t->opts &= ~TIMER_OPTS_STATE_MASK; |
307 | t->opts |= TIMER_OPTS_PERIODIC; | ||
288 | timer32_config(t); | 308 | timer32_config(t); |
289 | break; | 309 | break; |
290 | case CLOCK_EVT_MODE_ONESHOT: | 310 | case CLOCK_EVT_MODE_ONESHOT: |
291 | t->opts = TIMER_OPTS_ONESHOT; | 311 | t->opts &= ~TIMER_OPTS_STATE_MASK; |
312 | t->opts |= TIMER_OPTS_ONESHOT; | ||
292 | break; | 313 | break; |
293 | case CLOCK_EVT_MODE_UNUSED: | 314 | case CLOCK_EVT_MODE_UNUSED: |
294 | case CLOCK_EVT_MODE_SHUTDOWN: | 315 | case CLOCK_EVT_MODE_SHUTDOWN: |
295 | t->opts = TIMER_OPTS_DISABLED; | 316 | t->opts &= ~TIMER_OPTS_STATE_MASK; |
317 | t->opts |= TIMER_OPTS_DISABLED; | ||
296 | break; | 318 | break; |
297 | case CLOCK_EVT_MODE_RESUME: | 319 | case CLOCK_EVT_MODE_RESUME: |
298 | break; | 320 | break; |
@@ -300,7 +322,6 @@ static void davinci_set_mode(enum clock_event_mode mode, | |||
300 | } | 322 | } |
301 | 323 | ||
302 | static struct clock_event_device clockevent_davinci = { | 324 | static struct clock_event_device clockevent_davinci = { |
303 | .name = "timer0_0", | ||
304 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 325 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
305 | .shift = 32, | 326 | .shift = 32, |
306 | .set_next_event = davinci_set_next_event, | 327 | .set_next_event = davinci_set_next_event, |
@@ -311,10 +332,42 @@ static struct clock_event_device clockevent_davinci = { | |||
311 | static void __init davinci_timer_init(void) | 332 | static void __init davinci_timer_init(void) |
312 | { | 333 | { |
313 | struct clk *timer_clk; | 334 | struct clk *timer_clk; |
314 | 335 | struct davinci_soc_info *soc_info = &davinci_soc_info; | |
336 | unsigned int clockevent_id; | ||
337 | unsigned int clocksource_id; | ||
315 | static char err[] __initdata = KERN_ERR | 338 | static char err[] __initdata = KERN_ERR |
316 | "%s: can't register clocksource!\n"; | 339 | "%s: can't register clocksource!\n"; |
317 | 340 | ||
341 | clockevent_id = soc_info->timer_info->clockevent_id; | ||
342 | clocksource_id = soc_info->timer_info->clocksource_id; | ||
343 | |||
344 | timers[TID_CLOCKEVENT].id = clockevent_id; | ||
345 | timers[TID_CLOCKSOURCE].id = clocksource_id; | ||
346 | |||
347 | /* | ||
348 | * If using same timer for both clock events & clocksource, | ||
349 | * a compare register must be used to generate an event interrupt. | ||
350 | * This is equivalent to a oneshot timer only (not periodic). | ||
351 | */ | ||
352 | if (clockevent_id == clocksource_id) { | ||
353 | struct davinci_timer_instance *dtip = | ||
354 | soc_info->timer_info->timers; | ||
355 | int event_timer = ID_TO_TIMER(clockevent_id); | ||
356 | |||
357 | /* Only bottom timers can use compare regs */ | ||
358 | if (IS_TIMER_TOP(clockevent_id)) | ||
359 | pr_warning("davinci_timer_init: Invalid use" | ||
360 | " of system timers. Results unpredictable.\n"); | ||
361 | else if ((dtip[event_timer].cmp_off == 0) | ||
362 | || (dtip[event_timer].cmp_irq == 0)) | ||
363 | pr_warning("davinci_timer_init: Invalid timer instance" | ||
364 | " setup. Results unpredictable.\n"); | ||
365 | else { | ||
366 | timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE; | ||
367 | clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT; | ||
368 | } | ||
369 | } | ||
370 | |||
318 | /* init timer hw */ | 371 | /* init timer hw */ |
319 | timer_init(); | 372 | timer_init(); |
320 | 373 | ||
@@ -325,6 +378,7 @@ static void __init davinci_timer_init(void) | |||
325 | davinci_clock_tick_rate = clk_get_rate(timer_clk); | 378 | davinci_clock_tick_rate = clk_get_rate(timer_clk); |
326 | 379 | ||
327 | /* setup clocksource */ | 380 | /* setup clocksource */ |
381 | clocksource_davinci.name = id_to_name[clocksource_id]; | ||
328 | clocksource_davinci.mult = | 382 | clocksource_davinci.mult = |
329 | clocksource_khz2mult(davinci_clock_tick_rate/1000, | 383 | clocksource_khz2mult(davinci_clock_tick_rate/1000, |
330 | clocksource_davinci.shift); | 384 | clocksource_davinci.shift); |
@@ -332,12 +386,12 @@ static void __init davinci_timer_init(void) | |||
332 | printk(err, clocksource_davinci.name); | 386 | printk(err, clocksource_davinci.name); |
333 | 387 | ||
334 | /* setup clockevent */ | 388 | /* setup clockevent */ |
389 | clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; | ||
335 | clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, | 390 | clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, |
336 | clockevent_davinci.shift); | 391 | clockevent_davinci.shift); |
337 | clockevent_davinci.max_delta_ns = | 392 | clockevent_davinci.max_delta_ns = |
338 | clockevent_delta2ns(0xfffffffe, &clockevent_davinci); | 393 | clockevent_delta2ns(0xfffffffe, &clockevent_davinci); |
339 | clockevent_davinci.min_delta_ns = | 394 | clockevent_davinci.min_delta_ns = 50000; /* 50 usec */ |
340 | clockevent_delta2ns(1, &clockevent_davinci); | ||
341 | 395 | ||
342 | clockevent_davinci.cpumask = cpumask_of(0); | 396 | clockevent_davinci.cpumask = cpumask_of(0); |
343 | clockevents_register_device(&clockevent_davinci); | 397 | clockevents_register_device(&clockevent_davinci); |
@@ -349,15 +403,14 @@ struct sys_timer davinci_timer = { | |||
349 | 403 | ||
350 | 404 | ||
351 | /* reset board using watchdog timer */ | 405 | /* reset board using watchdog timer */ |
352 | void davinci_watchdog_reset(void) { | 406 | void davinci_watchdog_reset(void) |
407 | { | ||
353 | u32 tgcr, wdtcr; | 408 | u32 tgcr, wdtcr; |
354 | void __iomem *base = IO_ADDRESS(DAVINCI_WDOG_BASE); | 409 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
355 | struct device dev; | 410 | void __iomem *base = soc_info->wdt_base; |
356 | struct clk *wd_clk; | 411 | struct clk *wd_clk; |
357 | char *name = "watchdog"; | ||
358 | 412 | ||
359 | dev_set_name(&dev, name); | 413 | wd_clk = clk_get(&davinci_wdt_device.dev, NULL); |
360 | wd_clk = clk_get(&dev, NULL); | ||
361 | if (WARN_ON(IS_ERR(wd_clk))) | 414 | if (WARN_ON(IS_ERR(wd_clk))) |
362 | return; | 415 | return; |
363 | clk_enable(wd_clk); | 416 | clk_enable(wd_clk); |
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index e8ebeaea6c48..b2eede5531c8 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c | |||
@@ -21,15 +21,50 @@ | |||
21 | #include <asm/div64.h> | 21 | #include <asm/div64.h> |
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | 23 | ||
24 | |||
25 | /* | ||
26 | * The EP93xx has two external crystal oscillators. To generate the | ||
27 | * required high-frequency clocks, the processor uses two phase-locked- | ||
28 | * loops (PLLs) to multiply the incoming external clock signal to much | ||
29 | * higher frequencies that are then divided down by programmable dividers | ||
30 | * to produce the needed clocks. The PLLs operate independently of one | ||
31 | * another. | ||
32 | */ | ||
33 | #define EP93XX_EXT_CLK_RATE 14745600 | ||
34 | #define EP93XX_EXT_RTC_RATE 32768 | ||
35 | |||
36 | |||
24 | struct clk { | 37 | struct clk { |
25 | unsigned long rate; | 38 | unsigned long rate; |
26 | int users; | 39 | int users; |
40 | int sw_locked; | ||
27 | u32 enable_reg; | 41 | u32 enable_reg; |
28 | u32 enable_mask; | 42 | u32 enable_mask; |
43 | |||
44 | unsigned long (*get_rate)(struct clk *clk); | ||
29 | }; | 45 | }; |
30 | 46 | ||
31 | static struct clk clk_uart = { | 47 | |
32 | .rate = 14745600, | 48 | static unsigned long get_uart_rate(struct clk *clk); |
49 | |||
50 | |||
51 | static struct clk clk_uart1 = { | ||
52 | .sw_locked = 1, | ||
53 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | ||
54 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN, | ||
55 | .get_rate = get_uart_rate, | ||
56 | }; | ||
57 | static struct clk clk_uart2 = { | ||
58 | .sw_locked = 1, | ||
59 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | ||
60 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN, | ||
61 | .get_rate = get_uart_rate, | ||
62 | }; | ||
63 | static struct clk clk_uart3 = { | ||
64 | .sw_locked = 1, | ||
65 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | ||
66 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN, | ||
67 | .get_rate = get_uart_rate, | ||
33 | }; | 68 | }; |
34 | static struct clk clk_pll1; | 69 | static struct clk clk_pll1; |
35 | static struct clk clk_f; | 70 | static struct clk clk_f; |
@@ -95,9 +130,9 @@ static struct clk clk_m2m1 = { | |||
95 | { .dev_id = dev, .con_id = con, .clk = ck } | 130 | { .dev_id = dev, .con_id = con, .clk = ck } |
96 | 131 | ||
97 | static struct clk_lookup clocks[] = { | 132 | static struct clk_lookup clocks[] = { |
98 | INIT_CK("apb:uart1", NULL, &clk_uart), | 133 | INIT_CK("apb:uart1", NULL, &clk_uart1), |
99 | INIT_CK("apb:uart2", NULL, &clk_uart), | 134 | INIT_CK("apb:uart2", NULL, &clk_uart2), |
100 | INIT_CK("apb:uart3", NULL, &clk_uart), | 135 | INIT_CK("apb:uart3", NULL, &clk_uart3), |
101 | INIT_CK(NULL, "pll1", &clk_pll1), | 136 | INIT_CK(NULL, "pll1", &clk_pll1), |
102 | INIT_CK(NULL, "fclk", &clk_f), | 137 | INIT_CK(NULL, "fclk", &clk_f), |
103 | INIT_CK(NULL, "hclk", &clk_h), | 138 | INIT_CK(NULL, "hclk", &clk_h), |
@@ -125,6 +160,8 @@ int clk_enable(struct clk *clk) | |||
125 | u32 value; | 160 | u32 value; |
126 | 161 | ||
127 | value = __raw_readl(clk->enable_reg); | 162 | value = __raw_readl(clk->enable_reg); |
163 | if (clk->sw_locked) | ||
164 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
128 | __raw_writel(value | clk->enable_mask, clk->enable_reg); | 165 | __raw_writel(value | clk->enable_mask, clk->enable_reg); |
129 | } | 166 | } |
130 | 167 | ||
@@ -138,13 +175,29 @@ void clk_disable(struct clk *clk) | |||
138 | u32 value; | 175 | u32 value; |
139 | 176 | ||
140 | value = __raw_readl(clk->enable_reg); | 177 | value = __raw_readl(clk->enable_reg); |
178 | if (clk->sw_locked) | ||
179 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
141 | __raw_writel(value & ~clk->enable_mask, clk->enable_reg); | 180 | __raw_writel(value & ~clk->enable_mask, clk->enable_reg); |
142 | } | 181 | } |
143 | } | 182 | } |
144 | EXPORT_SYMBOL(clk_disable); | 183 | EXPORT_SYMBOL(clk_disable); |
145 | 184 | ||
185 | static unsigned long get_uart_rate(struct clk *clk) | ||
186 | { | ||
187 | u32 value; | ||
188 | |||
189 | value = __raw_readl(EP93XX_SYSCON_CLOCK_CONTROL); | ||
190 | if (value & EP93XX_SYSCON_CLOCK_UARTBAUD) | ||
191 | return EP93XX_EXT_CLK_RATE; | ||
192 | else | ||
193 | return EP93XX_EXT_CLK_RATE / 2; | ||
194 | } | ||
195 | |||
146 | unsigned long clk_get_rate(struct clk *clk) | 196 | unsigned long clk_get_rate(struct clk *clk) |
147 | { | 197 | { |
198 | if (clk->get_rate) | ||
199 | return clk->get_rate(clk); | ||
200 | |||
148 | return clk->rate; | 201 | return clk->rate; |
149 | } | 202 | } |
150 | EXPORT_SYMBOL(clk_get_rate); | 203 | EXPORT_SYMBOL(clk_get_rate); |
@@ -162,7 +215,7 @@ static unsigned long calc_pll_rate(u32 config_word) | |||
162 | unsigned long long rate; | 215 | unsigned long long rate; |
163 | int i; | 216 | int i; |
164 | 217 | ||
165 | rate = 14745600; | 218 | rate = EP93XX_EXT_CLK_RATE; |
166 | rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ | 219 | rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ |
167 | rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ | 220 | rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ |
168 | do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ | 221 | do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ |
@@ -195,7 +248,7 @@ static int __init ep93xx_clock_init(void) | |||
195 | 248 | ||
196 | value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); | 249 | value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); |
197 | if (!(value & 0x00800000)) { /* PLL1 bypassed? */ | 250 | if (!(value & 0x00800000)) { /* PLL1 bypassed? */ |
198 | clk_pll1.rate = 14745600; | 251 | clk_pll1.rate = EP93XX_EXT_CLK_RATE; |
199 | } else { | 252 | } else { |
200 | clk_pll1.rate = calc_pll_rate(value); | 253 | clk_pll1.rate = calc_pll_rate(value); |
201 | } | 254 | } |
@@ -206,7 +259,7 @@ static int __init ep93xx_clock_init(void) | |||
206 | 259 | ||
207 | value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); | 260 | value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); |
208 | if (!(value & 0x00080000)) { /* PLL2 bypassed? */ | 261 | if (!(value & 0x00080000)) { /* PLL2 bypassed? */ |
209 | clk_pll2.rate = 14745600; | 262 | clk_pll2.rate = EP93XX_EXT_CLK_RATE; |
210 | } else if (value & 0x00040000) { /* PLL2 enabled? */ | 263 | } else if (value & 0x00040000) { /* PLL2 enabled? */ |
211 | clk_pll2.rate = calc_pll_rate(value); | 264 | clk_pll2.rate = calc_pll_rate(value); |
212 | } else { | 265 | } else { |
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 78ac1bddc8bc..420f71b85123 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | |||
@@ -160,7 +160,10 @@ | |||
160 | #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) | 160 | #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) |
161 | #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) | 161 | #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) |
162 | #define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) | 162 | #define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) |
163 | #define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE 0x00800000 | 163 | #define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24) |
164 | #define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23) | ||
165 | #define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20) | ||
166 | #define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18) | ||
164 | #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) | 167 | #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) |
165 | 168 | ||
166 | #define EP93XX_WATCHDOG_BASE (EP93XX_APB_VIRT_BASE + 0x00140000) | 169 | #define EP93XX_WATCHDOG_BASE (EP93XX_APB_VIRT_BASE + 0x00140000) |
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 6f8872913073..a0f60e55da6a 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -121,7 +121,7 @@ static struct clk uartclk = { | |||
121 | .rate = 14745600, | 121 | .rate = 14745600, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | static struct clk_lookup lookups[] __initdata = { | 124 | static struct clk_lookup lookups[] = { |
125 | { /* UART0 */ | 125 | { /* UART0 */ |
126 | .dev_id = "mb:16", | 126 | .dev_id = "mb:16", |
127 | .clk = &uartclk, | 127 | .clk = &uartclk, |
diff --git a/arch/arm/mach-l7200/include/mach/sys-clock.h b/arch/arm/mach-l7200/include/mach/sys-clock.h index 2d7722be60ea..e9729a35751d 100644 --- a/arch/arm/mach-l7200/include/mach/sys-clock.h +++ b/arch/arm/mach-l7200/include/mach/sys-clock.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | /* IO_START and IO_BASE are defined in hardware.h */ | 19 | /* IO_START and IO_BASE are defined in hardware.h */ |
20 | 20 | ||
21 | #define SYS_CLOCK_START (IO_START + SYS_CLCOK_OFF) /* Physical address */ | 21 | #define SYS_CLOCK_START (IO_START + SYS_CLOCK_OFF) /* Physical address */ |
22 | #define SYS_CLOCK_BASE (IO_BASE + SYS_CLOCK_OFF) /* Virtual address */ | 22 | #define SYS_CLOCK_BASE (IO_BASE + SYS_CLOCK_OFF) /* Virtual address */ |
23 | 23 | ||
24 | /* Define the interface to the SYS_CLOCK */ | 24 | /* Define the interface to the SYS_CLOCK */ |
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index efc59c49341b..e4cef333e291 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c | |||
@@ -103,10 +103,10 @@ static struct omap_clk omap24xx_clks[] = { | |||
103 | CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), | 103 | CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), |
104 | CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), | 104 | CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), |
105 | /* DSS domain clocks */ | 105 | /* DSS domain clocks */ |
106 | CLK(NULL, "dss_ick", &dss_ick, CK_243X | CK_242X), | 106 | CLK("omapfb", "ick", &dss_ick, CK_243X | CK_242X), |
107 | CLK(NULL, "dss1_fck", &dss1_fck, CK_243X | CK_242X), | 107 | CLK("omapfb", "dss1_fck", &dss1_fck, CK_243X | CK_242X), |
108 | CLK(NULL, "dss2_fck", &dss2_fck, CK_243X | CK_242X), | 108 | CLK("omapfb", "dss2_fck", &dss2_fck, CK_243X | CK_242X), |
109 | CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X | CK_242X), | 109 | CLK("omapfb", "tv_fck", &dss_54m_fck, CK_243X | CK_242X), |
110 | /* L3 domain clocks */ | 110 | /* L3 domain clocks */ |
111 | CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X | CK_242X), | 111 | CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X | CK_242X), |
112 | CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X | CK_242X), | 112 | CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X | CK_242X), |
@@ -206,7 +206,7 @@ static struct omap_clk omap24xx_clks[] = { | |||
206 | CLK(NULL, "aes_ick", &aes_ick, CK_243X | CK_242X), | 206 | CLK(NULL, "aes_ick", &aes_ick, CK_243X | CK_242X), |
207 | CLK(NULL, "pka_ick", &pka_ick, CK_243X | CK_242X), | 207 | CLK(NULL, "pka_ick", &pka_ick, CK_243X | CK_242X), |
208 | CLK(NULL, "usb_fck", &usb_fck, CK_243X | CK_242X), | 208 | CLK(NULL, "usb_fck", &usb_fck, CK_243X | CK_242X), |
209 | CLK(NULL, "usbhs_ick", &usbhs_ick, CK_243X), | 209 | CLK("musb_hdrc", "ick", &usbhs_ick, CK_243X), |
210 | CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_243X), | 210 | CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_243X), |
211 | CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_243X), | 211 | CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_243X), |
212 | CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_243X), | 212 | CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_243X), |
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 0a14dca31e30..ba05aa42bd8e 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
@@ -157,7 +157,7 @@ static struct omap_clk omap34xx_clks[] = { | |||
157 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck, CK_343X), | 157 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck, CK_343X), |
158 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck, CK_343X), | 158 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck, CK_343X), |
159 | CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X), | 159 | CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X), |
160 | CLK(NULL, "hsotgusb_ick", &hsotgusb_ick, CK_343X), | 160 | CLK("musb_hdrc", "ick", &hsotgusb_ick, CK_343X), |
161 | CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X), | 161 | CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X), |
162 | CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X), | 162 | CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X), |
163 | CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X), | 163 | CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X), |
@@ -197,11 +197,11 @@ static struct omap_clk omap34xx_clks[] = { | |||
197 | CLK("omap_rng", "ick", &rng_ick, CK_343X), | 197 | CLK("omap_rng", "ick", &rng_ick, CK_343X), |
198 | CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), | 198 | CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), |
199 | CLK(NULL, "des1_ick", &des1_ick, CK_343X), | 199 | CLK(NULL, "des1_ick", &des1_ick, CK_343X), |
200 | CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck, CK_343X), | 200 | CLK("omapfb", "dss1_fck", &dss1_alwon_fck, CK_343X), |
201 | CLK(NULL, "dss_tv_fck", &dss_tv_fck, CK_343X), | 201 | CLK("omapfb", "tv_fck", &dss_tv_fck, CK_343X), |
202 | CLK(NULL, "dss_96m_fck", &dss_96m_fck, CK_343X), | 202 | CLK("omapfb", "video_fck", &dss_96m_fck, CK_343X), |
203 | CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck, CK_343X), | 203 | CLK("omapfb", "dss2_fck", &dss2_alwon_fck, CK_343X), |
204 | CLK(NULL, "dss_ick", &dss_ick, CK_343X), | 204 | CLK("omapfb", "ick", &dss_ick, CK_343X), |
205 | CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), | 205 | CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), |
206 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), | 206 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), |
207 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), | 207 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), |
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 6763b8f73028..017a30e9aa1d 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
@@ -2182,7 +2182,7 @@ static struct clk wkup_32k_fck = { | |||
2182 | 2182 | ||
2183 | static struct clk gpio1_dbck = { | 2183 | static struct clk gpio1_dbck = { |
2184 | .name = "gpio1_dbck", | 2184 | .name = "gpio1_dbck", |
2185 | .ops = &clkops_omap2_dflt_wait, | 2185 | .ops = &clkops_omap2_dflt, |
2186 | .parent = &wkup_32k_fck, | 2186 | .parent = &wkup_32k_fck, |
2187 | .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), | 2187 | .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), |
2188 | .enable_bit = OMAP3430_EN_GPIO1_SHIFT, | 2188 | .enable_bit = OMAP3430_EN_GPIO1_SHIFT, |
@@ -2427,7 +2427,7 @@ static struct clk per_32k_alwon_fck = { | |||
2427 | 2427 | ||
2428 | static struct clk gpio6_dbck = { | 2428 | static struct clk gpio6_dbck = { |
2429 | .name = "gpio6_dbck", | 2429 | .name = "gpio6_dbck", |
2430 | .ops = &clkops_omap2_dflt_wait, | 2430 | .ops = &clkops_omap2_dflt, |
2431 | .parent = &per_32k_alwon_fck, | 2431 | .parent = &per_32k_alwon_fck, |
2432 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2432 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2433 | .enable_bit = OMAP3430_EN_GPIO6_SHIFT, | 2433 | .enable_bit = OMAP3430_EN_GPIO6_SHIFT, |
@@ -2437,7 +2437,7 @@ static struct clk gpio6_dbck = { | |||
2437 | 2437 | ||
2438 | static struct clk gpio5_dbck = { | 2438 | static struct clk gpio5_dbck = { |
2439 | .name = "gpio5_dbck", | 2439 | .name = "gpio5_dbck", |
2440 | .ops = &clkops_omap2_dflt_wait, | 2440 | .ops = &clkops_omap2_dflt, |
2441 | .parent = &per_32k_alwon_fck, | 2441 | .parent = &per_32k_alwon_fck, |
2442 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2442 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2443 | .enable_bit = OMAP3430_EN_GPIO5_SHIFT, | 2443 | .enable_bit = OMAP3430_EN_GPIO5_SHIFT, |
@@ -2447,7 +2447,7 @@ static struct clk gpio5_dbck = { | |||
2447 | 2447 | ||
2448 | static struct clk gpio4_dbck = { | 2448 | static struct clk gpio4_dbck = { |
2449 | .name = "gpio4_dbck", | 2449 | .name = "gpio4_dbck", |
2450 | .ops = &clkops_omap2_dflt_wait, | 2450 | .ops = &clkops_omap2_dflt, |
2451 | .parent = &per_32k_alwon_fck, | 2451 | .parent = &per_32k_alwon_fck, |
2452 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2452 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2453 | .enable_bit = OMAP3430_EN_GPIO4_SHIFT, | 2453 | .enable_bit = OMAP3430_EN_GPIO4_SHIFT, |
@@ -2457,7 +2457,7 @@ static struct clk gpio4_dbck = { | |||
2457 | 2457 | ||
2458 | static struct clk gpio3_dbck = { | 2458 | static struct clk gpio3_dbck = { |
2459 | .name = "gpio3_dbck", | 2459 | .name = "gpio3_dbck", |
2460 | .ops = &clkops_omap2_dflt_wait, | 2460 | .ops = &clkops_omap2_dflt, |
2461 | .parent = &per_32k_alwon_fck, | 2461 | .parent = &per_32k_alwon_fck, |
2462 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2462 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2463 | .enable_bit = OMAP3430_EN_GPIO3_SHIFT, | 2463 | .enable_bit = OMAP3430_EN_GPIO3_SHIFT, |
@@ -2467,7 +2467,7 @@ static struct clk gpio3_dbck = { | |||
2467 | 2467 | ||
2468 | static struct clk gpio2_dbck = { | 2468 | static struct clk gpio2_dbck = { |
2469 | .name = "gpio2_dbck", | 2469 | .name = "gpio2_dbck", |
2470 | .ops = &clkops_omap2_dflt_wait, | 2470 | .ops = &clkops_omap2_dflt, |
2471 | .parent = &per_32k_alwon_fck, | 2471 | .parent = &per_32k_alwon_fck, |
2472 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2472 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2473 | .enable_bit = OMAP3430_EN_GPIO2_SHIFT, | 2473 | .enable_bit = OMAP3430_EN_GPIO2_SHIFT, |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 496983ade97e..894cc355818a 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -354,10 +354,12 @@ static void omap_init_mcspi(void) | |||
354 | platform_device_register(&omap2_mcspi1); | 354 | platform_device_register(&omap2_mcspi1); |
355 | platform_device_register(&omap2_mcspi2); | 355 | platform_device_register(&omap2_mcspi2); |
356 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | 356 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) |
357 | platform_device_register(&omap2_mcspi3); | 357 | if (cpu_is_omap2430() || cpu_is_omap343x()) |
358 | platform_device_register(&omap2_mcspi3); | ||
358 | #endif | 359 | #endif |
359 | #ifdef CONFIG_ARCH_OMAP3 | 360 | #ifdef CONFIG_ARCH_OMAP3 |
360 | platform_device_register(&omap2_mcspi4); | 361 | if (cpu_is_omap343x()) |
362 | platform_device_register(&omap2_mcspi4); | ||
361 | #endif | 363 | #endif |
362 | } | 364 | } |
363 | 365 | ||
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index c6a7940f4287..9fd03a2ec95c 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h | |||
@@ -409,7 +409,7 @@ | |||
409 | /* PM_PREPWSTST_CAM specific bits */ | 409 | /* PM_PREPWSTST_CAM specific bits */ |
410 | 410 | ||
411 | /* PM_PWSTCTRL_USBHOST specific bits */ | 411 | /* PM_PWSTCTRL_USBHOST specific bits */ |
412 | #define OMAP3430ES2_SAVEANDRESTORE_SHIFT (1 << 4) | 412 | #define OMAP3430ES2_SAVEANDRESTORE_SHIFT 4 |
413 | 413 | ||
414 | /* RM_RSTST_PER specific bits */ | 414 | /* RM_RSTST_PER specific bits */ |
415 | 415 | ||
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index 8df55f40f4c0..8622c24cd270 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c | |||
@@ -187,7 +187,7 @@ int tusb6010_platform_retime(unsigned is_refclk) | |||
187 | unsigned sysclk_ps; | 187 | unsigned sysclk_ps; |
188 | int status; | 188 | int status; |
189 | 189 | ||
190 | if (!refclk_psec || sysclk_ps == 0) | 190 | if (!refclk_psec || fclk_ps == 0) |
191 | return -ENODEV; | 191 | return -ENODEV; |
192 | 192 | ||
193 | sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60; | 193 | sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60; |
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 0e65344e9f53..dd031cc41847 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <mach/audio.h> | 46 | #include <mach/audio.h> |
47 | #include <mach/pxafb.h> | 47 | #include <mach/pxafb.h> |
48 | #include <mach/i2c.h> | 48 | #include <mach/i2c.h> |
49 | #include <mach/regs-uart.h> | ||
49 | #include <mach/viper.h> | 50 | #include <mach/viper.h> |
50 | 51 | ||
51 | #include <asm/setup.h> | 52 | #include <asm/setup.h> |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 942e1a7eb9b2..076acbc50706 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -750,14 +750,6 @@ void __init realview_timer_init(unsigned int timer_irq) | |||
750 | { | 750 | { |
751 | u32 val; | 751 | u32 val; |
752 | 752 | ||
753 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | ||
754 | /* | ||
755 | * The dummy clock device has to be registered before the main device | ||
756 | * so that the latter will broadcast the clock events | ||
757 | */ | ||
758 | local_timer_setup(); | ||
759 | #endif | ||
760 | |||
761 | /* | 753 | /* |
762 | * set clock frequency: | 754 | * set clock frequency: |
763 | * REALVIEW_REFCLK is 32KHz | 755 | * REALVIEW_REFCLK is 32KHz |
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h index 515819efd046..dd53892d44a7 100644 --- a/arch/arm/mach-realview/include/mach/smp.h +++ b/arch/arm/mach-realview/include/mach/smp.h | |||
@@ -15,16 +15,9 @@ | |||
15 | /* | 15 | /* |
16 | * We use IRQ1 as the IPI | 16 | * We use IRQ1 as the IPI |
17 | */ | 17 | */ |
18 | static inline void smp_cross_call(cpumask_t callmap) | 18 | static inline void smp_cross_call(const struct cpumask *mask) |
19 | { | ||
20 | gic_raise_softirq(callmap, 1); | ||
21 | } | ||
22 | |||
23 | /* | ||
24 | * Do nothing on MPcore. | ||
25 | */ | ||
26 | static inline void smp_cross_call_done(cpumask_t callmap) | ||
27 | { | 19 | { |
20 | gic_raise_softirq(mask, 1); | ||
28 | } | 21 | } |
29 | 22 | ||
30 | #endif | 23 | #endif |
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c index d0d39adf6407..1c01d13460f0 100644 --- a/arch/arm/mach-realview/localtimer.c +++ b/arch/arm/mach-realview/localtimer.c | |||
@@ -189,8 +189,10 @@ void __cpuinit local_timer_setup(void) | |||
189 | struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); | 189 | struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); |
190 | 190 | ||
191 | clk->name = "dummy_timer"; | 191 | clk->name = "dummy_timer"; |
192 | clk->features = CLOCK_EVT_FEAT_DUMMY; | 192 | clk->features = CLOCK_EVT_FEAT_ONESHOT | |
193 | clk->rating = 200; | 193 | CLOCK_EVT_FEAT_PERIODIC | |
194 | CLOCK_EVT_FEAT_DUMMY; | ||
195 | clk->rating = 400; | ||
194 | clk->mult = 1; | 196 | clk->mult = 1; |
195 | clk->set_mode = dummy_timer_set_mode; | 197 | clk->set_mode = dummy_timer_set_mode; |
196 | clk->broadcast = smp_timer_broadcast; | 198 | clk->broadcast = smp_timer_broadcast; |
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index ea3c75595fa9..30a9c68591f6 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c | |||
@@ -78,13 +78,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu) | |||
78 | trace_hardirqs_off(); | 78 | trace_hardirqs_off(); |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * the primary core may have used a "cross call" soft interrupt | ||
82 | * to get this processor out of WFI in the BootMonitor - make | ||
83 | * sure that we are no longer being sent this soft interrupt | ||
84 | */ | ||
85 | smp_cross_call_done(cpumask_of_cpu(cpu)); | ||
86 | |||
87 | /* | ||
88 | * if any interrupts are already enabled for the primary | 81 | * if any interrupts are already enabled for the primary |
89 | * core (e.g. timer irq), then they will not have been enabled | 82 | * core (e.g. timer irq), then they will not have been enabled |
90 | * for us: do so | 83 | * for us: do so |
@@ -136,7 +129,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
136 | * Use smp_cross_call() for this, since there's little | 129 | * Use smp_cross_call() for this, since there's little |
137 | * point duplicating the code here | 130 | * point duplicating the code here |
138 | */ | 131 | */ |
139 | smp_cross_call(cpumask_of_cpu(cpu)); | 132 | smp_cross_call(cpumask_of(cpu)); |
140 | 133 | ||
141 | timeout = jiffies + (1 * HZ); | 134 | timeout = jiffies + (1 * HZ); |
142 | while (time_before(jiffies, timeout)) { | 135 | while (time_before(jiffies, timeout)) { |
@@ -224,11 +217,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
224 | if (max_cpus > ncores) | 217 | if (max_cpus > ncores) |
225 | max_cpus = ncores; | 218 | max_cpus = ncores; |
226 | 219 | ||
227 | #ifdef CONFIG_LOCAL_TIMERS | 220 | #if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) |
228 | /* | 221 | /* |
229 | * Enable the local timer for primary CPU. If the device is | 222 | * Enable the local timer or broadcast device for the boot CPU. |
230 | * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in | ||
231 | * realview_timer_init | ||
232 | */ | 223 | */ |
233 | local_timer_setup(); | 224 | local_timer_setup(); |
234 | #endif | 225 | #endif |
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 4389c160f7d0..8637dea5e150 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
@@ -588,8 +588,6 @@ static void __init bast_map_io(void) | |||
588 | 588 | ||
589 | s3c_device_nand.dev.platform_data = &bast_nand_info; | 589 | s3c_device_nand.dev.platform_data = &bast_nand_info; |
590 | 590 | ||
591 | s3c_i2c0_set_platdata(&bast_i2c_info); | ||
592 | |||
593 | s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); | 591 | s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); |
594 | s3c24xx_init_clocks(0); | 592 | s3c24xx_init_clocks(0); |
595 | s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); | 593 | s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); |
@@ -602,6 +600,7 @@ static void __init bast_init(void) | |||
602 | sysdev_class_register(&bast_pm_sysclass); | 600 | sysdev_class_register(&bast_pm_sysclass); |
603 | sysdev_register(&bast_pm_sysdev); | 601 | sysdev_register(&bast_pm_sysdev); |
604 | 602 | ||
603 | s3c_i2c0_set_platdata(&bast_i2c_info); | ||
605 | s3c24xx_fb_set_platdata(&bast_fb_info); | 604 | s3c24xx_fb_set_platdata(&bast_fb_info); |
606 | platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); | 605 | platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); |
607 | 606 | ||
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 1f929c391af7..b3bebcc5623b 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -413,7 +413,7 @@ static struct clk ref24_clk = { | |||
413 | .rate = 24000000, | 413 | .rate = 24000000, |
414 | }; | 414 | }; |
415 | 415 | ||
416 | static struct clk_lookup lookups[] __initdata = { | 416 | static struct clk_lookup lookups[] = { |
417 | { /* UART0 */ | 417 | { /* UART0 */ |
418 | .dev_id = "dev:f1", | 418 | .dev_id = "dev:f1", |
419 | .clk = &ref24_clk, | 419 | .clk = &ref24_clk, |
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h index 386cbd13eaf4..d3a6f9298e9e 100644 --- a/arch/arm/nwfpe/fpa11.h +++ b/arch/arm/nwfpe/fpa11.h | |||
@@ -114,4 +114,8 @@ extern unsigned int SingleCPDO(struct roundingData *roundData, | |||
114 | extern unsigned int DoubleCPDO(struct roundingData *roundData, | 114 | extern unsigned int DoubleCPDO(struct roundingData *roundData, |
115 | const unsigned int opcode, FPREG * rFd); | 115 | const unsigned int opcode, FPREG * rFd); |
116 | 116 | ||
117 | /* extneded_cpdo.c */ | ||
118 | extern unsigned int ExtendedCPDO(struct roundingData *roundData, | ||
119 | const unsigned int opcode, FPREG * rFd); | ||
120 | |||
117 | #endif | 121 | #endif |
diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c index 9843dc533047..31c4eeec18b0 100644 --- a/arch/arm/nwfpe/fpa11_cprt.c +++ b/arch/arm/nwfpe/fpa11_cprt.c | |||
@@ -27,10 +27,6 @@ | |||
27 | #include "fpmodule.inl" | 27 | #include "fpmodule.inl" |
28 | #include "softfloat.h" | 28 | #include "softfloat.h" |
29 | 29 | ||
30 | #ifdef CONFIG_FPE_NWFPE_XP | ||
31 | extern flag floatx80_is_nan(floatx80); | ||
32 | #endif | ||
33 | |||
34 | unsigned int PerformFLT(const unsigned int opcode); | 30 | unsigned int PerformFLT(const unsigned int opcode); |
35 | unsigned int PerformFIX(const unsigned int opcode); | 31 | unsigned int PerformFIX(const unsigned int opcode); |
36 | 32 | ||
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h index 260fe29d73f5..13e479c5da57 100644 --- a/arch/arm/nwfpe/softfloat.h +++ b/arch/arm/nwfpe/softfloat.h | |||
@@ -226,6 +226,8 @@ char floatx80_le_quiet( floatx80, floatx80 ); | |||
226 | char floatx80_lt_quiet( floatx80, floatx80 ); | 226 | char floatx80_lt_quiet( floatx80, floatx80 ); |
227 | char floatx80_is_signaling_nan( floatx80 ); | 227 | char floatx80_is_signaling_nan( floatx80 ); |
228 | 228 | ||
229 | extern flag floatx80_is_nan(floatx80); | ||
230 | |||
229 | #endif | 231 | #endif |
230 | 232 | ||
231 | static inline flag extractFloat32Sign(float32 a) | 233 | static inline flag extractFloat32Sign(float32 a) |
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index ce6b4baeedec..3746222bed10 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c | |||
@@ -206,9 +206,10 @@ void __init omapfb_reserve_sdram(void) | |||
206 | config_invalid = 1; | 206 | config_invalid = 1; |
207 | return; | 207 | return; |
208 | } | 208 | } |
209 | if (rg.paddr) | 209 | if (rg.paddr) { |
210 | reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT); | 210 | reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT); |
211 | reserved += rg.size; | 211 | reserved += rg.size; |
212 | } | ||
212 | omapfb_config.mem_desc.region[i] = rg; | 213 | omapfb_config.mem_desc.region[i] = rg; |
213 | configured_regions++; | 214 | configured_regions++; |
214 | } | 215 | } |
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 17d7afe42b83..ee0b21f5b094 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -307,7 +307,7 @@ static inline int gpio_valid(int gpio) | |||
307 | return 0; | 307 | return 0; |
308 | if (cpu_is_omap24xx() && gpio < 128) | 308 | if (cpu_is_omap24xx() && gpio < 128) |
309 | return 0; | 309 | return 0; |
310 | if (cpu_is_omap34xx() && gpio < 160) | 310 | if (cpu_is_omap34xx() && gpio < 192) |
311 | return 0; | 311 | return 0; |
312 | return -1; | 312 | return -1; |
313 | } | 313 | } |
diff --git a/arch/arm/plat-s3c/clock.c b/arch/arm/plat-s3c/clock.c index b6be76e2fe51..4d01ef1a25dd 100644 --- a/arch/arm/plat-s3c/clock.c +++ b/arch/arm/plat-s3c/clock.c | |||
@@ -306,8 +306,6 @@ struct clk s3c24xx_uclk = { | |||
306 | 306 | ||
307 | int s3c24xx_register_clock(struct clk *clk) | 307 | int s3c24xx_register_clock(struct clk *clk) |
308 | { | 308 | { |
309 | clk->owner = THIS_MODULE; | ||
310 | |||
311 | if (clk->enable == NULL) | 309 | if (clk->enable == NULL) |
312 | clk->enable = clk_null_enable; | 310 | clk->enable = clk_null_enable; |
313 | 311 | ||
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index aee2aeb46c60..07326f632361 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c | |||
@@ -1235,7 +1235,7 @@ int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *d | |||
1235 | 1235 | ||
1236 | EXPORT_SYMBOL(s3c2410_dma_getposition); | 1236 | EXPORT_SYMBOL(s3c2410_dma_getposition); |
1237 | 1237 | ||
1238 | static struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev) | 1238 | static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev) |
1239 | { | 1239 | { |
1240 | return container_of(dev, struct s3c2410_dma_chan, dev); | 1240 | return container_of(dev, struct s3c2410_dma_chan, dev); |
1241 | } | 1241 | } |
diff --git a/arch/arm/plat-s3c64xx/gpiolib.c b/arch/arm/plat-s3c64xx/gpiolib.c index ee9188add8fb..78ee52cffc9e 100644 --- a/arch/arm/plat-s3c64xx/gpiolib.c +++ b/arch/arm/plat-s3c64xx/gpiolib.c | |||
@@ -57,7 +57,7 @@ | |||
57 | #if 1 | 57 | #if 1 |
58 | #define gpio_dbg(x...) do { } while(0) | 58 | #define gpio_dbg(x...) do { } while(0) |
59 | #else | 59 | #else |
60 | #define gpio_dbg(x...) printk(KERN_DEBUG ## x) | 60 | #define gpio_dbg(x...) printk(KERN_DEBUG x) |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | /* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where | 63 | /* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where |
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h index 81549516572f..2ba1767512d7 100644 --- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h +++ b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h | |||
@@ -61,14 +61,14 @@ | |||
61 | #define S3C64XX_GPH7_ADDR_CF1 (0x06 << 28) | 61 | #define S3C64XX_GPH7_ADDR_CF1 (0x06 << 28) |
62 | #define S3C64XX_GPH7_EINT_G6_7 (0x07 << 28) | 62 | #define S3C64XX_GPH7_EINT_G6_7 (0x07 << 28) |
63 | 63 | ||
64 | #define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 32) | 64 | #define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 0) |
65 | #define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 32) | 65 | #define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 0) |
66 | #define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 32) | 66 | #define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 0) |
67 | #define S3C64XX_GPH8_ADDR_CF2 (0x06 << 32) | 67 | #define S3C64XX_GPH8_ADDR_CF2 (0x06 << 0) |
68 | #define S3C64XX_GPH8_EINT_G6_8 (0x07 << 32) | 68 | #define S3C64XX_GPH8_EINT_G6_8 (0x07 << 0) |
69 | |||
70 | #define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 36) | ||
71 | #define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 36) | ||
72 | #define S3C64XX_GPH9_I2S_V40_DI (0x05 << 36) | ||
73 | #define S3C64XX_GPH9_EINT_G6_9 (0x07 << 36) | ||
74 | 69 | ||
70 | #define S3C64XX_GPH9_OUTPUT (0x01 << 4) | ||
71 | #define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 4) | ||
72 | #define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 4) | ||
73 | #define S3C64XX_GPH9_I2S_V40_DI (0x05 << 4) | ||
74 | #define S3C64XX_GPH9_EINT_G6_9 (0x07 << 4) | ||
diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig index beb7ecd72793..4ef6af0a8f31 100644 --- a/arch/microblaze/configs/nommu_defconfig +++ b/arch/microblaze/configs/nommu_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.29 | 3 | # Linux kernel version: 2.6.30-rc5 |
4 | # Tue Mar 24 10:23:20 2009 | 4 | # Mon May 11 09:01:02 2009 |
5 | # | 5 | # |
6 | CONFIG_MICROBLAZE=y | 6 | CONFIG_MICROBLAZE=y |
7 | # CONFIG_SWAP is not set | 7 | # CONFIG_SWAP is not set |
@@ -32,6 +32,7 @@ CONFIG_LOCALVERSION_AUTO=y | |||
32 | CONFIG_SYSVIPC=y | 32 | CONFIG_SYSVIPC=y |
33 | CONFIG_SYSVIPC_SYSCTL=y | 33 | CONFIG_SYSVIPC_SYSCTL=y |
34 | CONFIG_POSIX_MQUEUE=y | 34 | CONFIG_POSIX_MQUEUE=y |
35 | CONFIG_POSIX_MQUEUE_SYSCTL=y | ||
35 | CONFIG_BSD_PROCESS_ACCT=y | 36 | CONFIG_BSD_PROCESS_ACCT=y |
36 | CONFIG_BSD_PROCESS_ACCT_V3=y | 37 | CONFIG_BSD_PROCESS_ACCT_V3=y |
37 | # CONFIG_TASKSTATS is not set | 38 | # CONFIG_TASKSTATS is not set |
@@ -63,6 +64,7 @@ CONFIG_SYSCTL_SYSCALL=y | |||
63 | CONFIG_KALLSYMS=y | 64 | CONFIG_KALLSYMS=y |
64 | CONFIG_KALLSYMS_ALL=y | 65 | CONFIG_KALLSYMS_ALL=y |
65 | CONFIG_KALLSYMS_EXTRA_PASS=y | 66 | CONFIG_KALLSYMS_EXTRA_PASS=y |
67 | # CONFIG_STRIP_ASM_SYMS is not set | ||
66 | # CONFIG_HOTPLUG is not set | 68 | # CONFIG_HOTPLUG is not set |
67 | CONFIG_PRINTK=y | 69 | CONFIG_PRINTK=y |
68 | CONFIG_BUG=y | 70 | CONFIG_BUG=y |
@@ -80,6 +82,8 @@ CONFIG_SLAB=y | |||
80 | # CONFIG_SLUB is not set | 82 | # CONFIG_SLUB is not set |
81 | # CONFIG_SLOB is not set | 83 | # CONFIG_SLOB is not set |
82 | # CONFIG_PROFILING is not set | 84 | # CONFIG_PROFILING is not set |
85 | # CONFIG_MARKERS is not set | ||
86 | # CONFIG_SLOW_WORK is not set | ||
83 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | 87 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set |
84 | CONFIG_SLABINFO=y | 88 | CONFIG_SLABINFO=y |
85 | CONFIG_RT_MUTEXES=y | 89 | CONFIG_RT_MUTEXES=y |
@@ -92,7 +96,6 @@ CONFIG_MODULE_UNLOAD=y | |||
92 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 96 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
93 | CONFIG_BLOCK=y | 97 | CONFIG_BLOCK=y |
94 | # CONFIG_LBD is not set | 98 | # CONFIG_LBD is not set |
95 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
96 | # CONFIG_BLK_DEV_BSG is not set | 99 | # CONFIG_BLK_DEV_BSG is not set |
97 | # CONFIG_BLK_DEV_INTEGRITY is not set | 100 | # CONFIG_BLK_DEV_INTEGRITY is not set |
98 | 101 | ||
@@ -166,6 +169,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 | |||
166 | # CONFIG_PHYS_ADDR_T_64BIT is not set | 169 | # CONFIG_PHYS_ADDR_T_64BIT is not set |
167 | CONFIG_ZONE_DMA_FLAG=0 | 170 | CONFIG_ZONE_DMA_FLAG=0 |
168 | CONFIG_VIRT_TO_BUS=y | 171 | CONFIG_VIRT_TO_BUS=y |
172 | CONFIG_UNEVICTABLE_LRU=y | ||
173 | CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 | ||
169 | 174 | ||
170 | # | 175 | # |
171 | # Exectuable file formats | 176 | # Exectuable file formats |
@@ -180,7 +185,6 @@ CONFIG_NET=y | |||
180 | # | 185 | # |
181 | # Networking options | 186 | # Networking options |
182 | # | 187 | # |
183 | CONFIG_COMPAT_NET_DEV_OPS=y | ||
184 | CONFIG_PACKET=y | 188 | CONFIG_PACKET=y |
185 | # CONFIG_PACKET_MMAP is not set | 189 | # CONFIG_PACKET_MMAP is not set |
186 | CONFIG_UNIX=y | 190 | CONFIG_UNIX=y |
@@ -232,6 +236,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" | |||
232 | # CONFIG_LAPB is not set | 236 | # CONFIG_LAPB is not set |
233 | # CONFIG_ECONET is not set | 237 | # CONFIG_ECONET is not set |
234 | # CONFIG_WAN_ROUTER is not set | 238 | # CONFIG_WAN_ROUTER is not set |
239 | # CONFIG_PHONET is not set | ||
235 | # CONFIG_NET_SCHED is not set | 240 | # CONFIG_NET_SCHED is not set |
236 | # CONFIG_DCB is not set | 241 | # CONFIG_DCB is not set |
237 | 242 | ||
@@ -244,7 +249,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" | |||
244 | # CONFIG_IRDA is not set | 249 | # CONFIG_IRDA is not set |
245 | # CONFIG_BT is not set | 250 | # CONFIG_BT is not set |
246 | # CONFIG_AF_RXRPC is not set | 251 | # CONFIG_AF_RXRPC is not set |
247 | # CONFIG_PHONET is not set | ||
248 | CONFIG_WIRELESS=y | 252 | CONFIG_WIRELESS=y |
249 | # CONFIG_CFG80211 is not set | 253 | # CONFIG_CFG80211 is not set |
250 | CONFIG_WIRELESS_OLD_REGULATORY=y | 254 | CONFIG_WIRELESS_OLD_REGULATORY=y |
@@ -379,6 +383,7 @@ CONFIG_MISC_DEVICES=y | |||
379 | # CONFIG_ATA is not set | 383 | # CONFIG_ATA is not set |
380 | # CONFIG_MD is not set | 384 | # CONFIG_MD is not set |
381 | CONFIG_NETDEVICES=y | 385 | CONFIG_NETDEVICES=y |
386 | CONFIG_COMPAT_NET_DEV_OPS=y | ||
382 | # CONFIG_DUMMY is not set | 387 | # CONFIG_DUMMY is not set |
383 | # CONFIG_BONDING is not set | 388 | # CONFIG_BONDING is not set |
384 | # CONFIG_MACVLAN is not set | 389 | # CONFIG_MACVLAN is not set |
@@ -388,6 +393,7 @@ CONFIG_NETDEVICES=y | |||
388 | # CONFIG_PHYLIB is not set | 393 | # CONFIG_PHYLIB is not set |
389 | CONFIG_NET_ETHERNET=y | 394 | CONFIG_NET_ETHERNET=y |
390 | # CONFIG_MII is not set | 395 | # CONFIG_MII is not set |
396 | # CONFIG_ETHOC is not set | ||
391 | # CONFIG_DNET is not set | 397 | # CONFIG_DNET is not set |
392 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | 398 | # CONFIG_IBM_NEW_EMAC_ZMII is not set |
393 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | 399 | # CONFIG_IBM_NEW_EMAC_RGMII is not set |
@@ -405,7 +411,6 @@ CONFIG_NETDEV_10000=y | |||
405 | # | 411 | # |
406 | # CONFIG_WLAN_PRE80211 is not set | 412 | # CONFIG_WLAN_PRE80211 is not set |
407 | # CONFIG_WLAN_80211 is not set | 413 | # CONFIG_WLAN_80211 is not set |
408 | # CONFIG_IWLWIFI_LEDS is not set | ||
409 | 414 | ||
410 | # | 415 | # |
411 | # Enable WiMAX (Networking options) to see the WiMAX drivers | 416 | # Enable WiMAX (Networking options) to see the WiMAX drivers |
@@ -455,6 +460,7 @@ CONFIG_LEGACY_PTYS=y | |||
455 | CONFIG_LEGACY_PTY_COUNT=256 | 460 | CONFIG_LEGACY_PTY_COUNT=256 |
456 | # CONFIG_IPMI_HANDLER is not set | 461 | # CONFIG_IPMI_HANDLER is not set |
457 | CONFIG_HW_RANDOM=y | 462 | CONFIG_HW_RANDOM=y |
463 | # CONFIG_HW_RANDOM_TIMERIOMEM is not set | ||
458 | # CONFIG_RTC is not set | 464 | # CONFIG_RTC is not set |
459 | # CONFIG_GEN_RTC is not set | 465 | # CONFIG_GEN_RTC is not set |
460 | # CONFIG_R3964 is not set | 466 | # CONFIG_R3964 is not set |
@@ -525,7 +531,7 @@ CONFIG_USB_SUPPORT=y | |||
525 | # | 531 | # |
526 | 532 | ||
527 | # | 533 | # |
528 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; | 534 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may |
529 | # | 535 | # |
530 | # CONFIG_USB_GADGET is not set | 536 | # CONFIG_USB_GADGET is not set |
531 | 537 | ||
@@ -538,6 +544,7 @@ CONFIG_USB_SUPPORT=y | |||
538 | # CONFIG_ACCESSIBILITY is not set | 544 | # CONFIG_ACCESSIBILITY is not set |
539 | # CONFIG_RTC_CLASS is not set | 545 | # CONFIG_RTC_CLASS is not set |
540 | # CONFIG_DMADEVICES is not set | 546 | # CONFIG_DMADEVICES is not set |
547 | # CONFIG_AUXDISPLAY is not set | ||
541 | # CONFIG_UIO is not set | 548 | # CONFIG_UIO is not set |
542 | # CONFIG_STAGING is not set | 549 | # CONFIG_STAGING is not set |
543 | 550 | ||
@@ -563,6 +570,11 @@ CONFIG_FILE_LOCKING=y | |||
563 | # CONFIG_FUSE_FS is not set | 570 | # CONFIG_FUSE_FS is not set |
564 | 571 | ||
565 | # | 572 | # |
573 | # Caches | ||
574 | # | ||
575 | # CONFIG_FSCACHE is not set | ||
576 | |||
577 | # | ||
566 | # CD-ROM/DVD Filesystems | 578 | # CD-ROM/DVD Filesystems |
567 | # | 579 | # |
568 | # CONFIG_ISO9660_FS is not set | 580 | # CONFIG_ISO9660_FS is not set |
@@ -601,8 +613,13 @@ CONFIG_CRAMFS=y | |||
601 | # CONFIG_HPFS_FS is not set | 613 | # CONFIG_HPFS_FS is not set |
602 | # CONFIG_QNX4FS_FS is not set | 614 | # CONFIG_QNX4FS_FS is not set |
603 | CONFIG_ROMFS_FS=y | 615 | CONFIG_ROMFS_FS=y |
616 | CONFIG_ROMFS_BACKED_BY_BLOCK=y | ||
617 | # CONFIG_ROMFS_BACKED_BY_MTD is not set | ||
618 | # CONFIG_ROMFS_BACKED_BY_BOTH is not set | ||
619 | CONFIG_ROMFS_ON_BLOCK=y | ||
604 | # CONFIG_SYSV_FS is not set | 620 | # CONFIG_SYSV_FS is not set |
605 | # CONFIG_UFS_FS is not set | 621 | # CONFIG_UFS_FS is not set |
622 | # CONFIG_NILFS2_FS is not set | ||
606 | CONFIG_NETWORK_FILESYSTEMS=y | 623 | CONFIG_NETWORK_FILESYSTEMS=y |
607 | CONFIG_NFS_FS=y | 624 | CONFIG_NFS_FS=y |
608 | CONFIG_NFS_V3=y | 625 | CONFIG_NFS_V3=y |
@@ -614,7 +631,6 @@ CONFIG_LOCKD_V4=y | |||
614 | CONFIG_NFS_ACL_SUPPORT=y | 631 | CONFIG_NFS_ACL_SUPPORT=y |
615 | CONFIG_NFS_COMMON=y | 632 | CONFIG_NFS_COMMON=y |
616 | CONFIG_SUNRPC=y | 633 | CONFIG_SUNRPC=y |
617 | # CONFIG_SUNRPC_REGISTER_V4 is not set | ||
618 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 634 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
619 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 635 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
620 | # CONFIG_SMB_FS is not set | 636 | # CONFIG_SMB_FS is not set |
@@ -647,6 +663,9 @@ CONFIG_DEBUG_SHIRQ=y | |||
647 | CONFIG_DETECT_SOFTLOCKUP=y | 663 | CONFIG_DETECT_SOFTLOCKUP=y |
648 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y | 664 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y |
649 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 | 665 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 |
666 | CONFIG_DETECT_HUNG_TASK=y | ||
667 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
668 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
650 | CONFIG_SCHED_DEBUG=y | 669 | CONFIG_SCHED_DEBUG=y |
651 | CONFIG_SCHEDSTATS=y | 670 | CONFIG_SCHEDSTATS=y |
652 | CONFIG_TIMER_STATS=y | 671 | CONFIG_TIMER_STATS=y |
@@ -678,15 +697,8 @@ CONFIG_DEBUG_SG=y | |||
678 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | 697 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set |
679 | # CONFIG_FAULT_INJECTION is not set | 698 | # CONFIG_FAULT_INJECTION is not set |
680 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 699 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
681 | 700 | # CONFIG_PAGE_POISONING is not set | |
682 | # | 701 | # CONFIG_DYNAMIC_DEBUG is not set |
683 | # Tracers | ||
684 | # | ||
685 | # CONFIG_SCHED_TRACER is not set | ||
686 | # CONFIG_CONTEXT_SWITCH_TRACER is not set | ||
687 | # CONFIG_BOOT_TRACER is not set | ||
688 | # CONFIG_TRACE_BRANCH_PROFILING is not set | ||
689 | # CONFIG_DYNAMIC_PRINTK_DEBUG is not set | ||
690 | # CONFIG_SAMPLES is not set | 702 | # CONFIG_SAMPLES is not set |
691 | CONFIG_EARLY_PRINTK=y | 703 | CONFIG_EARLY_PRINTK=y |
692 | CONFIG_HEART_BEAT=y | 704 | CONFIG_HEART_BEAT=y |
@@ -777,6 +789,7 @@ CONFIG_CRYPTO=y | |||
777 | # Compression | 789 | # Compression |
778 | # | 790 | # |
779 | # CONFIG_CRYPTO_DEFLATE is not set | 791 | # CONFIG_CRYPTO_DEFLATE is not set |
792 | # CONFIG_CRYPTO_ZLIB is not set | ||
780 | # CONFIG_CRYPTO_LZO is not set | 793 | # CONFIG_CRYPTO_LZO is not set |
781 | 794 | ||
782 | # | 795 | # |
@@ -784,6 +797,7 @@ CONFIG_CRYPTO=y | |||
784 | # | 797 | # |
785 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 798 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
786 | CONFIG_CRYPTO_HW=y | 799 | CONFIG_CRYPTO_HW=y |
800 | # CONFIG_BINARY_PRINTF is not set | ||
787 | 801 | ||
788 | # | 802 | # |
789 | # Library routines | 803 | # Library routines |
@@ -797,8 +811,8 @@ CONFIG_GENERIC_FIND_LAST_BIT=y | |||
797 | # CONFIG_CRC7 is not set | 811 | # CONFIG_CRC7 is not set |
798 | # CONFIG_LIBCRC32C is not set | 812 | # CONFIG_LIBCRC32C is not set |
799 | CONFIG_ZLIB_INFLATE=y | 813 | CONFIG_ZLIB_INFLATE=y |
800 | CONFIG_PLIST=y | ||
801 | CONFIG_HAS_IOMEM=y | 814 | CONFIG_HAS_IOMEM=y |
802 | CONFIG_HAS_IOPORT=y | 815 | CONFIG_HAS_IOPORT=y |
803 | CONFIG_HAS_DMA=y | 816 | CONFIG_HAS_DMA=y |
804 | CONFIG_HAVE_LMB=y | 817 | CONFIG_HAVE_LMB=y |
818 | CONFIG_NLATTR=y | ||
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index a69d3e3c2fd4..b15605299a57 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c | |||
@@ -137,8 +137,8 @@ void __init init_IRQ(void) | |||
137 | 137 | ||
138 | intr_type = | 138 | intr_type = |
139 | *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); | 139 | *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); |
140 | if (intr_type >= (1 << nr_irq)) | 140 | if (intr_type >= (1 << (nr_irq + 1))) |
141 | printk(KERN_INFO " ERROR: Mishmash in king-of-intr param\n"); | 141 | printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); |
142 | 142 | ||
143 | #ifdef CONFIG_SELFMOD_INTC | 143 | #ifdef CONFIG_SELFMOD_INTC |
144 | selfmod_function((int *) arr_func, intc_baseaddr); | 144 | selfmod_function((int *) arr_func, intc_baseaddr); |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 26947ab85260..c4cae9e6b802 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -473,12 +473,12 @@ endif | |||
473 | # Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys | 473 | # Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys |
474 | # | 474 | # |
475 | ifdef CONFIG_SGI_IP28 | 475 | ifdef CONFIG_SGI_IP28 |
476 | ifeq ($(call cc-option-yn,-mr10k-cache-barrier=1), n) | 476 | ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n) |
477 | $(error gcc doesn't support needed option -mr10k-cache-barrier=1) | 477 | $(error gcc doesn't support needed option -mr10k-cache-barrier=store) |
478 | endif | 478 | endif |
479 | endif | 479 | endif |
480 | core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ | 480 | core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ |
481 | cflags-$(CONFIG_SGI_IP28) += -mr10k-cache-barrier=1 -I$(srctree)/arch/mips/include/asm/mach-ip28 | 481 | cflags-$(CONFIG_SGI_IP28) += -mr10k-cache-barrier=store -I$(srctree)/arch/mips/include/asm/mach-ip28 |
482 | load-$(CONFIG_SGI_IP28) += 0xa800000020004000 | 482 | load-$(CONFIG_SGI_IP28) += 0xa800000020004000 |
483 | 483 | ||
484 | # | 484 | # |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 8de858f5449f..c2d53c18fd36 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
@@ -956,7 +956,7 @@ __clear_user(void __user *addr, __kernel_size_t size) | |||
956 | void __user * __cl_addr = (addr); \ | 956 | void __user * __cl_addr = (addr); \ |
957 | unsigned long __cl_size = (n); \ | 957 | unsigned long __cl_size = (n); \ |
958 | if (__cl_size && access_ok(VERIFY_WRITE, \ | 958 | if (__cl_size && access_ok(VERIFY_WRITE, \ |
959 | ((unsigned long)(__cl_addr)), __cl_size)) \ | 959 | __cl_addr, __cl_size)) \ |
960 | __cl_size = __clear_user(__cl_addr, __cl_size); \ | 960 | __cl_size = __clear_user(__cl_addr, __cl_size); \ |
961 | __cl_size; \ | 961 | __cl_size; \ |
962 | }) | 962 | }) |
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index f0cf46adb978..1c0048a6f5cf 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c | |||
@@ -82,8 +82,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
82 | int cpu = smp_processor_id(); | 82 | int cpu = smp_processor_id(); |
83 | 83 | ||
84 | if (cpu_context(cpu, mm) != 0) { | 84 | if (cpu_context(cpu, mm) != 0) { |
85 | unsigned long flags; | 85 | unsigned long size, flags; |
86 | int size; | ||
87 | 86 | ||
88 | #ifdef DEBUG_TLB | 87 | #ifdef DEBUG_TLB |
89 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", | 88 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", |
@@ -121,8 +120,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
121 | 120 | ||
122 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | 121 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) |
123 | { | 122 | { |
124 | unsigned long flags; | 123 | unsigned long size, flags; |
125 | int size; | ||
126 | 124 | ||
127 | #ifdef DEBUG_TLB | 125 | #ifdef DEBUG_TLB |
128 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end); | 126 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end); |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 9619f66e531e..892be426787c 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -117,8 +117,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
117 | int cpu = smp_processor_id(); | 117 | int cpu = smp_processor_id(); |
118 | 118 | ||
119 | if (cpu_context(cpu, mm) != 0) { | 119 | if (cpu_context(cpu, mm) != 0) { |
120 | unsigned long flags; | 120 | unsigned long size, flags; |
121 | int size; | ||
122 | 121 | ||
123 | ENTER_CRITICAL(flags); | 122 | ENTER_CRITICAL(flags); |
124 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 123 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
@@ -160,8 +159,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
160 | 159 | ||
161 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | 160 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) |
162 | { | 161 | { |
163 | unsigned long flags; | 162 | unsigned long size, flags; |
164 | int size; | ||
165 | 163 | ||
166 | ENTER_CRITICAL(flags); | 164 | ENTER_CRITICAL(flags); |
167 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 165 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c index 4f01a3be215c..4ec95cc2df2f 100644 --- a/arch/mips/mm/tlb-r8k.c +++ b/arch/mips/mm/tlb-r8k.c | |||
@@ -111,8 +111,7 @@ out_restore: | |||
111 | /* Usable for KV1 addresses only! */ | 111 | /* Usable for KV1 addresses only! */ |
112 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | 112 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) |
113 | { | 113 | { |
114 | unsigned long flags; | 114 | unsigned long size, flags; |
115 | int size; | ||
116 | 115 | ||
117 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 116 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
118 | size = (size + 1) >> 1; | 117 | size = (size + 1) >> 1; |
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 4ad5c3393fd3..45b6694c2079 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c | |||
@@ -148,7 +148,7 @@ static irqreturn_t panel_int(int irq, void *dev_id) | |||
148 | 148 | ||
149 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { | 149 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { |
150 | /* Wait until interrupt goes away */ | 150 | /* Wait until interrupt goes away */ |
151 | disable_irq(SGI_PANEL_IRQ); | 151 | disable_irq_nosync(SGI_PANEL_IRQ); |
152 | init_timer(&debounce_timer); | 152 | init_timer(&debounce_timer); |
153 | debounce_timer.function = debounce; | 153 | debounce_timer.function = debounce; |
154 | debounce_timer.expires = jiffies + 5; | 154 | debounce_timer.expires = jiffies + 5; |
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c index b6cab089561e..9b95d80ebc6e 100644 --- a/arch/mips/sgi-ip32/ip32-reset.c +++ b/arch/mips/sgi-ip32/ip32-reset.c | |||
@@ -53,7 +53,7 @@ static inline void ip32_machine_halt(void) | |||
53 | 53 | ||
54 | static void ip32_machine_power_off(void) | 54 | static void ip32_machine_power_off(void) |
55 | { | 55 | { |
56 | volatile unsigned char reg_a, xctrl_a, xctrl_b; | 56 | unsigned char reg_a, xctrl_a, xctrl_b; |
57 | 57 | ||
58 | disable_irq(MACEISA_RTC_IRQ); | 58 | disable_irq(MACEISA_RTC_IRQ); |
59 | reg_a = CMOS_READ(RTC_REG_A); | 59 | reg_a = CMOS_READ(RTC_REG_A); |
@@ -91,9 +91,10 @@ static void blink_timeout(unsigned long data) | |||
91 | 91 | ||
92 | static void debounce(unsigned long data) | 92 | static void debounce(unsigned long data) |
93 | { | 93 | { |
94 | volatile unsigned char reg_a, reg_c, xctrl_a; | 94 | unsigned char reg_a, reg_c, xctrl_a; |
95 | 95 | ||
96 | reg_c = CMOS_READ(RTC_INTR_FLAGS); | 96 | reg_c = CMOS_READ(RTC_INTR_FLAGS); |
97 | reg_a = CMOS_READ(RTC_REG_A); | ||
97 | CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A); | 98 | CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A); |
98 | wbflush(); | 99 | wbflush(); |
99 | xctrl_a = CMOS_READ(DS_B1_XCTRL4A); | 100 | xctrl_a = CMOS_READ(DS_B1_XCTRL4A); |
@@ -137,7 +138,7 @@ static inline void ip32_power_button(void) | |||
137 | 138 | ||
138 | static irqreturn_t ip32_rtc_int(int irq, void *dev_id) | 139 | static irqreturn_t ip32_rtc_int(int irq, void *dev_id) |
139 | { | 140 | { |
140 | volatile unsigned char reg_c; | 141 | unsigned char reg_c; |
141 | 142 | ||
142 | reg_c = CMOS_READ(RTC_INTR_FLAGS); | 143 | reg_c = CMOS_READ(RTC_INTR_FLAGS); |
143 | if (!(reg_c & RTC_IRQF)) { | 144 | if (!(reg_c & RTC_IRQF)) { |
@@ -145,7 +146,7 @@ static irqreturn_t ip32_rtc_int(int irq, void *dev_id) | |||
145 | "%s: RTC IRQ without RTC_IRQF\n", __func__); | 146 | "%s: RTC IRQ without RTC_IRQF\n", __func__); |
146 | } | 147 | } |
147 | /* Wait until interrupt goes away */ | 148 | /* Wait until interrupt goes away */ |
148 | disable_irq(MACEISA_RTC_IRQ); | 149 | disable_irq_nosync(MACEISA_RTC_IRQ); |
149 | init_timer(&debounce_timer); | 150 | init_timer(&debounce_timer); |
150 | debounce_timer.function = debounce; | 151 | debounce_timer.function = debounce; |
151 | debounce_timer.expires = jiffies + 50; | 152 | debounce_timer.expires = jiffies + 50; |
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index ac14f5245d2a..e28e65e7a0e1 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig | |||
@@ -1,13 +1,14 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.29-rc8 | 3 | # Linux kernel version: 2.6.30-rc5 |
4 | # Fri Mar 13 09:28:45 2009 | 4 | # Fri May 15 10:37:00 2009 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | 7 | ||
8 | # | 8 | # |
9 | # Processor support | 9 | # Processor support |
10 | # | 10 | # |
11 | CONFIG_PPC_BOOK3S=y | ||
11 | # CONFIG_POWER4_ONLY is not set | 12 | # CONFIG_POWER4_ONLY is not set |
12 | CONFIG_POWER3=y | 13 | CONFIG_POWER3=y |
13 | CONFIG_POWER4=y | 14 | CONFIG_POWER4=y |
@@ -55,9 +56,11 @@ CONFIG_OF=y | |||
55 | # CONFIG_GENERIC_TBSYNC is not set | 56 | # CONFIG_GENERIC_TBSYNC is not set |
56 | CONFIG_AUDIT_ARCH=y | 57 | CONFIG_AUDIT_ARCH=y |
57 | CONFIG_GENERIC_BUG=y | 58 | CONFIG_GENERIC_BUG=y |
59 | CONFIG_DTC=y | ||
58 | # CONFIG_DEFAULT_UIMAGE is not set | 60 | # CONFIG_DEFAULT_UIMAGE is not set |
59 | # CONFIG_PPC_DCR_NATIVE is not set | 61 | # CONFIG_PPC_DCR_NATIVE is not set |
60 | # CONFIG_PPC_DCR_MMIO is not set | 62 | # CONFIG_PPC_DCR_MMIO is not set |
63 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y | ||
61 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 64 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
62 | 65 | ||
63 | # | 66 | # |
@@ -72,6 +75,7 @@ CONFIG_SWAP=y | |||
72 | CONFIG_SYSVIPC=y | 75 | CONFIG_SYSVIPC=y |
73 | CONFIG_SYSVIPC_SYSCTL=y | 76 | CONFIG_SYSVIPC_SYSCTL=y |
74 | CONFIG_POSIX_MQUEUE=y | 77 | CONFIG_POSIX_MQUEUE=y |
78 | CONFIG_POSIX_MQUEUE_SYSCTL=y | ||
75 | # CONFIG_BSD_PROCESS_ACCT is not set | 79 | # CONFIG_BSD_PROCESS_ACCT is not set |
76 | # CONFIG_TASKSTATS is not set | 80 | # CONFIG_TASKSTATS is not set |
77 | # CONFIG_AUDIT is not set | 81 | # CONFIG_AUDIT is not set |
@@ -88,8 +92,7 @@ CONFIG_CLASSIC_RCU=y | |||
88 | CONFIG_LOG_BUF_SHIFT=17 | 92 | CONFIG_LOG_BUF_SHIFT=17 |
89 | # CONFIG_GROUP_SCHED is not set | 93 | # CONFIG_GROUP_SCHED is not set |
90 | # CONFIG_CGROUPS is not set | 94 | # CONFIG_CGROUPS is not set |
91 | CONFIG_SYSFS_DEPRECATED=y | 95 | # CONFIG_SYSFS_DEPRECATED_V2 is not set |
92 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
93 | # CONFIG_RELAY is not set | 96 | # CONFIG_RELAY is not set |
94 | CONFIG_NAMESPACES=y | 97 | CONFIG_NAMESPACES=y |
95 | # CONFIG_UTS_NS is not set | 98 | # CONFIG_UTS_NS is not set |
@@ -99,6 +102,9 @@ CONFIG_NAMESPACES=y | |||
99 | # CONFIG_NET_NS is not set | 102 | # CONFIG_NET_NS is not set |
100 | CONFIG_BLK_DEV_INITRD=y | 103 | CONFIG_BLK_DEV_INITRD=y |
101 | CONFIG_INITRAMFS_SOURCE="" | 104 | CONFIG_INITRAMFS_SOURCE="" |
105 | CONFIG_RD_GZIP=y | ||
106 | # CONFIG_RD_BZIP2 is not set | ||
107 | # CONFIG_RD_LZMA is not set | ||
102 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 108 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
103 | CONFIG_SYSCTL=y | 109 | CONFIG_SYSCTL=y |
104 | CONFIG_ANON_INODES=y | 110 | CONFIG_ANON_INODES=y |
@@ -107,6 +113,7 @@ CONFIG_SYSCTL_SYSCALL=y | |||
107 | CONFIG_KALLSYMS=y | 113 | CONFIG_KALLSYMS=y |
108 | CONFIG_KALLSYMS_ALL=y | 114 | CONFIG_KALLSYMS_ALL=y |
109 | CONFIG_KALLSYMS_EXTRA_PASS=y | 115 | CONFIG_KALLSYMS_EXTRA_PASS=y |
116 | # CONFIG_STRIP_ASM_SYMS is not set | ||
110 | CONFIG_HOTPLUG=y | 117 | CONFIG_HOTPLUG=y |
111 | CONFIG_PRINTK=y | 118 | CONFIG_PRINTK=y |
112 | CONFIG_BUG=y | 119 | CONFIG_BUG=y |
@@ -138,6 +145,7 @@ CONFIG_HAVE_KRETPROBES=y | |||
138 | CONFIG_HAVE_ARCH_TRACEHOOK=y | 145 | CONFIG_HAVE_ARCH_TRACEHOOK=y |
139 | CONFIG_HAVE_DMA_ATTRS=y | 146 | CONFIG_HAVE_DMA_ATTRS=y |
140 | CONFIG_USE_GENERIC_SMP_HELPERS=y | 147 | CONFIG_USE_GENERIC_SMP_HELPERS=y |
148 | # CONFIG_SLOW_WORK is not set | ||
141 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | 149 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set |
142 | CONFIG_SLABINFO=y | 150 | CONFIG_SLABINFO=y |
143 | CONFIG_RT_MUTEXES=y | 151 | CONFIG_RT_MUTEXES=y |
@@ -150,7 +158,6 @@ CONFIG_MODULE_UNLOAD=y | |||
150 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 158 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
151 | CONFIG_STOP_MACHINE=y | 159 | CONFIG_STOP_MACHINE=y |
152 | CONFIG_BLOCK=y | 160 | CONFIG_BLOCK=y |
153 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
154 | CONFIG_BLK_DEV_BSG=y | 161 | CONFIG_BLK_DEV_BSG=y |
155 | # CONFIG_BLK_DEV_INTEGRITY is not set | 162 | # CONFIG_BLK_DEV_INTEGRITY is not set |
156 | CONFIG_BLOCK_COMPAT=y | 163 | CONFIG_BLOCK_COMPAT=y |
@@ -172,7 +179,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
172 | # | 179 | # |
173 | # Platform support | 180 | # Platform support |
174 | # | 181 | # |
175 | CONFIG_PPC_MULTIPLATFORM=y | ||
176 | # CONFIG_PPC_PSERIES is not set | 182 | # CONFIG_PPC_PSERIES is not set |
177 | # CONFIG_PPC_ISERIES is not set | 183 | # CONFIG_PPC_ISERIES is not set |
178 | # CONFIG_PPC_PMAC is not set | 184 | # CONFIG_PPC_PMAC is not set |
@@ -209,6 +215,7 @@ CONFIG_SPU_FS_64K_LS=y | |||
209 | # CONFIG_SPU_TRACE is not set | 215 | # CONFIG_SPU_TRACE is not set |
210 | CONFIG_SPU_BASE=y | 216 | CONFIG_SPU_BASE=y |
211 | # CONFIG_PQ2ADS is not set | 217 | # CONFIG_PQ2ADS is not set |
218 | # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set | ||
212 | # CONFIG_IPIC is not set | 219 | # CONFIG_IPIC is not set |
213 | # CONFIG_MPIC is not set | 220 | # CONFIG_MPIC is not set |
214 | # CONFIG_MPIC_WEIRD is not set | 221 | # CONFIG_MPIC_WEIRD is not set |
@@ -279,11 +286,14 @@ CONFIG_PHYS_ADDR_T_64BIT=y | |||
279 | CONFIG_ZONE_DMA_FLAG=1 | 286 | CONFIG_ZONE_DMA_FLAG=1 |
280 | CONFIG_BOUNCE=y | 287 | CONFIG_BOUNCE=y |
281 | CONFIG_UNEVICTABLE_LRU=y | 288 | CONFIG_UNEVICTABLE_LRU=y |
289 | CONFIG_HAVE_MLOCK=y | ||
290 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
282 | CONFIG_ARCH_MEMORY_PROBE=y | 291 | CONFIG_ARCH_MEMORY_PROBE=y |
283 | CONFIG_PPC_HAS_HASH_64K=y | 292 | CONFIG_PPC_HAS_HASH_64K=y |
284 | CONFIG_PPC_4K_PAGES=y | 293 | CONFIG_PPC_4K_PAGES=y |
285 | # CONFIG_PPC_16K_PAGES is not set | 294 | # CONFIG_PPC_16K_PAGES is not set |
286 | # CONFIG_PPC_64K_PAGES is not set | 295 | # CONFIG_PPC_64K_PAGES is not set |
296 | # CONFIG_PPC_256K_PAGES is not set | ||
287 | CONFIG_FORCE_MAX_ZONEORDER=13 | 297 | CONFIG_FORCE_MAX_ZONEORDER=13 |
288 | CONFIG_SCHED_SMT=y | 298 | CONFIG_SCHED_SMT=y |
289 | CONFIG_PROC_DEVICETREE=y | 299 | CONFIG_PROC_DEVICETREE=y |
@@ -316,7 +326,6 @@ CONFIG_NET=y | |||
316 | # | 326 | # |
317 | # Networking options | 327 | # Networking options |
318 | # | 328 | # |
319 | CONFIG_COMPAT_NET_DEV_OPS=y | ||
320 | CONFIG_PACKET=y | 329 | CONFIG_PACKET=y |
321 | CONFIG_PACKET_MMAP=y | 330 | CONFIG_PACKET_MMAP=y |
322 | CONFIG_UNIX=y | 331 | CONFIG_UNIX=y |
@@ -389,6 +398,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y | |||
389 | # CONFIG_LAPB is not set | 398 | # CONFIG_LAPB is not set |
390 | # CONFIG_ECONET is not set | 399 | # CONFIG_ECONET is not set |
391 | # CONFIG_WAN_ROUTER is not set | 400 | # CONFIG_WAN_ROUTER is not set |
401 | # CONFIG_PHONET is not set | ||
392 | # CONFIG_NET_SCHED is not set | 402 | # CONFIG_NET_SCHED is not set |
393 | # CONFIG_DCB is not set | 403 | # CONFIG_DCB is not set |
394 | 404 | ||
@@ -396,6 +406,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y | |||
396 | # Network testing | 406 | # Network testing |
397 | # | 407 | # |
398 | # CONFIG_NET_PKTGEN is not set | 408 | # CONFIG_NET_PKTGEN is not set |
409 | # CONFIG_NET_DROP_MONITOR is not set | ||
399 | # CONFIG_HAMRADIO is not set | 410 | # CONFIG_HAMRADIO is not set |
400 | # CONFIG_CAN is not set | 411 | # CONFIG_CAN is not set |
401 | # CONFIG_IRDA is not set | 412 | # CONFIG_IRDA is not set |
@@ -419,11 +430,9 @@ CONFIG_BT_HCIBTUSB=m | |||
419 | # CONFIG_BT_HCIBFUSB is not set | 430 | # CONFIG_BT_HCIBFUSB is not set |
420 | # CONFIG_BT_HCIVHCI is not set | 431 | # CONFIG_BT_HCIVHCI is not set |
421 | # CONFIG_AF_RXRPC is not set | 432 | # CONFIG_AF_RXRPC is not set |
422 | # CONFIG_PHONET is not set | ||
423 | CONFIG_WIRELESS=y | 433 | CONFIG_WIRELESS=y |
424 | CONFIG_CFG80211=m | 434 | CONFIG_CFG80211=m |
425 | # CONFIG_CFG80211_REG_DEBUG is not set | 435 | # CONFIG_CFG80211_REG_DEBUG is not set |
426 | CONFIG_NL80211=y | ||
427 | # CONFIG_WIRELESS_OLD_REGULATORY is not set | 436 | # CONFIG_WIRELESS_OLD_REGULATORY is not set |
428 | CONFIG_WIRELESS_EXT=y | 437 | CONFIG_WIRELESS_EXT=y |
429 | # CONFIG_WIRELESS_EXT_SYSFS is not set | 438 | # CONFIG_WIRELESS_EXT_SYSFS is not set |
@@ -602,6 +611,7 @@ CONFIG_SCSI_WAIT_SCAN=m | |||
602 | # CONFIG_SCSI_SRP_ATTRS is not set | 611 | # CONFIG_SCSI_SRP_ATTRS is not set |
603 | # CONFIG_SCSI_LOWLEVEL is not set | 612 | # CONFIG_SCSI_LOWLEVEL is not set |
604 | # CONFIG_SCSI_DH is not set | 613 | # CONFIG_SCSI_DH is not set |
614 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
605 | # CONFIG_ATA is not set | 615 | # CONFIG_ATA is not set |
606 | CONFIG_MD=y | 616 | CONFIG_MD=y |
607 | # CONFIG_BLK_DEV_MD is not set | 617 | # CONFIG_BLK_DEV_MD is not set |
@@ -616,6 +626,7 @@ CONFIG_BLK_DEV_DM=m | |||
616 | # CONFIG_DM_UEVENT is not set | 626 | # CONFIG_DM_UEVENT is not set |
617 | # CONFIG_MACINTOSH_DRIVERS is not set | 627 | # CONFIG_MACINTOSH_DRIVERS is not set |
618 | CONFIG_NETDEVICES=y | 628 | CONFIG_NETDEVICES=y |
629 | CONFIG_COMPAT_NET_DEV_OPS=y | ||
619 | # CONFIG_DUMMY is not set | 630 | # CONFIG_DUMMY is not set |
620 | # CONFIG_BONDING is not set | 631 | # CONFIG_BONDING is not set |
621 | # CONFIG_MACVLAN is not set | 632 | # CONFIG_MACVLAN is not set |
@@ -625,6 +636,8 @@ CONFIG_NETDEVICES=y | |||
625 | # CONFIG_PHYLIB is not set | 636 | # CONFIG_PHYLIB is not set |
626 | CONFIG_NET_ETHERNET=y | 637 | CONFIG_NET_ETHERNET=y |
627 | CONFIG_MII=m | 638 | CONFIG_MII=m |
639 | # CONFIG_ETHOC is not set | ||
640 | # CONFIG_DNET is not set | ||
628 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | 641 | # CONFIG_IBM_NEW_EMAC_ZMII is not set |
629 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | 642 | # CONFIG_IBM_NEW_EMAC_RGMII is not set |
630 | # CONFIG_IBM_NEW_EMAC_TAH is not set | 643 | # CONFIG_IBM_NEW_EMAC_TAH is not set |
@@ -646,12 +659,13 @@ CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y | |||
646 | CONFIG_WLAN_80211=y | 659 | CONFIG_WLAN_80211=y |
647 | # CONFIG_LIBERTAS is not set | 660 | # CONFIG_LIBERTAS is not set |
648 | # CONFIG_LIBERTAS_THINFIRM is not set | 661 | # CONFIG_LIBERTAS_THINFIRM is not set |
662 | # CONFIG_AT76C50X_USB is not set | ||
649 | # CONFIG_USB_ZD1201 is not set | 663 | # CONFIG_USB_ZD1201 is not set |
650 | # CONFIG_USB_NET_RNDIS_WLAN is not set | 664 | # CONFIG_USB_NET_RNDIS_WLAN is not set |
651 | # CONFIG_RTL8187 is not set | 665 | # CONFIG_RTL8187 is not set |
652 | # CONFIG_MAC80211_HWSIM is not set | 666 | # CONFIG_MAC80211_HWSIM is not set |
653 | # CONFIG_P54_COMMON is not set | 667 | # CONFIG_P54_COMMON is not set |
654 | # CONFIG_IWLWIFI_LEDS is not set | 668 | # CONFIG_AR9170_USB is not set |
655 | # CONFIG_HOSTAP is not set | 669 | # CONFIG_HOSTAP is not set |
656 | # CONFIG_B43 is not set | 670 | # CONFIG_B43 is not set |
657 | # CONFIG_B43LEGACY is not set | 671 | # CONFIG_B43LEGACY is not set |
@@ -673,6 +687,7 @@ CONFIG_USB_PEGASUS=m | |||
673 | CONFIG_USB_USBNET=m | 687 | CONFIG_USB_USBNET=m |
674 | CONFIG_USB_NET_AX8817X=m | 688 | CONFIG_USB_NET_AX8817X=m |
675 | # CONFIG_USB_NET_CDCETHER is not set | 689 | # CONFIG_USB_NET_CDCETHER is not set |
690 | # CONFIG_USB_NET_CDC_EEM is not set | ||
676 | # CONFIG_USB_NET_DM9601 is not set | 691 | # CONFIG_USB_NET_DM9601 is not set |
677 | # CONFIG_USB_NET_SMSC95XX is not set | 692 | # CONFIG_USB_NET_SMSC95XX is not set |
678 | # CONFIG_USB_NET_GL620A is not set | 693 | # CONFIG_USB_NET_GL620A is not set |
@@ -724,28 +739,7 @@ CONFIG_INPUT_EVDEV=m | |||
724 | # | 739 | # |
725 | # CONFIG_INPUT_KEYBOARD is not set | 740 | # CONFIG_INPUT_KEYBOARD is not set |
726 | # CONFIG_INPUT_MOUSE is not set | 741 | # CONFIG_INPUT_MOUSE is not set |
727 | CONFIG_INPUT_JOYSTICK=y | 742 | # CONFIG_INPUT_JOYSTICK is not set |
728 | # CONFIG_JOYSTICK_ANALOG is not set | ||
729 | # CONFIG_JOYSTICK_A3D is not set | ||
730 | # CONFIG_JOYSTICK_ADI is not set | ||
731 | # CONFIG_JOYSTICK_COBRA is not set | ||
732 | # CONFIG_JOYSTICK_GF2K is not set | ||
733 | # CONFIG_JOYSTICK_GRIP is not set | ||
734 | # CONFIG_JOYSTICK_GRIP_MP is not set | ||
735 | # CONFIG_JOYSTICK_GUILLEMOT is not set | ||
736 | # CONFIG_JOYSTICK_INTERACT is not set | ||
737 | # CONFIG_JOYSTICK_SIDEWINDER is not set | ||
738 | # CONFIG_JOYSTICK_TMDC is not set | ||
739 | # CONFIG_JOYSTICK_IFORCE is not set | ||
740 | # CONFIG_JOYSTICK_WARRIOR is not set | ||
741 | # CONFIG_JOYSTICK_MAGELLAN is not set | ||
742 | # CONFIG_JOYSTICK_SPACEORB is not set | ||
743 | # CONFIG_JOYSTICK_SPACEBALL is not set | ||
744 | # CONFIG_JOYSTICK_STINGER is not set | ||
745 | # CONFIG_JOYSTICK_TWIDJOY is not set | ||
746 | # CONFIG_JOYSTICK_ZHENHUA is not set | ||
747 | # CONFIG_JOYSTICK_JOYDUMP is not set | ||
748 | # CONFIG_JOYSTICK_XPAD is not set | ||
749 | # CONFIG_INPUT_TABLET is not set | 743 | # CONFIG_INPUT_TABLET is not set |
750 | # CONFIG_INPUT_TOUCHSCREEN is not set | 744 | # CONFIG_INPUT_TOUCHSCREEN is not set |
751 | # CONFIG_INPUT_MISC is not set | 745 | # CONFIG_INPUT_MISC is not set |
@@ -864,6 +858,7 @@ CONFIG_FB_PS3_DEFAULT_SIZE_M=9 | |||
864 | # CONFIG_FB_VIRTUAL is not set | 858 | # CONFIG_FB_VIRTUAL is not set |
865 | # CONFIG_FB_METRONOME is not set | 859 | # CONFIG_FB_METRONOME is not set |
866 | # CONFIG_FB_MB862XX is not set | 860 | # CONFIG_FB_MB862XX is not set |
861 | # CONFIG_FB_BROADSHEET is not set | ||
867 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 862 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
868 | 863 | ||
869 | # | 864 | # |
@@ -934,15 +929,17 @@ CONFIG_USB_HIDDEV=y | |||
934 | # | 929 | # |
935 | # Special HID drivers | 930 | # Special HID drivers |
936 | # | 931 | # |
937 | # CONFIG_HID_COMPAT is not set | ||
938 | # CONFIG_HID_A4TECH is not set | 932 | # CONFIG_HID_A4TECH is not set |
939 | # CONFIG_HID_APPLE is not set | 933 | # CONFIG_HID_APPLE is not set |
940 | # CONFIG_HID_BELKIN is not set | 934 | # CONFIG_HID_BELKIN is not set |
941 | # CONFIG_HID_CHERRY is not set | 935 | # CONFIG_HID_CHERRY is not set |
942 | # CONFIG_HID_CHICONY is not set | 936 | # CONFIG_HID_CHICONY is not set |
943 | # CONFIG_HID_CYPRESS is not set | 937 | # CONFIG_HID_CYPRESS is not set |
938 | # CONFIG_DRAGONRISE_FF is not set | ||
944 | # CONFIG_HID_EZKEY is not set | 939 | # CONFIG_HID_EZKEY is not set |
940 | # CONFIG_HID_KYE is not set | ||
945 | # CONFIG_HID_GYRATION is not set | 941 | # CONFIG_HID_GYRATION is not set |
942 | # CONFIG_HID_KENSINGTON is not set | ||
946 | # CONFIG_HID_LOGITECH is not set | 943 | # CONFIG_HID_LOGITECH is not set |
947 | # CONFIG_HID_MICROSOFT is not set | 944 | # CONFIG_HID_MICROSOFT is not set |
948 | # CONFIG_HID_MONTEREY is not set | 945 | # CONFIG_HID_MONTEREY is not set |
@@ -950,7 +947,7 @@ CONFIG_USB_HIDDEV=y | |||
950 | # CONFIG_HID_PANTHERLORD is not set | 947 | # CONFIG_HID_PANTHERLORD is not set |
951 | # CONFIG_HID_PETALYNX is not set | 948 | # CONFIG_HID_PETALYNX is not set |
952 | # CONFIG_HID_SAMSUNG is not set | 949 | # CONFIG_HID_SAMSUNG is not set |
953 | # CONFIG_HID_SONY is not set | 950 | CONFIG_HID_SONY=m |
954 | # CONFIG_HID_SUNPLUS is not set | 951 | # CONFIG_HID_SUNPLUS is not set |
955 | # CONFIG_GREENASIA_FF is not set | 952 | # CONFIG_GREENASIA_FF is not set |
956 | # CONFIG_HID_TOPSEED is not set | 953 | # CONFIG_HID_TOPSEED is not set |
@@ -1012,11 +1009,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y | |||
1012 | # CONFIG_USB_TMC is not set | 1009 | # CONFIG_USB_TMC is not set |
1013 | 1010 | ||
1014 | # | 1011 | # |
1015 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; | 1012 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may |
1016 | # | 1013 | # |
1017 | 1014 | ||
1018 | # | 1015 | # |
1019 | # see USB_STORAGE Help for more information | 1016 | # also be needed; see USB_STORAGE Help for more info |
1020 | # | 1017 | # |
1021 | CONFIG_USB_STORAGE=m | 1018 | CONFIG_USB_STORAGE=m |
1022 | # CONFIG_USB_STORAGE_DEBUG is not set | 1019 | # CONFIG_USB_STORAGE_DEBUG is not set |
@@ -1058,7 +1055,6 @@ CONFIG_USB_STORAGE=m | |||
1058 | # CONFIG_USB_LED is not set | 1055 | # CONFIG_USB_LED is not set |
1059 | # CONFIG_USB_CYPRESS_CY7C63 is not set | 1056 | # CONFIG_USB_CYPRESS_CY7C63 is not set |
1060 | # CONFIG_USB_CYTHERM is not set | 1057 | # CONFIG_USB_CYTHERM is not set |
1061 | # CONFIG_USB_PHIDGET is not set | ||
1062 | # CONFIG_USB_IDMOUSE is not set | 1058 | # CONFIG_USB_IDMOUSE is not set |
1063 | # CONFIG_USB_FTDI_ELAN is not set | 1059 | # CONFIG_USB_FTDI_ELAN is not set |
1064 | # CONFIG_USB_APPLEDISPLAY is not set | 1060 | # CONFIG_USB_APPLEDISPLAY is not set |
@@ -1074,6 +1070,7 @@ CONFIG_USB_STORAGE=m | |||
1074 | # | 1070 | # |
1075 | # OTG and related infrastructure | 1071 | # OTG and related infrastructure |
1076 | # | 1072 | # |
1073 | # CONFIG_NOP_USB_XCEIV is not set | ||
1077 | # CONFIG_MMC is not set | 1074 | # CONFIG_MMC is not set |
1078 | # CONFIG_MEMSTICK is not set | 1075 | # CONFIG_MEMSTICK is not set |
1079 | # CONFIG_NEW_LEDS is not set | 1076 | # CONFIG_NEW_LEDS is not set |
@@ -1113,8 +1110,10 @@ CONFIG_RTC_INTF_DEV=y | |||
1113 | # | 1110 | # |
1114 | # on-CPU RTC drivers | 1111 | # on-CPU RTC drivers |
1115 | # | 1112 | # |
1116 | CONFIG_RTC_DRV_PPC=m | 1113 | # CONFIG_RTC_DRV_GENERIC is not set |
1114 | CONFIG_RTC_DRV_PS3=m | ||
1117 | # CONFIG_DMADEVICES is not set | 1115 | # CONFIG_DMADEVICES is not set |
1116 | # CONFIG_AUXDISPLAY is not set | ||
1118 | # CONFIG_UIO is not set | 1117 | # CONFIG_UIO is not set |
1119 | # CONFIG_STAGING is not set | 1118 | # CONFIG_STAGING is not set |
1120 | 1119 | ||
@@ -1125,6 +1124,7 @@ CONFIG_EXT2_FS=m | |||
1125 | # CONFIG_EXT2_FS_XATTR is not set | 1124 | # CONFIG_EXT2_FS_XATTR is not set |
1126 | # CONFIG_EXT2_FS_XIP is not set | 1125 | # CONFIG_EXT2_FS_XIP is not set |
1127 | CONFIG_EXT3_FS=m | 1126 | CONFIG_EXT3_FS=m |
1127 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
1128 | CONFIG_EXT3_FS_XATTR=y | 1128 | CONFIG_EXT3_FS_XATTR=y |
1129 | # CONFIG_EXT3_FS_POSIX_ACL is not set | 1129 | # CONFIG_EXT3_FS_POSIX_ACL is not set |
1130 | # CONFIG_EXT3_FS_SECURITY is not set | 1130 | # CONFIG_EXT3_FS_SECURITY is not set |
@@ -1161,6 +1161,11 @@ CONFIG_AUTOFS4_FS=m | |||
1161 | # CONFIG_FUSE_FS is not set | 1161 | # CONFIG_FUSE_FS is not set |
1162 | 1162 | ||
1163 | # | 1163 | # |
1164 | # Caches | ||
1165 | # | ||
1166 | # CONFIG_FSCACHE is not set | ||
1167 | |||
1168 | # | ||
1164 | # CD-ROM/DVD Filesystems | 1169 | # CD-ROM/DVD Filesystems |
1165 | # | 1170 | # |
1166 | CONFIG_ISO9660_FS=m | 1171 | CONFIG_ISO9660_FS=m |
@@ -1211,6 +1216,7 @@ CONFIG_MISC_FILESYSTEMS=y | |||
1211 | # CONFIG_ROMFS_FS is not set | 1216 | # CONFIG_ROMFS_FS is not set |
1212 | # CONFIG_SYSV_FS is not set | 1217 | # CONFIG_SYSV_FS is not set |
1213 | # CONFIG_UFS_FS is not set | 1218 | # CONFIG_UFS_FS is not set |
1219 | # CONFIG_NILFS2_FS is not set | ||
1214 | CONFIG_NETWORK_FILESYSTEMS=y | 1220 | CONFIG_NETWORK_FILESYSTEMS=y |
1215 | CONFIG_NFS_FS=y | 1221 | CONFIG_NFS_FS=y |
1216 | CONFIG_NFS_V3=y | 1222 | CONFIG_NFS_V3=y |
@@ -1223,7 +1229,6 @@ CONFIG_LOCKD_V4=y | |||
1223 | CONFIG_NFS_COMMON=y | 1229 | CONFIG_NFS_COMMON=y |
1224 | CONFIG_SUNRPC=y | 1230 | CONFIG_SUNRPC=y |
1225 | CONFIG_SUNRPC_GSS=y | 1231 | CONFIG_SUNRPC_GSS=y |
1226 | # CONFIG_SUNRPC_REGISTER_V4 is not set | ||
1227 | CONFIG_RPCSEC_GSS_KRB5=y | 1232 | CONFIG_RPCSEC_GSS_KRB5=y |
1228 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 1233 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
1229 | # CONFIG_SMB_FS is not set | 1234 | # CONFIG_SMB_FS is not set |
@@ -1283,6 +1288,7 @@ CONFIG_NLS_ISO8859_1=y | |||
1283 | # CONFIG_NLS_KOI8_U is not set | 1288 | # CONFIG_NLS_KOI8_U is not set |
1284 | # CONFIG_NLS_UTF8 is not set | 1289 | # CONFIG_NLS_UTF8 is not set |
1285 | # CONFIG_DLM is not set | 1290 | # CONFIG_DLM is not set |
1291 | CONFIG_BINARY_PRINTF=y | ||
1286 | 1292 | ||
1287 | # | 1293 | # |
1288 | # Library routines | 1294 | # Library routines |
@@ -1296,15 +1302,16 @@ CONFIG_CRC_ITU_T=m | |||
1296 | CONFIG_CRC32=y | 1302 | CONFIG_CRC32=y |
1297 | # CONFIG_CRC7 is not set | 1303 | # CONFIG_CRC7 is not set |
1298 | # CONFIG_LIBCRC32C is not set | 1304 | # CONFIG_LIBCRC32C is not set |
1299 | CONFIG_ZLIB_INFLATE=m | 1305 | CONFIG_ZLIB_INFLATE=y |
1300 | CONFIG_ZLIB_DEFLATE=m | 1306 | CONFIG_ZLIB_DEFLATE=m |
1301 | CONFIG_LZO_COMPRESS=m | 1307 | CONFIG_LZO_COMPRESS=m |
1302 | CONFIG_LZO_DECOMPRESS=m | 1308 | CONFIG_LZO_DECOMPRESS=m |
1303 | CONFIG_PLIST=y | 1309 | CONFIG_DECOMPRESS_GZIP=y |
1304 | CONFIG_HAS_IOMEM=y | 1310 | CONFIG_HAS_IOMEM=y |
1305 | CONFIG_HAS_IOPORT=y | 1311 | CONFIG_HAS_IOPORT=y |
1306 | CONFIG_HAS_DMA=y | 1312 | CONFIG_HAS_DMA=y |
1307 | CONFIG_HAVE_LMB=y | 1313 | CONFIG_HAVE_LMB=y |
1314 | CONFIG_NLATTR=y | ||
1308 | 1315 | ||
1309 | # | 1316 | # |
1310 | # Kernel hacking | 1317 | # Kernel hacking |
@@ -1322,6 +1329,9 @@ CONFIG_DEBUG_KERNEL=y | |||
1322 | CONFIG_DETECT_SOFTLOCKUP=y | 1329 | CONFIG_DETECT_SOFTLOCKUP=y |
1323 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | 1330 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set |
1324 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | 1331 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 |
1332 | CONFIG_DETECT_HUNG_TASK=y | ||
1333 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
1334 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
1325 | CONFIG_SCHED_DEBUG=y | 1335 | CONFIG_SCHED_DEBUG=y |
1326 | # CONFIG_SCHEDSTATS is not set | 1336 | # CONFIG_SCHEDSTATS is not set |
1327 | # CONFIG_TIMER_STATS is not set | 1337 | # CONFIG_TIMER_STATS is not set |
@@ -1357,12 +1367,15 @@ CONFIG_DEBUG_LIST=y | |||
1357 | # CONFIG_FAULT_INJECTION is not set | 1367 | # CONFIG_FAULT_INJECTION is not set |
1358 | # CONFIG_LATENCYTOP is not set | 1368 | # CONFIG_LATENCYTOP is not set |
1359 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 1369 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
1370 | # CONFIG_DEBUG_PAGEALLOC is not set | ||
1360 | CONFIG_NOP_TRACER=y | 1371 | CONFIG_NOP_TRACER=y |
1361 | CONFIG_HAVE_FUNCTION_TRACER=y | 1372 | CONFIG_HAVE_FUNCTION_TRACER=y |
1373 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | ||
1362 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 1374 | CONFIG_HAVE_DYNAMIC_FTRACE=y |
1363 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | 1375 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
1364 | CONFIG_RING_BUFFER=y | 1376 | CONFIG_RING_BUFFER=y |
1365 | CONFIG_TRACING=y | 1377 | CONFIG_TRACING=y |
1378 | CONFIG_TRACING_SUPPORT=y | ||
1366 | 1379 | ||
1367 | # | 1380 | # |
1368 | # Tracers | 1381 | # Tracers |
@@ -1371,18 +1384,21 @@ CONFIG_TRACING=y | |||
1371 | # CONFIG_IRQSOFF_TRACER is not set | 1384 | # CONFIG_IRQSOFF_TRACER is not set |
1372 | # CONFIG_SCHED_TRACER is not set | 1385 | # CONFIG_SCHED_TRACER is not set |
1373 | # CONFIG_CONTEXT_SWITCH_TRACER is not set | 1386 | # CONFIG_CONTEXT_SWITCH_TRACER is not set |
1387 | # CONFIG_EVENT_TRACER is not set | ||
1374 | # CONFIG_BOOT_TRACER is not set | 1388 | # CONFIG_BOOT_TRACER is not set |
1375 | # CONFIG_TRACE_BRANCH_PROFILING is not set | 1389 | # CONFIG_TRACE_BRANCH_PROFILING is not set |
1376 | # CONFIG_STACK_TRACER is not set | 1390 | # CONFIG_STACK_TRACER is not set |
1391 | # CONFIG_KMEMTRACE is not set | ||
1392 | # CONFIG_WORKQUEUE_TRACER is not set | ||
1393 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
1377 | # CONFIG_FTRACE_STARTUP_TEST is not set | 1394 | # CONFIG_FTRACE_STARTUP_TEST is not set |
1378 | # CONFIG_DYNAMIC_PRINTK_DEBUG is not set | 1395 | # CONFIG_DYNAMIC_DEBUG is not set |
1379 | # CONFIG_SAMPLES is not set | 1396 | # CONFIG_SAMPLES is not set |
1380 | CONFIG_HAVE_ARCH_KGDB=y | 1397 | CONFIG_HAVE_ARCH_KGDB=y |
1381 | # CONFIG_KGDB is not set | 1398 | # CONFIG_KGDB is not set |
1382 | CONFIG_PRINT_STACK_DEPTH=64 | 1399 | CONFIG_PRINT_STACK_DEPTH=64 |
1383 | CONFIG_DEBUG_STACKOVERFLOW=y | 1400 | CONFIG_DEBUG_STACKOVERFLOW=y |
1384 | # CONFIG_DEBUG_STACK_USAGE is not set | 1401 | # CONFIG_DEBUG_STACK_USAGE is not set |
1385 | # CONFIG_DEBUG_PAGEALLOC is not set | ||
1386 | # CONFIG_CODE_PATCHING_SELFTEST is not set | 1402 | # CONFIG_CODE_PATCHING_SELFTEST is not set |
1387 | # CONFIG_FTR_FIXUP_SELFTEST is not set | 1403 | # CONFIG_FTR_FIXUP_SELFTEST is not set |
1388 | # CONFIG_MSI_BITMAP_SELFTEST is not set | 1404 | # CONFIG_MSI_BITMAP_SELFTEST is not set |
@@ -1415,10 +1431,12 @@ CONFIG_CRYPTO_HASH=y | |||
1415 | CONFIG_CRYPTO_HASH2=y | 1431 | CONFIG_CRYPTO_HASH2=y |
1416 | CONFIG_CRYPTO_RNG=m | 1432 | CONFIG_CRYPTO_RNG=m |
1417 | CONFIG_CRYPTO_RNG2=y | 1433 | CONFIG_CRYPTO_RNG2=y |
1434 | CONFIG_CRYPTO_PCOMP=y | ||
1418 | CONFIG_CRYPTO_MANAGER=y | 1435 | CONFIG_CRYPTO_MANAGER=y |
1419 | CONFIG_CRYPTO_MANAGER2=y | 1436 | CONFIG_CRYPTO_MANAGER2=y |
1420 | CONFIG_CRYPTO_GF128MUL=m | 1437 | CONFIG_CRYPTO_GF128MUL=m |
1421 | # CONFIG_CRYPTO_NULL is not set | 1438 | # CONFIG_CRYPTO_NULL is not set |
1439 | CONFIG_CRYPTO_WORKQUEUE=y | ||
1422 | # CONFIG_CRYPTO_CRYPTD is not set | 1440 | # CONFIG_CRYPTO_CRYPTD is not set |
1423 | # CONFIG_CRYPTO_AUTHENC is not set | 1441 | # CONFIG_CRYPTO_AUTHENC is not set |
1424 | # CONFIG_CRYPTO_TEST is not set | 1442 | # CONFIG_CRYPTO_TEST is not set |
@@ -1487,6 +1505,7 @@ CONFIG_CRYPTO_SALSA20=m | |||
1487 | # Compression | 1505 | # Compression |
1488 | # | 1506 | # |
1489 | # CONFIG_CRYPTO_DEFLATE is not set | 1507 | # CONFIG_CRYPTO_DEFLATE is not set |
1508 | # CONFIG_CRYPTO_ZLIB is not set | ||
1490 | CONFIG_CRYPTO_LZO=m | 1509 | CONFIG_CRYPTO_LZO=m |
1491 | 1510 | ||
1492 | # | 1511 | # |
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 70e2a736be1f..2d182f119d1d 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
@@ -157,7 +157,7 @@ __ftrace_make_nop(struct module *mod, | |||
157 | * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12) | 157 | * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12) |
158 | */ | 158 | */ |
159 | 159 | ||
160 | pr_debug("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc); | 160 | pr_devel("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc); |
161 | 161 | ||
162 | /* Find where the trampoline jumps to */ | 162 | /* Find where the trampoline jumps to */ |
163 | if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { | 163 | if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { |
@@ -165,7 +165,7 @@ __ftrace_make_nop(struct module *mod, | |||
165 | return -EFAULT; | 165 | return -EFAULT; |
166 | } | 166 | } |
167 | 167 | ||
168 | pr_debug(" %08x %08x", jmp[0], jmp[1]); | 168 | pr_devel(" %08x %08x", jmp[0], jmp[1]); |
169 | 169 | ||
170 | /* verify that this is what we expect it to be */ | 170 | /* verify that this is what we expect it to be */ |
171 | if (((jmp[0] & 0xffff0000) != 0x3d820000) || | 171 | if (((jmp[0] & 0xffff0000) != 0x3d820000) || |
@@ -181,18 +181,18 @@ __ftrace_make_nop(struct module *mod, | |||
181 | offset = ((unsigned)((unsigned short)jmp[0]) << 16) + | 181 | offset = ((unsigned)((unsigned short)jmp[0]) << 16) + |
182 | (int)((short)jmp[1]); | 182 | (int)((short)jmp[1]); |
183 | 183 | ||
184 | pr_debug(" %x ", offset); | 184 | pr_devel(" %x ", offset); |
185 | 185 | ||
186 | /* get the address this jumps too */ | 186 | /* get the address this jumps too */ |
187 | tramp = mod->arch.toc + offset + 32; | 187 | tramp = mod->arch.toc + offset + 32; |
188 | pr_debug("toc: %lx", tramp); | 188 | pr_devel("toc: %lx", tramp); |
189 | 189 | ||
190 | if (probe_kernel_read(jmp, (void *)tramp, 8)) { | 190 | if (probe_kernel_read(jmp, (void *)tramp, 8)) { |
191 | printk(KERN_ERR "Failed to read %lx\n", tramp); | 191 | printk(KERN_ERR "Failed to read %lx\n", tramp); |
192 | return -EFAULT; | 192 | return -EFAULT; |
193 | } | 193 | } |
194 | 194 | ||
195 | pr_debug(" %08x %08x\n", jmp[0], jmp[1]); | 195 | pr_devel(" %08x %08x\n", jmp[0], jmp[1]); |
196 | 196 | ||
197 | ptr = ((unsigned long)jmp[0] << 32) + jmp[1]; | 197 | ptr = ((unsigned long)jmp[0] << 32) + jmp[1]; |
198 | 198 | ||
@@ -269,7 +269,7 @@ __ftrace_make_nop(struct module *mod, | |||
269 | * 0x4e, 0x80, 0x04, 0x20 bctr | 269 | * 0x4e, 0x80, 0x04, 0x20 bctr |
270 | */ | 270 | */ |
271 | 271 | ||
272 | pr_debug("ip:%lx jumps to %lx", ip, tramp); | 272 | pr_devel("ip:%lx jumps to %lx", ip, tramp); |
273 | 273 | ||
274 | /* Find where the trampoline jumps to */ | 274 | /* Find where the trampoline jumps to */ |
275 | if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { | 275 | if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { |
@@ -277,7 +277,7 @@ __ftrace_make_nop(struct module *mod, | |||
277 | return -EFAULT; | 277 | return -EFAULT; |
278 | } | 278 | } |
279 | 279 | ||
280 | pr_debug(" %08x %08x ", jmp[0], jmp[1]); | 280 | pr_devel(" %08x %08x ", jmp[0], jmp[1]); |
281 | 281 | ||
282 | /* verify that this is what we expect it to be */ | 282 | /* verify that this is what we expect it to be */ |
283 | if (((jmp[0] & 0xffff0000) != 0x3d600000) || | 283 | if (((jmp[0] & 0xffff0000) != 0x3d600000) || |
@@ -293,7 +293,7 @@ __ftrace_make_nop(struct module *mod, | |||
293 | if (tramp & 0x8000) | 293 | if (tramp & 0x8000) |
294 | tramp -= 0x10000; | 294 | tramp -= 0x10000; |
295 | 295 | ||
296 | pr_debug(" %lx ", tramp); | 296 | pr_devel(" %lx ", tramp); |
297 | 297 | ||
298 | if (tramp != addr) { | 298 | if (tramp != addr) { |
299 | printk(KERN_ERR | 299 | printk(KERN_ERR |
@@ -402,7 +402,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
402 | /* ld r2,40(r1) */ | 402 | /* ld r2,40(r1) */ |
403 | op[1] = 0xe8410028; | 403 | op[1] = 0xe8410028; |
404 | 404 | ||
405 | pr_debug("write to %lx\n", rec->ip); | 405 | pr_devel("write to %lx\n", rec->ip); |
406 | 406 | ||
407 | if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2)) | 407 | if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2)) |
408 | return -EPERM; | 408 | return -EPERM; |
@@ -442,7 +442,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
442 | return -EINVAL; | 442 | return -EINVAL; |
443 | } | 443 | } |
444 | 444 | ||
445 | pr_debug("write to %lx\n", rec->ip); | 445 | pr_devel("write to %lx\n", rec->ip); |
446 | 446 | ||
447 | if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) | 447 | if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) |
448 | return -EPERM; | 448 | return -EPERM; |
@@ -594,7 +594,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | |||
594 | PPC_LONG "2b,4b\n" | 594 | PPC_LONG "2b,4b\n" |
595 | ".previous" | 595 | ".previous" |
596 | 596 | ||
597 | : [old] "=r" (old), [faulted] "=r" (faulted) | 597 | : [old] "=&r" (old), [faulted] "=r" (faulted) |
598 | : [parent] "r" (parent), [return_hooker] "r" (return_hooker) | 598 | : [parent] "r" (parent), [return_hooker] "r" (return_hooker) |
599 | : "memory" | 599 | : "memory" |
600 | ); | 600 | ); |
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index a047a6cfca4d..8ef8a14abc95 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
@@ -264,6 +264,7 @@ SECTIONS | |||
264 | *(.data.page_aligned) | 264 | *(.data.page_aligned) |
265 | } | 265 | } |
266 | 266 | ||
267 | . = ALIGN(L1_CACHE_BYTES); | ||
267 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { | 268 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { |
268 | *(.data.cacheline_aligned) | 269 | *(.data.cacheline_aligned) |
269 | } | 270 | } |
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index f5c6fd42265c..ae1d67cc090c 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c | |||
@@ -219,7 +219,8 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, | |||
219 | entry = do_dcache_icache_coherency(entry); | 219 | entry = do_dcache_icache_coherency(entry); |
220 | changed = !pte_same(*(ptep), entry); | 220 | changed = !pte_same(*(ptep), entry); |
221 | if (changed) { | 221 | if (changed) { |
222 | assert_pte_locked(vma->vm_mm, address); | 222 | if (!(vma->vm_flags & VM_HUGETLB)) |
223 | assert_pte_locked(vma->vm_mm, address); | ||
223 | __ptep_set_access_flags(ptep, entry); | 224 | __ptep_set_access_flags(ptep, entry); |
224 | flush_tlb_page_nohash(vma, address); | 225 | flush_tlb_page_nohash(vma, address); |
225 | } | 226 | } |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 301855263b81..04296ffff8bf 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
@@ -592,3 +592,17 @@ int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) | |||
592 | } | 592 | } |
593 | return irq; | 593 | return irq; |
594 | } | 594 | } |
595 | |||
596 | static void __devinit quirk_ipr_msi(struct pci_dev *dev) | ||
597 | { | ||
598 | /* Something prevents MSIs from the IPR from working on Bimini, | ||
599 | * and the driver has no smarts to recover. So disable MSI | ||
600 | * on it for now. */ | ||
601 | |||
602 | if (machine_is(maple)) { | ||
603 | dev->no_msi = 1; | ||
604 | dev_info(&dev->dev, "Quirk disabled MSI\n"); | ||
605 | } | ||
606 | } | ||
607 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | ||
608 | quirk_ipr_msi); | ||
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index 39e46919df14..f2a29641b6a3 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c | |||
@@ -263,6 +263,9 @@ static int camera_probe(void) | |||
263 | struct i2c_msg msg; | 263 | struct i2c_msg msg; |
264 | int ret; | 264 | int ret; |
265 | 265 | ||
266 | if (!a) | ||
267 | return -ENODEV; | ||
268 | |||
266 | camera_power(1); | 269 | camera_power(1); |
267 | msg.addr = 0x6e; | 270 | msg.addr = 0x6e; |
268 | msg.buf = camera_ncm03j_magic; | 271 | msg.buf = camera_ncm03j_magic; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index df9e885eee14..a6efe0a2e9ae 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -498,6 +498,19 @@ config PARAVIRT | |||
498 | over full virtualization. However, when run without a hypervisor | 498 | over full virtualization. However, when run without a hypervisor |
499 | the kernel is theoretically slower and slightly larger. | 499 | the kernel is theoretically slower and slightly larger. |
500 | 500 | ||
501 | config PARAVIRT_SPINLOCKS | ||
502 | bool "Paravirtualization layer for spinlocks" | ||
503 | depends on PARAVIRT && SMP && EXPERIMENTAL | ||
504 | ---help--- | ||
505 | Paravirtualized spinlocks allow a pvops backend to replace the | ||
506 | spinlock implementation with something virtualization-friendly | ||
507 | (for example, block the virtual CPU rather than spinning). | ||
508 | |||
509 | Unfortunately the downside is an up to 5% performance hit on | ||
510 | native kernels, with various workloads. | ||
511 | |||
512 | If you are unsure how to answer this question, answer N. | ||
513 | |||
501 | config PARAVIRT_CLOCK | 514 | config PARAVIRT_CLOCK |
502 | bool | 515 | bool |
503 | default n | 516 | default n |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 378e3691c08c..a53da004e08e 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -1443,7 +1443,7 @@ u64 _paravirt_ident_64(u64); | |||
1443 | 1443 | ||
1444 | #define paravirt_nop ((void *)_paravirt_nop) | 1444 | #define paravirt_nop ((void *)_paravirt_nop) |
1445 | 1445 | ||
1446 | #ifdef CONFIG_SMP | 1446 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) |
1447 | 1447 | ||
1448 | static inline int __raw_spin_is_locked(struct raw_spinlock *lock) | 1448 | static inline int __raw_spin_is_locked(struct raw_spinlock *lock) |
1449 | { | 1449 | { |
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index aee103b26d01..02ecb30982a3 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
@@ -82,22 +82,22 @@ do { \ | |||
82 | case 1: \ | 82 | case 1: \ |
83 | asm(op "b %1,"__percpu_arg(0) \ | 83 | asm(op "b %1,"__percpu_arg(0) \ |
84 | : "+m" (var) \ | 84 | : "+m" (var) \ |
85 | : "ri" ((T__)val)); \ | 85 | : "qi" ((T__)(val))); \ |
86 | break; \ | 86 | break; \ |
87 | case 2: \ | 87 | case 2: \ |
88 | asm(op "w %1,"__percpu_arg(0) \ | 88 | asm(op "w %1,"__percpu_arg(0) \ |
89 | : "+m" (var) \ | 89 | : "+m" (var) \ |
90 | : "ri" ((T__)val)); \ | 90 | : "ri" ((T__)(val))); \ |
91 | break; \ | 91 | break; \ |
92 | case 4: \ | 92 | case 4: \ |
93 | asm(op "l %1,"__percpu_arg(0) \ | 93 | asm(op "l %1,"__percpu_arg(0) \ |
94 | : "+m" (var) \ | 94 | : "+m" (var) \ |
95 | : "ri" ((T__)val)); \ | 95 | : "ri" ((T__)(val))); \ |
96 | break; \ | 96 | break; \ |
97 | case 8: \ | 97 | case 8: \ |
98 | asm(op "q %1,"__percpu_arg(0) \ | 98 | asm(op "q %1,"__percpu_arg(0) \ |
99 | : "+m" (var) \ | 99 | : "+m" (var) \ |
100 | : "re" ((T__)val)); \ | 100 | : "re" ((T__)(val))); \ |
101 | break; \ | 101 | break; \ |
102 | default: __bad_percpu_size(); \ | 102 | default: __bad_percpu_size(); \ |
103 | } \ | 103 | } \ |
@@ -109,7 +109,7 @@ do { \ | |||
109 | switch (sizeof(var)) { \ | 109 | switch (sizeof(var)) { \ |
110 | case 1: \ | 110 | case 1: \ |
111 | asm(op "b "__percpu_arg(1)",%0" \ | 111 | asm(op "b "__percpu_arg(1)",%0" \ |
112 | : "=r" (ret__) \ | 112 | : "=q" (ret__) \ |
113 | : "m" (var)); \ | 113 | : "m" (var)); \ |
114 | break; \ | 114 | break; \ |
115 | case 2: \ | 115 | case 2: \ |
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index e304b66abeea..624f133943ed 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -187,14 +187,15 @@ static inline int v8086_mode(struct pt_regs *regs) | |||
187 | 187 | ||
188 | /* | 188 | /* |
189 | * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode | 189 | * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode |
190 | * when it traps. So regs will be the current sp. | 190 | * when it traps. The previous stack will be directly underneath the saved |
191 | * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. | ||
191 | * | 192 | * |
192 | * This is valid only for kernel mode traps. | 193 | * This is valid only for kernel mode traps. |
193 | */ | 194 | */ |
194 | static inline unsigned long kernel_trap_sp(struct pt_regs *regs) | 195 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) |
195 | { | 196 | { |
196 | #ifdef CONFIG_X86_32 | 197 | #ifdef CONFIG_X86_32 |
197 | return (unsigned long)regs; | 198 | return (unsigned long)(®s->sp); |
198 | #else | 199 | #else |
199 | return regs->sp; | 200 | return regs->sp; |
200 | #endif | 201 | #endif |
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index e5e6caffec87..b7e5db876399 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h | |||
@@ -172,7 +172,7 @@ static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) | |||
172 | return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1; | 172 | return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1; |
173 | } | 173 | } |
174 | 174 | ||
175 | #ifndef CONFIG_PARAVIRT | 175 | #ifndef CONFIG_PARAVIRT_SPINLOCKS |
176 | 176 | ||
177 | static inline int __raw_spin_is_locked(raw_spinlock_t *lock) | 177 | static inline int __raw_spin_is_locked(raw_spinlock_t *lock) |
178 | { | 178 | { |
@@ -206,7 +206,7 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, | |||
206 | __raw_spin_lock(lock); | 206 | __raw_spin_lock(lock); |
207 | } | 207 | } |
208 | 208 | ||
209 | #endif | 209 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ |
210 | 210 | ||
211 | static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) | 211 | static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) |
212 | { | 212 | { |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 145cce75cda7..88d1bfc847d3 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -89,7 +89,8 @@ obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o | |||
89 | obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o | 89 | obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o |
90 | obj-$(CONFIG_KVM_GUEST) += kvm.o | 90 | obj-$(CONFIG_KVM_GUEST) += kvm.o |
91 | obj-$(CONFIG_KVM_CLOCK) += kvmclock.o | 91 | obj-$(CONFIG_KVM_CLOCK) += kvmclock.o |
92 | obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o paravirt-spinlocks.o | 92 | obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o |
93 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o | ||
93 | obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o | 94 | obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o |
94 | 95 | ||
95 | obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o | 96 | obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 1c11b819f245..302947775575 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -254,7 +254,7 @@ static int parse_unisys_oem(char *oemptr) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | #ifdef CONFIG_ACPI | 256 | #ifdef CONFIG_ACPI |
257 | static int find_unisys_acpi_oem_table(unsigned long *oem_addr) | 257 | static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) |
258 | { | 258 | { |
259 | struct acpi_table_header *header = NULL; | 259 | struct acpi_table_header *header = NULL; |
260 | struct es7000_oem_table *table; | 260 | struct es7000_oem_table *table; |
@@ -285,7 +285,7 @@ static int find_unisys_acpi_oem_table(unsigned long *oem_addr) | |||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | static void unmap_unisys_acpi_oem_table(unsigned long oem_addr) | 288 | static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) |
289 | { | 289 | { |
290 | if (!oem_addr) | 290 | if (!oem_addr) |
291 | return; | 291 | return; |
@@ -306,7 +306,7 @@ static int es7000_check_dsdt(void) | |||
306 | static int es7000_acpi_ret; | 306 | static int es7000_acpi_ret; |
307 | 307 | ||
308 | /* Hook from generic ACPI tables.c */ | 308 | /* Hook from generic ACPI tables.c */ |
309 | static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 309 | static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
310 | { | 310 | { |
311 | unsigned long oem_addr = 0; | 311 | unsigned long oem_addr = 0; |
312 | int check_dsdt; | 312 | int check_dsdt; |
@@ -717,7 +717,7 @@ struct apic apic_es7000_cluster = { | |||
717 | .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, | 717 | .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, |
718 | }; | 718 | }; |
719 | 719 | ||
720 | struct apic apic_es7000 = { | 720 | struct apic __refdata apic_es7000 = { |
721 | 721 | ||
722 | .name = "es7000", | 722 | .name = "es7000", |
723 | .probe = probe_es7000, | 723 | .probe = probe_es7000, |
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 0b776c09aff3..d21d4fb161f7 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -275,7 +275,11 @@ static void __init print_mtrr_state(void) | |||
275 | } | 275 | } |
276 | printk(KERN_DEBUG "MTRR variable ranges %sabled:\n", | 276 | printk(KERN_DEBUG "MTRR variable ranges %sabled:\n", |
277 | mtrr_state.enabled & 2 ? "en" : "dis"); | 277 | mtrr_state.enabled & 2 ? "en" : "dis"); |
278 | high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4; | 278 | if (size_or_mask & 0xffffffffUL) |
279 | high_width = ffs(size_or_mask & 0xffffffffUL) - 1; | ||
280 | else | ||
281 | high_width = ffs(size_or_mask>>32) + 32 - 1; | ||
282 | high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4; | ||
279 | for (i = 0; i < num_var_ranges; ++i) { | 283 | for (i = 0; i < num_var_ranges; ++i) { |
280 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) | 284 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) |
281 | printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n", | 285 | printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n", |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 18dfa30795c9..b79c5533c421 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -442,7 +442,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | |||
442 | _ASM_EXTABLE(1b, 4b) | 442 | _ASM_EXTABLE(1b, 4b) |
443 | _ASM_EXTABLE(2b, 4b) | 443 | _ASM_EXTABLE(2b, 4b) |
444 | 444 | ||
445 | : [old] "=r" (old), [faulted] "=r" (faulted) | 445 | : [old] "=&r" (old), [faulted] "=r" (faulted) |
446 | : [parent] "r" (parent), [return_hooker] "r" (return_hooker) | 446 | : [parent] "r" (parent), [return_hooker] "r" (return_hooker) |
447 | : "memory" | 447 | : "memory" |
448 | ); | 448 | ); |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 8e45f4464880..9faf43bea336 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -134,7 +134,9 @@ static void *get_call_destination(u8 type) | |||
134 | .pv_irq_ops = pv_irq_ops, | 134 | .pv_irq_ops = pv_irq_ops, |
135 | .pv_apic_ops = pv_apic_ops, | 135 | .pv_apic_ops = pv_apic_ops, |
136 | .pv_mmu_ops = pv_mmu_ops, | 136 | .pv_mmu_ops = pv_mmu_ops, |
137 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | ||
137 | .pv_lock_ops = pv_lock_ops, | 138 | .pv_lock_ops = pv_lock_ops, |
139 | #endif | ||
138 | }; | 140 | }; |
139 | return *((void **)&tmpl + type); | 141 | return *((void **)&tmpl + type); |
140 | } | 142 | } |
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index 04df67f8a7ba..044897be021f 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c | |||
@@ -76,9 +76,9 @@ void | |||
76 | x86_backtrace(struct pt_regs * const regs, unsigned int depth) | 76 | x86_backtrace(struct pt_regs * const regs, unsigned int depth) |
77 | { | 77 | { |
78 | struct frame_head *head = (struct frame_head *)frame_pointer(regs); | 78 | struct frame_head *head = (struct frame_head *)frame_pointer(regs); |
79 | unsigned long stack = kernel_trap_sp(regs); | ||
80 | 79 | ||
81 | if (!user_mode_vm(regs)) { | 80 | if (!user_mode_vm(regs)) { |
81 | unsigned long stack = kernel_stack_pointer(regs); | ||
82 | if (depth) | 82 | if (depth) |
83 | dump_trace(NULL, regs, (unsigned long *)stack, 0, | 83 | dump_trace(NULL, regs, (unsigned long *)stack, 0, |
84 | &backtrace_ops, &depth); | 84 | &backtrace_ops, &depth); |
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 3b767d03fd6a..172438f86a02 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
@@ -9,5 +9,6 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ | |||
9 | time.o xen-asm.o xen-asm_$(BITS).o \ | 9 | time.o xen-asm.o xen-asm_$(BITS).o \ |
10 | grant-table.o suspend.o | 10 | grant-table.o suspend.o |
11 | 11 | ||
12 | obj-$(CONFIG_SMP) += smp.o spinlock.o | 12 | obj-$(CONFIG_SMP) += smp.o |
13 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o \ No newline at end of file | 13 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
14 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index e25a78e1113a..fba55b1a4021 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
43 | #include <linux/debugfs.h> | 43 | #include <linux/debugfs.h> |
44 | #include <linux/bug.h> | 44 | #include <linux/bug.h> |
45 | #include <linux/module.h> | ||
45 | 46 | ||
46 | #include <asm/pgtable.h> | 47 | #include <asm/pgtable.h> |
47 | #include <asm/tlbflush.h> | 48 | #include <asm/tlbflush.h> |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 20139464943c..ca6596b05d53 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -62,15 +62,26 @@ void xen_setup_vcpu_info_placement(void); | |||
62 | #ifdef CONFIG_SMP | 62 | #ifdef CONFIG_SMP |
63 | void xen_smp_init(void); | 63 | void xen_smp_init(void); |
64 | 64 | ||
65 | void __init xen_init_spinlocks(void); | ||
66 | __cpuinit void xen_init_lock_cpu(int cpu); | ||
67 | void xen_uninit_lock_cpu(int cpu); | ||
68 | |||
69 | extern cpumask_var_t xen_cpu_initialized_map; | 65 | extern cpumask_var_t xen_cpu_initialized_map; |
70 | #else | 66 | #else |
71 | static inline void xen_smp_init(void) {} | 67 | static inline void xen_smp_init(void) {} |
72 | #endif | 68 | #endif |
73 | 69 | ||
70 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | ||
71 | void __init xen_init_spinlocks(void); | ||
72 | __cpuinit void xen_init_lock_cpu(int cpu); | ||
73 | void xen_uninit_lock_cpu(int cpu); | ||
74 | #else | ||
75 | static inline void xen_init_spinlocks(void) | ||
76 | { | ||
77 | } | ||
78 | static inline void xen_init_lock_cpu(int cpu) | ||
79 | { | ||
80 | } | ||
81 | static inline void xen_uninit_lock_cpu(int cpu) | ||
82 | { | ||
83 | } | ||
84 | #endif | ||
74 | 85 | ||
75 | /* Declare an asm function, along with symbols needed to make it | 86 | /* Declare an asm function, along with symbols needed to make it |
76 | inlineable */ | 87 | inlineable */ |
diff --git a/crypto/api.c b/crypto/api.c index 314dab96840e..fd2545decb28 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
@@ -221,7 +221,8 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask) | |||
221 | 221 | ||
222 | request_module(name); | 222 | request_module(name); |
223 | 223 | ||
224 | if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask) && | 224 | if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask & |
225 | CRYPTO_ALG_NEED_FALLBACK) && | ||
225 | snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp)) | 226 | snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp)) |
226 | request_module(tmp); | 227 | request_module(tmp); |
227 | 228 | ||
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c index 2a342c8e52b3..3ca3b669d5d5 100644 --- a/crypto/eseqiv.c +++ b/crypto/eseqiv.c | |||
@@ -153,7 +153,8 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) | |||
153 | if (err) | 153 | if (err) |
154 | goto out; | 154 | goto out; |
155 | 155 | ||
156 | eseqiv_complete2(req); | 156 | if (giv != req->giv) |
157 | eseqiv_complete2(req); | ||
157 | 158 | ||
158 | out: | 159 | out: |
159 | return err; | 160 | return err; |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 17e50824a6f1..72ac28da14e3 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -5,40 +5,43 @@ | |||
5 | ccflags-y := -Os | 5 | ccflags-y := -Os |
6 | ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT | 6 | ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT |
7 | 7 | ||
8 | obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ | 8 | # use acpi.o to put all files here into acpi.o modparam namespace |
9 | obj-y += acpi.o | ||
10 | |||
11 | acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ | ||
9 | dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ | 12 | dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ |
10 | dsinit.o | 13 | dsinit.o |
11 | 14 | ||
12 | obj-y += evevent.o evregion.o evsci.o evxfevnt.o \ | 15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ |
13 | evmisc.o evrgnini.o evxface.o evxfregn.o \ | 16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ |
14 | evgpe.o evgpeblk.o | 17 | evgpe.o evgpeblk.o |
15 | 18 | ||
16 | obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | 19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ |
17 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ | 20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ |
18 | excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ | 21 | excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ |
19 | exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o | 22 | exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o |
20 | 23 | ||
21 | obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o | 24 | acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o |
22 | 25 | ||
23 | obj-$(ACPI_FUTURE_USAGE) += hwtimer.o | 26 | acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o |
24 | 27 | ||
25 | obj-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ | 28 | acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ |
26 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ | 29 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ |
27 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ | 30 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ |
28 | nsparse.o nspredef.o | 31 | nsparse.o nspredef.o |
29 | 32 | ||
30 | obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o | 33 | acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o |
31 | 34 | ||
32 | obj-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ | 35 | acpi-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ |
33 | psopcode.o psscope.o psutils.o psxface.o | 36 | psopcode.o psscope.o psutils.o psxface.o |
34 | 37 | ||
35 | obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ | 38 | acpi-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ |
36 | rscalc.o rsirq.o rsmemory.o rsutils.o | 39 | rscalc.o rsirq.o rsmemory.o rsutils.o |
37 | 40 | ||
38 | obj-$(ACPI_FUTURE_USAGE) += rsdump.o | 41 | acpi-$(ACPI_FUTURE_USAGE) += rsdump.o |
39 | 42 | ||
40 | obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o | 43 | acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o |
41 | 44 | ||
42 | obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
43 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ | 46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ |
44 | utstate.o utmutex.o utobject.o utresrc.o utlock.o | 47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 772ee5c4ccca..2ec394a328e9 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -787,7 +787,12 @@ struct acpi_bit_register_info { | |||
787 | 787 | ||
788 | /* For control registers, both ignored and reserved bits must be preserved */ | 788 | /* For control registers, both ignored and reserved bits must be preserved */ |
789 | 789 | ||
790 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */ | 790 | /* |
791 | * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) | ||
792 | * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly | ||
793 | * as a BIOS workaround on some machines. | ||
794 | */ | ||
795 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ | ||
791 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ | 796 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ |
792 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ | 797 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ |
793 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) | 798 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e8f7b64e92da..ae862f1798dc 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -312,7 +312,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
312 | end: | 312 | end: |
313 | if (result) | 313 | if (result) |
314 | printk(KERN_WARNING PREFIX | 314 | printk(KERN_WARNING PREFIX |
315 | "Transitioning device [%s] to D%d\n", | 315 | "Device [%s] failed to transition to D%d\n", |
316 | device->pnp.bus_id, state); | 316 | device->pnp.bus_id, state); |
317 | else { | 317 | else { |
318 | device->power.state = state; | 318 | device->power.state = state; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f7ca8c55956b..72069ba5f1ed 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -202,21 +202,44 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, | |||
202 | * Suspend / resume control | 202 | * Suspend / resume control |
203 | */ | 203 | */ |
204 | static int acpi_idle_suspend; | 204 | static int acpi_idle_suspend; |
205 | static u32 saved_bm_rld; | ||
206 | |||
207 | static void acpi_idle_bm_rld_save(void) | ||
208 | { | ||
209 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); | ||
210 | } | ||
211 | static void acpi_idle_bm_rld_restore(void) | ||
212 | { | ||
213 | u32 resumed_bm_rld; | ||
214 | |||
215 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); | ||
216 | |||
217 | if (resumed_bm_rld != saved_bm_rld) | ||
218 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); | ||
219 | } | ||
205 | 220 | ||
206 | int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) | 221 | int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) |
207 | { | 222 | { |
223 | if (acpi_idle_suspend == 1) | ||
224 | return 0; | ||
225 | |||
226 | acpi_idle_bm_rld_save(); | ||
208 | acpi_idle_suspend = 1; | 227 | acpi_idle_suspend = 1; |
209 | return 0; | 228 | return 0; |
210 | } | 229 | } |
211 | 230 | ||
212 | int acpi_processor_resume(struct acpi_device * device) | 231 | int acpi_processor_resume(struct acpi_device * device) |
213 | { | 232 | { |
233 | if (acpi_idle_suspend == 0) | ||
234 | return 0; | ||
235 | |||
236 | acpi_idle_bm_rld_restore(); | ||
214 | acpi_idle_suspend = 0; | 237 | acpi_idle_suspend = 0; |
215 | return 0; | 238 | return 0; |
216 | } | 239 | } |
217 | 240 | ||
218 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) | 241 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) |
219 | static int tsc_halts_in_c(int state) | 242 | static void tsc_check_state(int state) |
220 | { | 243 | { |
221 | switch (boot_cpu_data.x86_vendor) { | 244 | switch (boot_cpu_data.x86_vendor) { |
222 | case X86_VENDOR_AMD: | 245 | case X86_VENDOR_AMD: |
@@ -226,13 +249,17 @@ static int tsc_halts_in_c(int state) | |||
226 | * C/P/S0/S1 states when this bit is set. | 249 | * C/P/S0/S1 states when this bit is set. |
227 | */ | 250 | */ |
228 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | 251 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
229 | return 0; | 252 | return; |
230 | 253 | ||
231 | /*FALL THROUGH*/ | 254 | /*FALL THROUGH*/ |
232 | default: | 255 | default: |
233 | return state > ACPI_STATE_C1; | 256 | /* TSC could halt in idle, so notify users */ |
257 | if (state > ACPI_STATE_C1) | ||
258 | mark_tsc_unstable("TSC halts in idle"); | ||
234 | } | 259 | } |
235 | } | 260 | } |
261 | #else | ||
262 | static void tsc_check_state(int state) { return; } | ||
236 | #endif | 263 | #endif |
237 | 264 | ||
238 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | 265 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) |
@@ -578,14 +605,9 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
578 | 605 | ||
579 | pr->power.timer_broadcast_on_state = INT_MAX; | 606 | pr->power.timer_broadcast_on_state = INT_MAX; |
580 | 607 | ||
581 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { | 608 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { |
582 | struct acpi_processor_cx *cx = &pr->power.states[i]; | 609 | struct acpi_processor_cx *cx = &pr->power.states[i]; |
583 | 610 | ||
584 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) | ||
585 | /* TSC could halt in idle, so notify users */ | ||
586 | if (tsc_halts_in_c(cx->type)) | ||
587 | mark_tsc_unstable("TSC halts in idle");; | ||
588 | #endif | ||
589 | switch (cx->type) { | 611 | switch (cx->type) { |
590 | case ACPI_STATE_C1: | 612 | case ACPI_STATE_C1: |
591 | cx->valid = 1; | 613 | cx->valid = 1; |
@@ -603,6 +625,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
603 | acpi_timer_check_state(i, pr, cx); | 625 | acpi_timer_check_state(i, pr, cx); |
604 | break; | 626 | break; |
605 | } | 627 | } |
628 | if (cx->valid) | ||
629 | tsc_check_state(cx->type); | ||
606 | 630 | ||
607 | if (cx->valid) | 631 | if (cx->valid) |
608 | working++; | 632 | working++; |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index d0d1f4d50434..7f16f5f8e7d3 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -45,6 +45,14 @@ | |||
45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
46 | ACPI_MODULE_NAME("processor_throttling"); | 46 | ACPI_MODULE_NAME("processor_throttling"); |
47 | 47 | ||
48 | /* ignore_tpc: | ||
49 | * 0 -> acpi processor driver doesn't ignore _TPC values | ||
50 | * 1 -> acpi processor driver ignores _TPC values | ||
51 | */ | ||
52 | static int ignore_tpc; | ||
53 | module_param(ignore_tpc, int, 0644); | ||
54 | MODULE_PARM_DESC(ignore_tpc, "Disable broken BIOS _TPC throttling support"); | ||
55 | |||
48 | struct throttling_tstate { | 56 | struct throttling_tstate { |
49 | unsigned int cpu; /* cpu nr */ | 57 | unsigned int cpu; /* cpu nr */ |
50 | int target_state; /* target T-state */ | 58 | int target_state; /* target T-state */ |
@@ -283,6 +291,10 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) | |||
283 | 291 | ||
284 | if (!pr) | 292 | if (!pr) |
285 | return -EINVAL; | 293 | return -EINVAL; |
294 | |||
295 | if (ignore_tpc) | ||
296 | goto end; | ||
297 | |||
286 | status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc); | 298 | status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc); |
287 | if (ACPI_FAILURE(status)) { | 299 | if (ACPI_FAILURE(status)) { |
288 | if (status != AE_NOT_FOUND) { | 300 | if (status != AE_NOT_FOUND) { |
@@ -290,6 +302,8 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) | |||
290 | } | 302 | } |
291 | return -ENODEV; | 303 | return -ENODEV; |
292 | } | 304 | } |
305 | |||
306 | end: | ||
293 | pr->throttling_platform_limit = (int)tpc; | 307 | pr->throttling_platform_limit = (int)tpc; |
294 | return 0; | 308 | return 0; |
295 | } | 309 | } |
@@ -302,6 +316,9 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr) | |||
302 | struct acpi_processor_limit *limit; | 316 | struct acpi_processor_limit *limit; |
303 | int target_state; | 317 | int target_state; |
304 | 318 | ||
319 | if (ignore_tpc) | ||
320 | return 0; | ||
321 | |||
305 | result = acpi_processor_get_platform_limit(pr); | 322 | result = acpi_processor_get_platform_limit(pr); |
306 | if (result) { | 323 | if (result) { |
307 | /* Throttling Limit is unsupported */ | 324 | /* Throttling Limit is unsupported */ |
@@ -821,6 +838,14 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) | |||
821 | ret = acpi_read_throttling_status(pr, &value); | 838 | ret = acpi_read_throttling_status(pr, &value); |
822 | if (ret >= 0) { | 839 | if (ret >= 0) { |
823 | state = acpi_get_throttling_state(pr, value); | 840 | state = acpi_get_throttling_state(pr, value); |
841 | if (state == -1) { | ||
842 | ACPI_WARNING((AE_INFO, | ||
843 | "Invalid throttling state, reset\n")); | ||
844 | state = 0; | ||
845 | ret = acpi_processor_set_throttling(pr, state); | ||
846 | if (ret) | ||
847 | return ret; | ||
848 | } | ||
824 | pr->throttling.state = state; | 849 | pr->throttling.state = state; |
825 | } | 850 | } |
826 | 851 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d7ff61c0d571..810cca90ca7f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -538,6 +538,41 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) | |||
538 | return -EINVAL; | 538 | return -EINVAL; |
539 | } | 539 | } |
540 | 540 | ||
541 | /* | ||
542 | * For some buggy _BQC methods, we need to add a constant value to | ||
543 | * the _BQC return value to get the actual current brightness level | ||
544 | */ | ||
545 | |||
546 | static int bqc_offset_aml_bug_workaround; | ||
547 | static int __init video_set_bqc_offset(const struct dmi_system_id *d) | ||
548 | { | ||
549 | bqc_offset_aml_bug_workaround = 9; | ||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static struct dmi_system_id video_dmi_table[] __initdata = { | ||
554 | /* | ||
555 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 | ||
556 | */ | ||
557 | { | ||
558 | .callback = video_set_bqc_offset, | ||
559 | .ident = "Acer Aspire 5720", | ||
560 | .matches = { | ||
561 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
562 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), | ||
563 | }, | ||
564 | }, | ||
565 | { | ||
566 | .callback = video_set_bqc_offset, | ||
567 | .ident = "Acer Aspire 5710Z", | ||
568 | .matches = { | ||
569 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
570 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), | ||
571 | }, | ||
572 | }, | ||
573 | {} | ||
574 | }; | ||
575 | |||
541 | static int | 576 | static int |
542 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | 577 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, |
543 | unsigned long long *level) | 578 | unsigned long long *level) |
@@ -557,6 +592,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
557 | *level = device->brightness->levels[*level + 2]; | 592 | *level = device->brightness->levels[*level + 2]; |
558 | 593 | ||
559 | } | 594 | } |
595 | *level += bqc_offset_aml_bug_workaround; | ||
560 | device->brightness->curr = *level; | 596 | device->brightness->curr = *level; |
561 | return 0; | 597 | return 0; |
562 | } else { | 598 | } else { |
@@ -2290,6 +2326,8 @@ EXPORT_SYMBOL(acpi_video_register); | |||
2290 | 2326 | ||
2291 | static int __init acpi_video_init(void) | 2327 | static int __init acpi_video_init(void) |
2292 | { | 2328 | { |
2329 | dmi_check_system(video_dmi_table); | ||
2330 | |||
2293 | if (intel_opregion_present()) | 2331 | if (intel_opregion_present()) |
2294 | return 0; | 2332 | return 0; |
2295 | 2333 | ||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 8f905089b72b..a6cbf7b808e6 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -934,8 +934,6 @@ static void blkfront_closing(struct xenbus_device *dev) | |||
934 | 934 | ||
935 | spin_lock_irqsave(&blkif_io_lock, flags); | 935 | spin_lock_irqsave(&blkif_io_lock, flags); |
936 | 936 | ||
937 | del_gendisk(info->gd); | ||
938 | |||
939 | /* No more blkif_request(). */ | 937 | /* No more blkif_request(). */ |
940 | blk_stop_queue(info->rq); | 938 | blk_stop_queue(info->rq); |
941 | 939 | ||
@@ -949,6 +947,8 @@ static void blkfront_closing(struct xenbus_device *dev) | |||
949 | blk_cleanup_queue(info->rq); | 947 | blk_cleanup_queue(info->rq); |
950 | info->rq = NULL; | 948 | info->rq = NULL; |
951 | 949 | ||
950 | del_gendisk(info->gd); | ||
951 | |||
952 | out: | 952 | out: |
953 | xenbus_frontend_closed(dev); | 953 | xenbus_frontend_closed(dev); |
954 | } | 954 | } |
@@ -977,8 +977,10 @@ static void backend_changed(struct xenbus_device *dev, | |||
977 | break; | 977 | break; |
978 | 978 | ||
979 | case XenbusStateClosing: | 979 | case XenbusStateClosing: |
980 | if (info->gd == NULL) | 980 | if (info->gd == NULL) { |
981 | xenbus_dev_fatal(dev, -ENODEV, "gd is NULL"); | 981 | xenbus_frontend_closed(dev); |
982 | break; | ||
983 | } | ||
982 | bd = bdget_disk(info->gd, 0); | 984 | bd = bdget_disk(info->gd, 0); |
983 | if (bd == NULL) | 985 | if (bd == NULL) |
984 | xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); | 986 | xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 13929356135c..9b1624e0ddeb 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -587,7 +587,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
587 | struct device_node *node = vdev->dev.archdata.of_node; | 587 | struct device_node *node = vdev->dev.archdata.of_node; |
588 | 588 | ||
589 | deviceno = vdev->unit_address; | 589 | deviceno = vdev->unit_address; |
590 | if (deviceno > VIOCD_MAX_CD) | 590 | if (deviceno >= VIOCD_MAX_CD) |
591 | return -ENODEV; | 591 | return -ENODEV; |
592 | if (!node) | 592 | if (!node) |
593 | return -ENODEV; | 593 | return -ENODEV; |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index aa83a0865ec1..09050797c76a 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -2856,6 +2856,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2856 | /* Assume a single IPMB channel at zero. */ | 2856 | /* Assume a single IPMB channel at zero. */ |
2857 | intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB; | 2857 | intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB; |
2858 | intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB; | 2858 | intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB; |
2859 | intf->curr_channel = IPMI_MAX_CHANNELS; | ||
2859 | } | 2860 | } |
2860 | 2861 | ||
2861 | if (rv == 0) | 2862 | if (rv == 0) |
@@ -3648,13 +3649,13 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3648 | } | 3649 | } |
3649 | 3650 | ||
3650 | /* | 3651 | /* |
3651 | ** We need to make sure the channels have been initialized. | 3652 | * We need to make sure the channels have been initialized. |
3652 | ** The channel_handler routine will set the "curr_channel" | 3653 | * The channel_handler routine will set the "curr_channel" |
3653 | ** equal to or greater than IPMI_MAX_CHANNELS when all the | 3654 | * equal to or greater than IPMI_MAX_CHANNELS when all the |
3654 | ** channels for this interface have been initialized. | 3655 | * channels for this interface have been initialized. |
3655 | */ | 3656 | */ |
3656 | if (intf->curr_channel < IPMI_MAX_CHANNELS) { | 3657 | if (intf->curr_channel < IPMI_MAX_CHANNELS) { |
3657 | requeue = 1; /* Just put the message back for now */ | 3658 | requeue = 0; /* Throw the message away */ |
3658 | goto out; | 3659 | goto out; |
3659 | } | 3660 | } |
3660 | 3661 | ||
diff --git a/drivers/char/random.c b/drivers/char/random.c index b2ced39d76b2..8c7444857a4b 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1673,7 +1673,7 @@ unsigned int get_random_int(void) | |||
1673 | int ret; | 1673 | int ret; |
1674 | 1674 | ||
1675 | keyptr = get_keyptr(); | 1675 | keyptr = get_keyptr(); |
1676 | hash[0] += current->pid + jiffies + get_cycles() + (int)(long)&ret; | 1676 | hash[0] += current->pid + jiffies + get_cycles(); |
1677 | 1677 | ||
1678 | ret = half_md4_transform(hash, keyptr->secret); | 1678 | ret = half_md4_transform(hash, keyptr->secret); |
1679 | put_cpu_var(get_random_int_hash); | 1679 | put_cpu_var(get_random_int_hash); |
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index ed306eb1057f..0c2f55a38b95 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c | |||
@@ -212,7 +212,8 @@ static int get_event_name(char *dest, struct tcpa_event *event, | |||
212 | unsigned char * event_entry) | 212 | unsigned char * event_entry) |
213 | { | 213 | { |
214 | const char *name = ""; | 214 | const char *name = ""; |
215 | char data[40] = ""; | 215 | /* 41 so there is room for 40 data and 1 nul */ |
216 | char data[41] = ""; | ||
216 | int i, n_len = 0, d_len = 0; | 217 | int i, n_len = 0, d_len = 0; |
217 | struct tcpa_pc_event *pc_event; | 218 | struct tcpa_pc_event *pc_event; |
218 | 219 | ||
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index f9f05d7a707d..6c6656d3b1e2 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c | |||
@@ -415,6 +415,7 @@ static void crypto_done_action(unsigned long arg) | |||
415 | static int init_ixp_crypto(void) | 415 | static int init_ixp_crypto(void) |
416 | { | 416 | { |
417 | int ret = -ENODEV; | 417 | int ret = -ENODEV; |
418 | u32 msg[2] = { 0, 0 }; | ||
418 | 419 | ||
419 | if (! ( ~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH | | 420 | if (! ( ~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH | |
420 | IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) { | 421 | IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) { |
@@ -426,9 +427,35 @@ static int init_ixp_crypto(void) | |||
426 | return ret; | 427 | return ret; |
427 | 428 | ||
428 | if (!npe_running(npe_c)) { | 429 | if (!npe_running(npe_c)) { |
429 | npe_load_firmware(npe_c, npe_name(npe_c), dev); | 430 | ret = npe_load_firmware(npe_c, npe_name(npe_c), dev); |
431 | if (ret) { | ||
432 | return ret; | ||
433 | } | ||
434 | if (npe_recv_message(npe_c, msg, "STATUS_MSG")) | ||
435 | goto npe_error; | ||
436 | } else { | ||
437 | if (npe_send_message(npe_c, msg, "STATUS_MSG")) | ||
438 | goto npe_error; | ||
439 | |||
440 | if (npe_recv_message(npe_c, msg, "STATUS_MSG")) | ||
441 | goto npe_error; | ||
430 | } | 442 | } |
431 | 443 | ||
444 | switch ((msg[1]>>16) & 0xff) { | ||
445 | case 3: | ||
446 | printk(KERN_WARNING "Firmware of %s lacks AES support\n", | ||
447 | npe_name(npe_c)); | ||
448 | support_aes = 0; | ||
449 | break; | ||
450 | case 4: | ||
451 | case 5: | ||
452 | support_aes = 1; | ||
453 | break; | ||
454 | default: | ||
455 | printk(KERN_ERR "Firmware of %s lacks crypto support\n", | ||
456 | npe_name(npe_c)); | ||
457 | return -ENODEV; | ||
458 | } | ||
432 | /* buffer_pool will also be used to sometimes store the hmac, | 459 | /* buffer_pool will also be used to sometimes store the hmac, |
433 | * so assure it is large enough | 460 | * so assure it is large enough |
434 | */ | 461 | */ |
@@ -459,6 +486,10 @@ static int init_ixp_crypto(void) | |||
459 | 486 | ||
460 | qmgr_enable_irq(RECV_QID); | 487 | qmgr_enable_irq(RECV_QID); |
461 | return 0; | 488 | return 0; |
489 | |||
490 | npe_error: | ||
491 | printk(KERN_ERR "%s not responding\n", npe_name(npe_c)); | ||
492 | ret = -EIO; | ||
462 | err: | 493 | err: |
463 | if (ctx_pool) | 494 | if (ctx_pool) |
464 | dma_pool_destroy(ctx_pool); | 495 | dma_pool_destroy(ctx_pool); |
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 3f0fdd18255d..856b3cc25583 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
@@ -489,4 +489,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support"); | |||
489 | MODULE_LICENSE("GPL"); | 489 | MODULE_LICENSE("GPL"); |
490 | MODULE_AUTHOR("Michal Ludvig"); | 490 | MODULE_AUTHOR("Michal Ludvig"); |
491 | 491 | ||
492 | MODULE_ALIAS("aes-all"); | 492 | MODULE_ALIAS("aes"); |
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 17b24c580c09..4cd35d8fd799 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -84,6 +84,12 @@ config DRM_I915 | |||
84 | config DRM_I915_KMS | 84 | config DRM_I915_KMS |
85 | bool "Enable modesetting on intel by default" | 85 | bool "Enable modesetting on intel by default" |
86 | depends on DRM_I915 | 86 | depends on DRM_I915 |
87 | # i915 KMS depends on ACPI_VIDEO when ACPI is enabled | ||
88 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | ||
89 | select VIDEO_OUTPUT_CONTROL if ACPI | ||
90 | select BACKLIGHT_CLASS_DEVICE if ACPI | ||
91 | select INPUT if ACPI | ||
92 | select ACPI_VIDEO if ACPI | ||
87 | help | 93 | help |
88 | Choose this option if you want kernel modesetting enabled by default, | 94 | Choose this option if you want kernel modesetting enabled by default, |
89 | and you have a new enough userspace to support this. Running old | 95 | and you have a new enough userspace to support this. Running old |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 6d80d17f1e96..0411d912d82a 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
@@ -170,6 +170,14 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
170 | } | 170 | } |
171 | DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", | 171 | DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", |
172 | (unsigned long long)map->offset, map->size, map->type); | 172 | (unsigned long long)map->offset, map->size, map->type); |
173 | |||
174 | /* page-align _DRM_SHM maps. They are allocated here so there is no security | ||
175 | * hole created by that and it works around various broken drivers that use | ||
176 | * a non-aligned quantity to map the SAREA. --BenH | ||
177 | */ | ||
178 | if (map->type == _DRM_SHM) | ||
179 | map->size = PAGE_ALIGN(map->size); | ||
180 | |||
173 | if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { | 181 | if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { |
174 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 182 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
175 | return -EINVAL; | 183 | return -EINVAL; |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index f01def16a669..019b7c578236 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -481,7 +481,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
481 | } | 481 | } |
482 | retcode = func(dev, kdata, file_priv); | 482 | retcode = func(dev, kdata, file_priv); |
483 | 483 | ||
484 | if ((retcode == 0) && (cmd & IOC_OUT)) { | 484 | if (cmd & IOC_OUT) { |
485 | if (copy_to_user((void __user *)arg, kdata, | 485 | if (copy_to_user((void __user *)arg, kdata, |
486 | _IOC_SIZE(cmd)) != 0) | 486 | _IOC_SIZE(cmd)) != 0) |
487 | retcode = -EFAULT; | 487 | retcode = -EFAULT; |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 4e16ce68b063..36da913cc553 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c | |||
@@ -466,7 +466,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) | |||
466 | struct ide_host *host; | 466 | struct ide_host *host; |
467 | unsigned int sel = 0; | 467 | unsigned int sel = 0; |
468 | int ret; | 468 | int ret; |
469 | hw_regs_t hw[2], *hws[] = { &hw[0], NULL, NULL, NULL }; | 469 | hw_regs_t hw[2], *hws[] = { &hw[0], &hw[1], NULL, NULL }; |
470 | struct ide_port_info d = icside_v6_port_info; | 470 | struct ide_port_info d = icside_v6_port_info; |
471 | 471 | ||
472 | ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); | 472 | ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 35dc38d3b2c5..6415a2e2ba87 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -696,7 +696,7 @@ void ide_timer_expiry (unsigned long data) | |||
696 | } | 696 | } |
697 | spin_lock_irq(&hwif->lock); | 697 | spin_lock_irq(&hwif->lock); |
698 | enable_irq(hwif->irq); | 698 | enable_irq(hwif->irq); |
699 | if (startstop == ide_stopped) { | 699 | if (startstop == ide_stopped && hwif->polling == 0) { |
700 | ide_unlock_port(hwif); | 700 | ide_unlock_port(hwif); |
701 | plug_device = 1; | 701 | plug_device = 1; |
702 | } | 702 | } |
@@ -868,7 +868,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
868 | * same irq as is currently being serviced here, and Linux | 868 | * same irq as is currently being serviced here, and Linux |
869 | * won't allow another of the same (on any CPU) until we return. | 869 | * won't allow another of the same (on any CPU) until we return. |
870 | */ | 870 | */ |
871 | if (startstop == ide_stopped) { | 871 | if (startstop == ide_stopped && hwif->polling == 0) { |
872 | BUG_ON(hwif->handler); | 872 | BUG_ON(hwif->handler); |
873 | ide_unlock_port(hwif); | 873 | ide_unlock_port(hwif); |
874 | plug_device = 1; | 874 | plug_device = 1; |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c19a221b1e18..06fe002116ec 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -206,8 +206,6 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list); | |||
206 | 206 | ||
207 | /* | 207 | /* |
208 | * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. | 208 | * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. |
209 | * We list them here and depend on the device side cable detection for them. | ||
210 | * | ||
211 | * Some optical devices with the buggy firmwares have the same problem. | 209 | * Some optical devices with the buggy firmwares have the same problem. |
212 | */ | 210 | */ |
213 | static const struct drive_list_entry ivb_list[] = { | 211 | static const struct drive_list_entry ivb_list[] = { |
@@ -251,10 +249,25 @@ u8 eighty_ninty_three(ide_drive_t *drive) | |||
251 | * - force bit13 (80c cable present) check also for !ivb devices | 249 | * - force bit13 (80c cable present) check also for !ivb devices |
252 | * (unless the slave device is pre-ATA3) | 250 | * (unless the slave device is pre-ATA3) |
253 | */ | 251 | */ |
254 | if ((id[ATA_ID_HW_CONFIG] & 0x4000) || | 252 | if (id[ATA_ID_HW_CONFIG] & 0x4000) |
255 | (ivb && (id[ATA_ID_HW_CONFIG] & 0x2000))) | ||
256 | return 1; | 253 | return 1; |
257 | 254 | ||
255 | if (ivb) { | ||
256 | const char *model = (char *)&id[ATA_ID_PROD]; | ||
257 | |||
258 | if (strstr(model, "TSSTcorp CDDVDW SH-S202")) { | ||
259 | /* | ||
260 | * These ATAPI devices always report 80c cable | ||
261 | * so we have to depend on the host in this case. | ||
262 | */ | ||
263 | if (hwif->cbl == ATA_CBL_PATA80) | ||
264 | return 1; | ||
265 | } else { | ||
266 | /* Depend on the device side cable detection. */ | ||
267 | if (id[ATA_ID_HW_CONFIG] & 0x2000) | ||
268 | return 1; | ||
269 | } | ||
270 | } | ||
258 | no_80w: | 271 | no_80w: |
259 | if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED) | 272 | if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED) |
260 | return 0; | 273 | return 0; |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 56ff8c46c7d1..2148df836ce7 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -31,24 +31,6 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) | |||
31 | blk_queue_bounce_limit(drive->queue, addr); | 31 | blk_queue_bounce_limit(drive->queue, addr); |
32 | } | 32 | } |
33 | 33 | ||
34 | static void ide_dump_opcode(ide_drive_t *drive) | ||
35 | { | ||
36 | struct request *rq = drive->hwif->rq; | ||
37 | struct ide_cmd *cmd = NULL; | ||
38 | |||
39 | if (!rq) | ||
40 | return; | ||
41 | |||
42 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | ||
43 | cmd = rq->special; | ||
44 | |||
45 | printk(KERN_ERR "ide: failed opcode was: "); | ||
46 | if (cmd == NULL) | ||
47 | printk(KERN_CONT "unknown\n"); | ||
48 | else | ||
49 | printk(KERN_CONT "0x%02x\n", cmd->tf.command); | ||
50 | } | ||
51 | |||
52 | u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48) | 34 | u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48) |
53 | { | 35 | { |
54 | struct ide_taskfile *tf = &cmd->tf; | 36 | struct ide_taskfile *tf = &cmd->tf; |
@@ -91,7 +73,7 @@ static void ide_dump_sector(ide_drive_t *drive) | |||
91 | 73 | ||
92 | static void ide_dump_ata_error(ide_drive_t *drive, u8 err) | 74 | static void ide_dump_ata_error(ide_drive_t *drive, u8 err) |
93 | { | 75 | { |
94 | printk(KERN_ERR "{ "); | 76 | printk(KERN_CONT "{ "); |
95 | if (err & ATA_ABORTED) | 77 | if (err & ATA_ABORTED) |
96 | printk(KERN_CONT "DriveStatusError "); | 78 | printk(KERN_CONT "DriveStatusError "); |
97 | if (err & ATA_ICRC) | 79 | if (err & ATA_ICRC) |
@@ -121,7 +103,7 @@ static void ide_dump_ata_error(ide_drive_t *drive, u8 err) | |||
121 | 103 | ||
122 | static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) | 104 | static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) |
123 | { | 105 | { |
124 | printk(KERN_ERR "{ "); | 106 | printk(KERN_CONT "{ "); |
125 | if (err & ATAPI_ILI) | 107 | if (err & ATAPI_ILI) |
126 | printk(KERN_CONT "IllegalLengthIndication "); | 108 | printk(KERN_CONT "IllegalLengthIndication "); |
127 | if (err & ATAPI_EOM) | 109 | if (err & ATAPI_EOM) |
@@ -179,7 +161,10 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) | |||
179 | else | 161 | else |
180 | ide_dump_atapi_error(drive, err); | 162 | ide_dump_atapi_error(drive, err); |
181 | } | 163 | } |
182 | ide_dump_opcode(drive); | 164 | |
165 | printk(KERN_ERR "%s: possibly failed opcode: 0x%02x\n", | ||
166 | drive->name, drive->hwif->cmd.tf.command); | ||
167 | |||
183 | return err; | 168 | return err; |
184 | } | 169 | } |
185 | EXPORT_SYMBOL(ide_dump_status); | 170 | EXPORT_SYMBOL(ide_dump_status); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 7f264ed1141b..c895ed52b2e8 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -295,7 +295,7 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) | |||
295 | 295 | ||
296 | timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; | 296 | timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; |
297 | 297 | ||
298 | if (ide_busy_sleep(hwif, timeout, use_altstatus)) | 298 | if (ide_busy_sleep(drive, timeout, use_altstatus)) |
299 | return 1; | 299 | return 1; |
300 | 300 | ||
301 | /* wait for IRQ and ATA_DRQ */ | 301 | /* wait for IRQ and ATA_DRQ */ |
@@ -316,8 +316,9 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) | |||
316 | return rc; | 316 | return rc; |
317 | } | 317 | } |
318 | 318 | ||
319 | int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus) | 319 | int ide_busy_sleep(ide_drive_t *drive, unsigned long timeout, int altstatus) |
320 | { | 320 | { |
321 | ide_hwif_t *hwif = drive->hwif; | ||
321 | u8 stat; | 322 | u8 stat; |
322 | 323 | ||
323 | timeout += jiffies; | 324 | timeout += jiffies; |
@@ -330,6 +331,8 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus) | |||
330 | return 0; | 331 | return 0; |
331 | } while (time_before(jiffies, timeout)); | 332 | } while (time_before(jiffies, timeout)); |
332 | 333 | ||
334 | printk(KERN_ERR "%s: timeout in %s\n", drive->name, __func__); | ||
335 | |||
333 | return 1; /* drive timed-out */ | 336 | return 1; /* drive timed-out */ |
334 | } | 337 | } |
335 | 338 | ||
@@ -420,7 +423,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
420 | tp_ops->dev_select(drive); | 423 | tp_ops->dev_select(drive); |
421 | msleep(50); | 424 | msleep(50); |
422 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); | 425 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); |
423 | (void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0); | 426 | (void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0); |
424 | rc = ide_dev_read_id(drive, cmd, id); | 427 | rc = ide_dev_read_id(drive, cmd, id); |
425 | } | 428 | } |
426 | 429 | ||
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index cb942a9b580f..3a53e0834cf7 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -614,12 +614,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, | |||
614 | { | 614 | { |
615 | idetape_tape_t *tape = drive->driver_data; | 615 | idetape_tape_t *tape = drive->driver_data; |
616 | 616 | ||
617 | if (drive->pc->c[0] == REQUEST_SENSE && | ||
618 | pc->c[0] == REQUEST_SENSE) { | ||
619 | printk(KERN_ERR "ide-tape: possible ide-tape.c bug - " | ||
620 | "Two request sense in serial were issued\n"); | ||
621 | } | ||
622 | |||
623 | if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) | 617 | if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) |
624 | drive->failed_pc = pc; | 618 | drive->failed_pc = pc; |
625 | 619 | ||
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 2aa699933064..69860dea3820 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c | |||
@@ -263,6 +263,7 @@ static const struct ich_laptop ich_laptop[] = { | |||
263 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ | 263 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ |
264 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ | 264 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ |
265 | { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ | 265 | { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ |
266 | { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */ | ||
266 | /* end marker */ | 267 | /* end marker */ |
267 | { 0, } | 268 | { 0, } |
268 | }; | 269 | }; |
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 3ff7231e4858..028de26a25fe 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c | |||
@@ -67,6 +67,7 @@ static struct via_isa_bridge { | |||
67 | u8 udma_mask; | 67 | u8 udma_mask; |
68 | u8 flags; | 68 | u8 flags; |
69 | } via_isa_bridges[] = { | 69 | } via_isa_bridges[] = { |
70 | { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, | ||
70 | { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, | 71 | { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, |
71 | { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, | 72 | { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, |
72 | { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, | 73 | { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, |
@@ -474,6 +475,7 @@ static const struct pci_device_id via_pci_tbl[] = { | |||
474 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 }, | 475 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 }, |
475 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 }, | 476 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 }, |
476 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 }, | 477 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 }, |
478 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), 0 }, | ||
477 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 }, | 479 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 }, |
478 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 }, | 480 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 }, |
479 | { 0, }, | 481 | { 0, }, |
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index e29cdc13a199..a28c06d686e1 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
@@ -107,7 +107,7 @@ static void amba_kmi_close(struct serio *io) | |||
107 | clk_disable(kmi->clk); | 107 | clk_disable(kmi->clk); |
108 | } | 108 | } |
109 | 109 | ||
110 | static int amba_kmi_probe(struct amba_device *dev, void *id) | 110 | static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) |
111 | { | 111 | { |
112 | struct amba_kmi_port *kmi; | 112 | struct amba_kmi_port *kmi; |
113 | struct serio *io; | 113 | struct serio *io; |
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 7793932a513b..11a6248cc1c1 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c | |||
@@ -443,7 +443,7 @@ static irqreturn_t pcf50633_irq(int irq, void *data) | |||
443 | dev_dbg(pcf->dev, "pcf50633_irq\n"); | 443 | dev_dbg(pcf->dev, "pcf50633_irq\n"); |
444 | 444 | ||
445 | get_device(pcf->dev); | 445 | get_device(pcf->dev); |
446 | disable_irq(pcf->irq); | 446 | disable_irq_nosync(pcf->irq); |
447 | schedule_work(&pcf->irq_work); | 447 | schedule_work(&pcf->irq_work); |
448 | 448 | ||
449 | return IRQ_HANDLED; | 449 | return IRQ_HANDLED; |
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index c2be3088e2e1..fe24079387c5 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -79,10 +79,6 @@ static int wm8350_phys_read(struct wm8350 *wm8350, u8 reg, int num_regs, | |||
79 | /* Cache is CPU endian */ | 79 | /* Cache is CPU endian */ |
80 | dest[i - reg] = be16_to_cpu(dest[i - reg]); | 80 | dest[i - reg] = be16_to_cpu(dest[i - reg]); |
81 | 81 | ||
82 | /* Satisfy non-volatile bits from cache */ | ||
83 | dest[i - reg] &= wm8350_reg_io_map[i].vol; | ||
84 | dest[i - reg] |= wm8350->reg_cache[i]; | ||
85 | |||
86 | /* Mask out non-readable bits */ | 82 | /* Mask out non-readable bits */ |
87 | dest[i - reg] &= wm8350_reg_io_map[i].readable; | 83 | dest[i - reg] &= wm8350_reg_io_map[i].readable; |
88 | } | 84 | } |
@@ -182,9 +178,6 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src) | |||
182 | (wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable) | 178 | (wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable) |
183 | | src[i - reg]; | 179 | | src[i - reg]; |
184 | 180 | ||
185 | /* Don't store volatile bits */ | ||
186 | wm8350->reg_cache[i] &= ~wm8350_reg_io_map[i].vol; | ||
187 | |||
188 | src[i - reg] = cpu_to_be16(src[i - reg]); | 181 | src[i - reg] = cpu_to_be16(src[i - reg]); |
189 | } | 182 | } |
190 | 183 | ||
@@ -1261,7 +1254,6 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode) | |||
1261 | (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) { | 1254 | (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) { |
1262 | value = be16_to_cpu(wm8350->reg_cache[i]); | 1255 | value = be16_to_cpu(wm8350->reg_cache[i]); |
1263 | value &= wm8350_reg_io_map[i].readable; | 1256 | value &= wm8350_reg_io_map[i].readable; |
1264 | value &= ~wm8350_reg_io_map[i].vol; | ||
1265 | wm8350->reg_cache[i] = value; | 1257 | wm8350->reg_cache[i] = value; |
1266 | } else | 1258 | } else |
1267 | wm8350->reg_cache[i] = reg_map[i]; | 1259 | wm8350->reg_cache[i] = reg_map[i]; |
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 3cf61ece71d7..348443bdb23b 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c | |||
@@ -119,7 +119,7 @@ enclosure_register(struct device *dev, const char *name, int components, | |||
119 | edev->edev.class = &enclosure_class; | 119 | edev->edev.class = &enclosure_class; |
120 | edev->edev.parent = get_device(dev); | 120 | edev->edev.parent = get_device(dev); |
121 | edev->cb = cb; | 121 | edev->cb = cb; |
122 | dev_set_name(&edev->edev, name); | 122 | dev_set_name(&edev->edev, "%s", name); |
123 | err = device_register(&edev->edev); | 123 | err = device_register(&edev->edev); |
124 | if (err) | 124 | if (err) |
125 | goto err; | 125 | goto err; |
@@ -255,8 +255,8 @@ enclosure_component_register(struct enclosure_device *edev, | |||
255 | ecomp->number = number; | 255 | ecomp->number = number; |
256 | cdev = &ecomp->cdev; | 256 | cdev = &ecomp->cdev; |
257 | cdev->parent = get_device(&edev->edev); | 257 | cdev->parent = get_device(&edev->edev); |
258 | if (name) | 258 | if (name && name[0]) |
259 | dev_set_name(cdev, name); | 259 | dev_set_name(cdev, "%s", name); |
260 | else | 260 | else |
261 | dev_set_name(cdev, "%u", number); | 261 | dev_set_name(cdev, "%u", number); |
262 | 262 | ||
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 36875dcfa492..7d4febdab286 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -490,7 +490,7 @@ static void mmci_check_status(unsigned long data) | |||
490 | mod_timer(&host->timer, jiffies + HZ); | 490 | mod_timer(&host->timer, jiffies + HZ); |
491 | } | 491 | } |
492 | 492 | ||
493 | static int __devinit mmci_probe(struct amba_device *dev, void *id) | 493 | static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) |
494 | { | 494 | { |
495 | struct mmc_platform_data *plat = dev->dev.platform_data; | 495 | struct mmc_platform_data *plat = dev->dev.platform_data; |
496 | struct mmci_host *host; | 496 | struct mmci_host *host; |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 62dee54af0a5..43976aa4dbb1 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -178,7 +178,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
178 | /* Calculate flash page address; use block erase (for speed) if | 178 | /* Calculate flash page address; use block erase (for speed) if |
179 | * we're at a block boundary and need to erase the whole block. | 179 | * we're at a block boundary and need to erase the whole block. |
180 | */ | 180 | */ |
181 | pageaddr = div_u64(instr->len, priv->page_size); | 181 | pageaddr = div_u64(instr->addr, priv->page_size); |
182 | do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize; | 182 | do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize; |
183 | pageaddr = pageaddr << priv->page_offset; | 183 | pageaddr = pageaddr << priv->page_offset; |
184 | 184 | ||
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index c49ddd08b2aa..b4bb06fdf307 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -35,8 +35,22 @@ | |||
35 | #define DRV_VER "2.0.348" | 35 | #define DRV_VER "2.0.348" |
36 | #define DRV_NAME "be2net" | 36 | #define DRV_NAME "be2net" |
37 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" | 37 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" |
38 | #define OC_NAME "Emulex OneConnect 10Gbps NIC" | ||
38 | #define DRV_DESC BE_NAME "Driver" | 39 | #define DRV_DESC BE_NAME "Driver" |
39 | 40 | ||
41 | #define BE_VENDOR_ID 0x19a2 | ||
42 | #define BE_DEVICE_ID1 0x211 | ||
43 | #define OC_DEVICE_ID1 0x700 | ||
44 | #define OC_DEVICE_ID2 0x701 | ||
45 | |||
46 | static inline char *nic_name(struct pci_dev *pdev) | ||
47 | { | ||
48 | if (pdev->device == OC_DEVICE_ID1 || pdev->device == OC_DEVICE_ID2) | ||
49 | return OC_NAME; | ||
50 | else | ||
51 | return BE_NAME; | ||
52 | } | ||
53 | |||
40 | /* Number of bytes of an RX frame that are copied to skb->data */ | 54 | /* Number of bytes of an RX frame that are copied to skb->data */ |
41 | #define BE_HDR_LEN 64 | 55 | #define BE_HDR_LEN 64 |
42 | #define BE_MAX_JUMBO_FRAME_SIZE 9018 | 56 | #define BE_MAX_JUMBO_FRAME_SIZE 9018 |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 30d0c81c989e..5c378b5e8e41 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -28,10 +28,10 @@ static unsigned int rx_frag_size = 2048; | |||
28 | module_param(rx_frag_size, uint, S_IRUGO); | 28 | module_param(rx_frag_size, uint, S_IRUGO); |
29 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); | 29 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); |
30 | 30 | ||
31 | #define BE_VENDOR_ID 0x19a2 | ||
32 | #define BE2_DEVICE_ID_1 0x0211 | ||
33 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { | 31 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { |
34 | { PCI_DEVICE(BE_VENDOR_ID, BE2_DEVICE_ID_1) }, | 32 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, |
33 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, | ||
34 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, | ||
35 | { 0 } | 35 | { 0 } |
36 | }; | 36 | }; |
37 | MODULE_DEVICE_TABLE(pci, be_dev_ids); | 37 | MODULE_DEVICE_TABLE(pci, be_dev_ids); |
@@ -1859,7 +1859,7 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
1859 | if (status != 0) | 1859 | if (status != 0) |
1860 | goto stats_clean; | 1860 | goto stats_clean; |
1861 | 1861 | ||
1862 | dev_info(&pdev->dev, BE_NAME " port %d\n", adapter->port_num); | 1862 | dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); |
1863 | return 0; | 1863 | return 0; |
1864 | 1864 | ||
1865 | stats_clean: | 1865 | stats_clean: |
@@ -1873,7 +1873,7 @@ rel_reg: | |||
1873 | disable_dev: | 1873 | disable_dev: |
1874 | pci_disable_device(pdev); | 1874 | pci_disable_device(pdev); |
1875 | do_none: | 1875 | do_none: |
1876 | dev_warn(&pdev->dev, BE_NAME " initialization failed\n"); | 1876 | dev_err(&pdev->dev, "%s initialization failed\n", nic_name(pdev)); |
1877 | return status; | 1877 | return status; |
1878 | } | 1878 | } |
1879 | 1879 | ||
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 8c2e5ab51f08..faf094abef7f 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -1465,6 +1465,12 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, | |||
1465 | return best; | 1465 | return best; |
1466 | } | 1466 | } |
1467 | 1467 | ||
1468 | static int agg_device_up(const struct aggregator *agg) | ||
1469 | { | ||
1470 | return (netif_running(agg->slave->dev) && | ||
1471 | netif_carrier_ok(agg->slave->dev)); | ||
1472 | } | ||
1473 | |||
1468 | /** | 1474 | /** |
1469 | * ad_agg_selection_logic - select an aggregation group for a team | 1475 | * ad_agg_selection_logic - select an aggregation group for a team |
1470 | * @aggregator: the aggregator we're looking at | 1476 | * @aggregator: the aggregator we're looking at |
@@ -1496,14 +1502,13 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
1496 | struct port *port; | 1502 | struct port *port; |
1497 | 1503 | ||
1498 | origin = agg; | 1504 | origin = agg; |
1499 | |||
1500 | active = __get_active_agg(agg); | 1505 | active = __get_active_agg(agg); |
1501 | best = active; | 1506 | best = (active && agg_device_up(active)) ? active : NULL; |
1502 | 1507 | ||
1503 | do { | 1508 | do { |
1504 | agg->is_active = 0; | 1509 | agg->is_active = 0; |
1505 | 1510 | ||
1506 | if (agg->num_of_ports) | 1511 | if (agg->num_of_ports && agg_device_up(agg)) |
1507 | best = ad_agg_selection_test(best, agg); | 1512 | best = ad_agg_selection_test(best, agg); |
1508 | 1513 | ||
1509 | } while ((agg = __get_next_agg(agg))); | 1514 | } while ((agg = __get_next_agg(agg))); |
diff --git a/drivers/net/meth.c b/drivers/net/meth.c index aa08987f6e81..dbd3436912b8 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c | |||
@@ -127,11 +127,11 @@ static unsigned long mdio_read(struct meth_private *priv, unsigned long phyreg) | |||
127 | static int mdio_probe(struct meth_private *priv) | 127 | static int mdio_probe(struct meth_private *priv) |
128 | { | 128 | { |
129 | int i; | 129 | int i; |
130 | unsigned long p2, p3; | 130 | unsigned long p2, p3, flags; |
131 | /* check if phy is detected already */ | 131 | /* check if phy is detected already */ |
132 | if(priv->phy_addr>=0&&priv->phy_addr<32) | 132 | if(priv->phy_addr>=0&&priv->phy_addr<32) |
133 | return 0; | 133 | return 0; |
134 | spin_lock(&priv->meth_lock); | 134 | spin_lock_irqsave(&priv->meth_lock, flags); |
135 | for (i=0;i<32;++i){ | 135 | for (i=0;i<32;++i){ |
136 | priv->phy_addr=i; | 136 | priv->phy_addr=i; |
137 | p2=mdio_read(priv,2); | 137 | p2=mdio_read(priv,2); |
@@ -157,7 +157,7 @@ static int mdio_probe(struct meth_private *priv) | |||
157 | break; | 157 | break; |
158 | } | 158 | } |
159 | } | 159 | } |
160 | spin_unlock(&priv->meth_lock); | 160 | spin_unlock_irqrestore(&priv->meth_lock, flags); |
161 | if(priv->phy_addr<32) { | 161 | if(priv->phy_addr<32) { |
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
@@ -373,14 +373,14 @@ static int meth_release(struct net_device *dev) | |||
373 | static void meth_rx(struct net_device* dev, unsigned long int_status) | 373 | static void meth_rx(struct net_device* dev, unsigned long int_status) |
374 | { | 374 | { |
375 | struct sk_buff *skb; | 375 | struct sk_buff *skb; |
376 | unsigned long status; | 376 | unsigned long status, flags; |
377 | struct meth_private *priv = netdev_priv(dev); | 377 | struct meth_private *priv = netdev_priv(dev); |
378 | unsigned long fifo_rptr = (int_status & METH_INT_RX_RPTR_MASK) >> 8; | 378 | unsigned long fifo_rptr = (int_status & METH_INT_RX_RPTR_MASK) >> 8; |
379 | 379 | ||
380 | spin_lock(&priv->meth_lock); | 380 | spin_lock_irqsave(&priv->meth_lock, flags); |
381 | priv->dma_ctrl &= ~METH_DMA_RX_INT_EN; | 381 | priv->dma_ctrl &= ~METH_DMA_RX_INT_EN; |
382 | mace->eth.dma_ctrl = priv->dma_ctrl; | 382 | mace->eth.dma_ctrl = priv->dma_ctrl; |
383 | spin_unlock(&priv->meth_lock); | 383 | spin_unlock_irqrestore(&priv->meth_lock, flags); |
384 | 384 | ||
385 | if (int_status & METH_INT_RX_UNDERFLOW) { | 385 | if (int_status & METH_INT_RX_UNDERFLOW) { |
386 | fifo_rptr = (fifo_rptr - 1) & 0x0f; | 386 | fifo_rptr = (fifo_rptr - 1) & 0x0f; |
@@ -452,12 +452,12 @@ static void meth_rx(struct net_device* dev, unsigned long int_status) | |||
452 | mace->eth.rx_fifo = priv->rx_ring_dmas[priv->rx_write]; | 452 | mace->eth.rx_fifo = priv->rx_ring_dmas[priv->rx_write]; |
453 | ADVANCE_RX_PTR(priv->rx_write); | 453 | ADVANCE_RX_PTR(priv->rx_write); |
454 | } | 454 | } |
455 | spin_lock(&priv->meth_lock); | 455 | spin_lock_irqsave(&priv->meth_lock, flags); |
456 | /* In case there was underflow, and Rx DMA was disabled */ | 456 | /* In case there was underflow, and Rx DMA was disabled */ |
457 | priv->dma_ctrl |= METH_DMA_RX_INT_EN | METH_DMA_RX_EN; | 457 | priv->dma_ctrl |= METH_DMA_RX_INT_EN | METH_DMA_RX_EN; |
458 | mace->eth.dma_ctrl = priv->dma_ctrl; | 458 | mace->eth.dma_ctrl = priv->dma_ctrl; |
459 | mace->eth.int_stat = METH_INT_RX_THRESHOLD; | 459 | mace->eth.int_stat = METH_INT_RX_THRESHOLD; |
460 | spin_unlock(&priv->meth_lock); | 460 | spin_unlock_irqrestore(&priv->meth_lock, flags); |
461 | } | 461 | } |
462 | 462 | ||
463 | static int meth_tx_full(struct net_device *dev) | 463 | static int meth_tx_full(struct net_device *dev) |
@@ -470,11 +470,11 @@ static int meth_tx_full(struct net_device *dev) | |||
470 | static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) | 470 | static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) |
471 | { | 471 | { |
472 | struct meth_private *priv = netdev_priv(dev); | 472 | struct meth_private *priv = netdev_priv(dev); |
473 | unsigned long status; | 473 | unsigned long status, flags; |
474 | struct sk_buff *skb; | 474 | struct sk_buff *skb; |
475 | unsigned long rptr = (int_status&TX_INFO_RPTR) >> 16; | 475 | unsigned long rptr = (int_status&TX_INFO_RPTR) >> 16; |
476 | 476 | ||
477 | spin_lock(&priv->meth_lock); | 477 | spin_lock_irqsave(&priv->meth_lock, flags); |
478 | 478 | ||
479 | /* Stop DMA notification */ | 479 | /* Stop DMA notification */ |
480 | priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN); | 480 | priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN); |
@@ -527,12 +527,13 @@ static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) | |||
527 | } | 527 | } |
528 | 528 | ||
529 | mace->eth.int_stat = METH_INT_TX_EMPTY | METH_INT_TX_PKT; | 529 | mace->eth.int_stat = METH_INT_TX_EMPTY | METH_INT_TX_PKT; |
530 | spin_unlock(&priv->meth_lock); | 530 | spin_unlock_irqrestore(&priv->meth_lock, flags); |
531 | } | 531 | } |
532 | 532 | ||
533 | static void meth_error(struct net_device* dev, unsigned status) | 533 | static void meth_error(struct net_device* dev, unsigned status) |
534 | { | 534 | { |
535 | struct meth_private *priv = netdev_priv(dev); | 535 | struct meth_private *priv = netdev_priv(dev); |
536 | unsigned long flags; | ||
536 | 537 | ||
537 | printk(KERN_WARNING "meth: error status: 0x%08x\n",status); | 538 | printk(KERN_WARNING "meth: error status: 0x%08x\n",status); |
538 | /* check for errors too... */ | 539 | /* check for errors too... */ |
@@ -547,7 +548,7 @@ static void meth_error(struct net_device* dev, unsigned status) | |||
547 | printk(KERN_WARNING "meth: Rx overflow\n"); | 548 | printk(KERN_WARNING "meth: Rx overflow\n"); |
548 | if (status & (METH_INT_RX_UNDERFLOW)) { | 549 | if (status & (METH_INT_RX_UNDERFLOW)) { |
549 | printk(KERN_WARNING "meth: Rx underflow\n"); | 550 | printk(KERN_WARNING "meth: Rx underflow\n"); |
550 | spin_lock(&priv->meth_lock); | 551 | spin_lock_irqsave(&priv->meth_lock, flags); |
551 | mace->eth.int_stat = METH_INT_RX_UNDERFLOW; | 552 | mace->eth.int_stat = METH_INT_RX_UNDERFLOW; |
552 | /* more underflow interrupts will be delivered, | 553 | /* more underflow interrupts will be delivered, |
553 | * effectively throwing us into an infinite loop. | 554 | * effectively throwing us into an infinite loop. |
@@ -555,7 +556,7 @@ static void meth_error(struct net_device* dev, unsigned status) | |||
555 | priv->dma_ctrl &= ~METH_DMA_RX_EN; | 556 | priv->dma_ctrl &= ~METH_DMA_RX_EN; |
556 | mace->eth.dma_ctrl = priv->dma_ctrl; | 557 | mace->eth.dma_ctrl = priv->dma_ctrl; |
557 | DPRINTK("Disabled meth Rx DMA temporarily\n"); | 558 | DPRINTK("Disabled meth Rx DMA temporarily\n"); |
558 | spin_unlock(&priv->meth_lock); | 559 | spin_unlock_irqrestore(&priv->meth_lock, flags); |
559 | } | 560 | } |
560 | mace->eth.int_stat = METH_INT_ERROR; | 561 | mace->eth.int_stat = METH_INT_ERROR; |
561 | } | 562 | } |
diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c index 91f50de84be9..a276125b709b 100644 --- a/drivers/net/mlx4/en_cq.c +++ b/drivers/net/mlx4/en_cq.c | |||
@@ -125,8 +125,10 @@ void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) | |||
125 | 125 | ||
126 | if (cq->is_tx) | 126 | if (cq->is_tx) |
127 | del_timer(&cq->timer); | 127 | del_timer(&cq->timer); |
128 | else | 128 | else { |
129 | napi_disable(&cq->napi); | 129 | napi_disable(&cq->napi); |
130 | netif_napi_del(&cq->napi); | ||
131 | } | ||
130 | 132 | ||
131 | mlx4_cq_free(mdev->dev, &cq->mcq); | 133 | mlx4_cq_free(mdev->dev, &cq->mcq); |
132 | } | 134 | } |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index a400d7115f78..6bb5af35eda6 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -569,7 +569,7 @@ static int rxq_process(struct rx_queue *rxq, int budget) | |||
569 | if (rxq->rx_curr_desc == rxq->rx_ring_size) | 569 | if (rxq->rx_curr_desc == rxq->rx_ring_size) |
570 | rxq->rx_curr_desc = 0; | 570 | rxq->rx_curr_desc = 0; |
571 | 571 | ||
572 | dma_unmap_single(NULL, rx_desc->buf_ptr, | 572 | dma_unmap_single(mp->dev->dev.parent, rx_desc->buf_ptr, |
573 | rx_desc->buf_size, DMA_FROM_DEVICE); | 573 | rx_desc->buf_size, DMA_FROM_DEVICE); |
574 | rxq->rx_desc_count--; | 574 | rxq->rx_desc_count--; |
575 | rx++; | 575 | rx++; |
@@ -678,8 +678,9 @@ static int rxq_refill(struct rx_queue *rxq, int budget) | |||
678 | 678 | ||
679 | rx_desc = rxq->rx_desc_area + rx; | 679 | rx_desc = rxq->rx_desc_area + rx; |
680 | 680 | ||
681 | rx_desc->buf_ptr = dma_map_single(NULL, skb->data, | 681 | rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent, |
682 | mp->skb_size, DMA_FROM_DEVICE); | 682 | skb->data, mp->skb_size, |
683 | DMA_FROM_DEVICE); | ||
683 | rx_desc->buf_size = mp->skb_size; | 684 | rx_desc->buf_size = mp->skb_size; |
684 | rxq->rx_skb[rx] = skb; | 685 | rxq->rx_skb[rx] = skb; |
685 | wmb(); | 686 | wmb(); |
@@ -718,6 +719,7 @@ static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) | |||
718 | 719 | ||
719 | static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | 720 | static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) |
720 | { | 721 | { |
722 | struct mv643xx_eth_private *mp = txq_to_mp(txq); | ||
721 | int nr_frags = skb_shinfo(skb)->nr_frags; | 723 | int nr_frags = skb_shinfo(skb)->nr_frags; |
722 | int frag; | 724 | int frag; |
723 | 725 | ||
@@ -746,10 +748,10 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | |||
746 | 748 | ||
747 | desc->l4i_chk = 0; | 749 | desc->l4i_chk = 0; |
748 | desc->byte_cnt = this_frag->size; | 750 | desc->byte_cnt = this_frag->size; |
749 | desc->buf_ptr = dma_map_page(NULL, this_frag->page, | 751 | desc->buf_ptr = dma_map_page(mp->dev->dev.parent, |
750 | this_frag->page_offset, | 752 | this_frag->page, |
751 | this_frag->size, | 753 | this_frag->page_offset, |
752 | DMA_TO_DEVICE); | 754 | this_frag->size, DMA_TO_DEVICE); |
753 | } | 755 | } |
754 | } | 756 | } |
755 | 757 | ||
@@ -826,7 +828,8 @@ no_csum: | |||
826 | 828 | ||
827 | desc->l4i_chk = l4i_chk; | 829 | desc->l4i_chk = l4i_chk; |
828 | desc->byte_cnt = length; | 830 | desc->byte_cnt = length; |
829 | desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); | 831 | desc->buf_ptr = dma_map_single(mp->dev->dev.parent, skb->data, |
832 | length, DMA_TO_DEVICE); | ||
830 | 833 | ||
831 | __skb_queue_tail(&txq->tx_skb, skb); | 834 | __skb_queue_tail(&txq->tx_skb, skb); |
832 | 835 | ||
@@ -956,10 +959,10 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
956 | } | 959 | } |
957 | 960 | ||
958 | if (cmd_sts & TX_FIRST_DESC) { | 961 | if (cmd_sts & TX_FIRST_DESC) { |
959 | dma_unmap_single(NULL, desc->buf_ptr, | 962 | dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr, |
960 | desc->byte_cnt, DMA_TO_DEVICE); | 963 | desc->byte_cnt, DMA_TO_DEVICE); |
961 | } else { | 964 | } else { |
962 | dma_unmap_page(NULL, desc->buf_ptr, | 965 | dma_unmap_page(mp->dev->dev.parent, desc->buf_ptr, |
963 | desc->byte_cnt, DMA_TO_DEVICE); | 966 | desc->byte_cnt, DMA_TO_DEVICE); |
964 | } | 967 | } |
965 | 968 | ||
@@ -1894,9 +1897,9 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) | |||
1894 | mp->rx_desc_sram_size); | 1897 | mp->rx_desc_sram_size); |
1895 | rxq->rx_desc_dma = mp->rx_desc_sram_addr; | 1898 | rxq->rx_desc_dma = mp->rx_desc_sram_addr; |
1896 | } else { | 1899 | } else { |
1897 | rxq->rx_desc_area = dma_alloc_coherent(NULL, size, | 1900 | rxq->rx_desc_area = dma_alloc_coherent(mp->dev->dev.parent, |
1898 | &rxq->rx_desc_dma, | 1901 | size, &rxq->rx_desc_dma, |
1899 | GFP_KERNEL); | 1902 | GFP_KERNEL); |
1900 | } | 1903 | } |
1901 | 1904 | ||
1902 | if (rxq->rx_desc_area == NULL) { | 1905 | if (rxq->rx_desc_area == NULL) { |
@@ -1947,7 +1950,7 @@ out_free: | |||
1947 | if (index == 0 && size <= mp->rx_desc_sram_size) | 1950 | if (index == 0 && size <= mp->rx_desc_sram_size) |
1948 | iounmap(rxq->rx_desc_area); | 1951 | iounmap(rxq->rx_desc_area); |
1949 | else | 1952 | else |
1950 | dma_free_coherent(NULL, size, | 1953 | dma_free_coherent(mp->dev->dev.parent, size, |
1951 | rxq->rx_desc_area, | 1954 | rxq->rx_desc_area, |
1952 | rxq->rx_desc_dma); | 1955 | rxq->rx_desc_dma); |
1953 | 1956 | ||
@@ -1979,7 +1982,7 @@ static void rxq_deinit(struct rx_queue *rxq) | |||
1979 | rxq->rx_desc_area_size <= mp->rx_desc_sram_size) | 1982 | rxq->rx_desc_area_size <= mp->rx_desc_sram_size) |
1980 | iounmap(rxq->rx_desc_area); | 1983 | iounmap(rxq->rx_desc_area); |
1981 | else | 1984 | else |
1982 | dma_free_coherent(NULL, rxq->rx_desc_area_size, | 1985 | dma_free_coherent(mp->dev->dev.parent, rxq->rx_desc_area_size, |
1983 | rxq->rx_desc_area, rxq->rx_desc_dma); | 1986 | rxq->rx_desc_area, rxq->rx_desc_dma); |
1984 | 1987 | ||
1985 | kfree(rxq->rx_skb); | 1988 | kfree(rxq->rx_skb); |
@@ -2007,9 +2010,9 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
2007 | mp->tx_desc_sram_size); | 2010 | mp->tx_desc_sram_size); |
2008 | txq->tx_desc_dma = mp->tx_desc_sram_addr; | 2011 | txq->tx_desc_dma = mp->tx_desc_sram_addr; |
2009 | } else { | 2012 | } else { |
2010 | txq->tx_desc_area = dma_alloc_coherent(NULL, size, | 2013 | txq->tx_desc_area = dma_alloc_coherent(mp->dev->dev.parent, |
2011 | &txq->tx_desc_dma, | 2014 | size, &txq->tx_desc_dma, |
2012 | GFP_KERNEL); | 2015 | GFP_KERNEL); |
2013 | } | 2016 | } |
2014 | 2017 | ||
2015 | if (txq->tx_desc_area == NULL) { | 2018 | if (txq->tx_desc_area == NULL) { |
@@ -2053,7 +2056,7 @@ static void txq_deinit(struct tx_queue *txq) | |||
2053 | txq->tx_desc_area_size <= mp->tx_desc_sram_size) | 2056 | txq->tx_desc_area_size <= mp->tx_desc_sram_size) |
2054 | iounmap(txq->tx_desc_area); | 2057 | iounmap(txq->tx_desc_area); |
2055 | else | 2058 | else |
2056 | dma_free_coherent(NULL, txq->tx_desc_area_size, | 2059 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, |
2057 | txq->tx_desc_area, txq->tx_desc_dma); | 2060 | txq->tx_desc_area, txq->tx_desc_dma); |
2058 | } | 2061 | } |
2059 | 2062 | ||
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 7be0ae10d69b..c2eeac4125f3 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c | |||
@@ -115,7 +115,7 @@ enum vxge_hw_status vxge_hw_vpath_intr_enable(struct __vxge_hw_vpath_handle *vp) | |||
115 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_POISON| | 115 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_POISON| |
116 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_POISON| | 116 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_POISON| |
117 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR| | 117 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR| |
118 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR), 0, 32), | 118 | VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_DMA_ERR), 0, 32), |
119 | &vp_reg->kdfcctl_errors_mask); | 119 | &vp_reg->kdfcctl_errors_mask); |
120 | 120 | ||
121 | __vxge_hw_pio_mem_write32_upper(0, &vp_reg->vpath_ppif_int_mask); | 121 | __vxge_hw_pio_mem_write32_upper(0, &vp_reg->vpath_ppif_int_mask); |
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 02419bfd64b5..f9fc38902322 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c | |||
@@ -819,10 +819,9 @@ void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq, | |||
819 | roq_data = (struct i2400m_roq_data *) &skb->cb; | 819 | roq_data = (struct i2400m_roq_data *) &skb->cb; |
820 | i2400m_net_erx(i2400m, skb, roq_data->cs); | 820 | i2400m_net_erx(i2400m, skb, roq_data->cs); |
821 | } | 821 | } |
822 | else { | 822 | else |
823 | __i2400m_roq_queue(i2400m, roq, skb, sn, nsn); | 823 | __i2400m_roq_queue(i2400m, roq, skb, sn, nsn); |
824 | __i2400m_roq_update_ws(i2400m, roq, sn + 1); | 824 | __i2400m_roq_update_ws(i2400m, roq, sn + 1); |
825 | } | ||
826 | i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET_WS, | 825 | i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET_WS, |
827 | old_ws, len, sn, nsn, roq->ws); | 826 | old_ws, len, sn, nsn, roq->ws); |
828 | } | 827 | } |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 34bf0fdf5047..1a91bf9687af 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -557,7 +557,8 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) | |||
557 | } else { | 557 | } else { |
558 | error = -ENODEV; | 558 | error = -ENODEV; |
559 | /* Fall back to PCI_D0 if native PM is not supported */ | 559 | /* Fall back to PCI_D0 if native PM is not supported */ |
560 | pci_update_current_state(dev, PCI_D0); | 560 | if (!dev->pm_cap) |
561 | dev->current_state = PCI_D0; | ||
561 | } | 562 | } |
562 | 563 | ||
563 | return error; | 564 | return error; |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index eeafc6c0160d..bfc1a8892a32 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -269,16 +269,16 @@ static struct key_entry asus_keymap[] = { | |||
269 | {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, | 269 | {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, |
270 | {KE_KEY, 0x40, KEY_PREVIOUSSONG}, | 270 | {KE_KEY, 0x40, KEY_PREVIOUSSONG}, |
271 | {KE_KEY, 0x41, KEY_NEXTSONG}, | 271 | {KE_KEY, 0x41, KEY_NEXTSONG}, |
272 | {KE_KEY, 0x43, KEY_STOP}, | 272 | {KE_KEY, 0x43, KEY_STOPCD}, |
273 | {KE_KEY, 0x45, KEY_PLAYPAUSE}, | 273 | {KE_KEY, 0x45, KEY_PLAYPAUSE}, |
274 | {KE_KEY, 0x50, KEY_EMAIL}, | 274 | {KE_KEY, 0x50, KEY_EMAIL}, |
275 | {KE_KEY, 0x51, KEY_WWW}, | 275 | {KE_KEY, 0x51, KEY_WWW}, |
276 | {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ | 276 | {KE_KEY, 0x5C, KEY_SCREENLOCK}, /* Screenlock */ |
277 | {KE_KEY, 0x5D, KEY_WLAN}, | 277 | {KE_KEY, 0x5D, KEY_WLAN}, |
278 | {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, | 278 | {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, |
279 | {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ | 279 | {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ |
280 | {KE_KEY, 0x82, KEY_CAMERA}, | 280 | {KE_KEY, 0x82, KEY_CAMERA}, |
281 | {KE_KEY, 0x8A, KEY_TV}, | 281 | {KE_KEY, 0x8A, KEY_PROG1}, |
282 | {KE_KEY, 0x95, KEY_MEDIA}, | 282 | {KE_KEY, 0x95, KEY_MEDIA}, |
283 | {KE_KEY, 0x99, KEY_PHONE}, | 283 | {KE_KEY, 0x99, KEY_PHONE}, |
284 | {KE_END, 0}, | 284 | {KE_END, 0}, |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 6f54fd1757cd..353a898c3693 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -158,6 +158,7 @@ enum { KE_KEY, KE_END }; | |||
158 | static struct key_entry eeepc_keymap[] = { | 158 | static struct key_entry eeepc_keymap[] = { |
159 | /* Sleep already handled via generic ACPI code */ | 159 | /* Sleep already handled via generic ACPI code */ |
160 | {KE_KEY, 0x10, KEY_WLAN }, | 160 | {KE_KEY, 0x10, KEY_WLAN }, |
161 | {KE_KEY, 0x11, KEY_WLAN }, | ||
161 | {KE_KEY, 0x12, KEY_PROG1 }, | 162 | {KE_KEY, 0x12, KEY_PROG1 }, |
162 | {KE_KEY, 0x13, KEY_MUTE }, | 163 | {KE_KEY, 0x13, KEY_MUTE }, |
163 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, | 164 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, |
@@ -166,6 +167,8 @@ static struct key_entry eeepc_keymap[] = { | |||
166 | {KE_KEY, 0x1b, KEY_ZOOM }, | 167 | {KE_KEY, 0x1b, KEY_ZOOM }, |
167 | {KE_KEY, 0x1c, KEY_PROG2 }, | 168 | {KE_KEY, 0x1c, KEY_PROG2 }, |
168 | {KE_KEY, 0x1d, KEY_PROG3 }, | 169 | {KE_KEY, 0x1d, KEY_PROG3 }, |
170 | {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN }, | ||
171 | {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP }, | ||
169 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, | 172 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, |
170 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, | 173 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, |
171 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, | 174 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, |
@@ -381,11 +384,13 @@ static ssize_t show_sys_acpi(int cm, char *buf) | |||
381 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); | 384 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); |
382 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); | 385 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); |
383 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); | 386 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); |
387 | EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV); | ||
384 | 388 | ||
385 | static struct attribute *platform_attributes[] = { | 389 | static struct attribute *platform_attributes[] = { |
386 | &dev_attr_camera.attr, | 390 | &dev_attr_camera.attr, |
387 | &dev_attr_cardr.attr, | 391 | &dev_attr_cardr.attr, |
388 | &dev_attr_disp.attr, | 392 | &dev_attr_disp.attr, |
393 | &dev_attr_cpufv.attr, | ||
389 | NULL | 394 | NULL |
390 | }; | 395 | }; |
391 | 396 | ||
@@ -512,15 +517,21 @@ static int eeepc_hotk_check(void) | |||
512 | return 0; | 517 | return 0; |
513 | } | 518 | } |
514 | 519 | ||
515 | static void notify_brn(void) | 520 | static int notify_brn(void) |
516 | { | 521 | { |
522 | /* returns the *previous* brightness, or -1 */ | ||
517 | struct backlight_device *bd = eeepc_backlight_device; | 523 | struct backlight_device *bd = eeepc_backlight_device; |
518 | if (bd) | 524 | if (bd) { |
525 | int old = bd->props.brightness; | ||
519 | bd->props.brightness = read_brightness(bd); | 526 | bd->props.brightness = read_brightness(bd); |
527 | return old; | ||
528 | } | ||
529 | return -1; | ||
520 | } | 530 | } |
521 | 531 | ||
522 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 532 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
523 | { | 533 | { |
534 | enum rfkill_state state; | ||
524 | struct pci_dev *dev; | 535 | struct pci_dev *dev; |
525 | struct pci_bus *bus = pci_find_bus(0, 1); | 536 | struct pci_bus *bus = pci_find_bus(0, 1); |
526 | 537 | ||
@@ -532,7 +543,9 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
532 | return; | 543 | return; |
533 | } | 544 | } |
534 | 545 | ||
535 | if (get_acpi(CM_ASL_WLAN) == 1) { | 546 | eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); |
547 | |||
548 | if (state == RFKILL_STATE_UNBLOCKED) { | ||
536 | dev = pci_get_slot(bus, 0); | 549 | dev = pci_get_slot(bus, 0); |
537 | if (dev) { | 550 | if (dev) { |
538 | /* Device already present */ | 551 | /* Device already present */ |
@@ -552,23 +565,41 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
552 | pci_dev_put(dev); | 565 | pci_dev_put(dev); |
553 | } | 566 | } |
554 | } | 567 | } |
568 | |||
569 | rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); | ||
555 | } | 570 | } |
556 | 571 | ||
557 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | 572 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) |
558 | { | 573 | { |
559 | static struct key_entry *key; | 574 | static struct key_entry *key; |
560 | u16 count; | 575 | u16 count; |
576 | int brn = -ENODEV; | ||
561 | 577 | ||
562 | if (!ehotk) | 578 | if (!ehotk) |
563 | return; | 579 | return; |
564 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) | 580 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) |
565 | notify_brn(); | 581 | brn = notify_brn(); |
566 | count = ehotk->event_count[event % 128]++; | 582 | count = ehotk->event_count[event % 128]++; |
567 | acpi_bus_generate_proc_event(ehotk->device, event, count); | 583 | acpi_bus_generate_proc_event(ehotk->device, event, count); |
568 | acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, | 584 | acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, |
569 | dev_name(&ehotk->device->dev), event, | 585 | dev_name(&ehotk->device->dev), event, |
570 | count); | 586 | count); |
571 | if (ehotk->inputdev) { | 587 | if (ehotk->inputdev) { |
588 | if (brn != -ENODEV) { | ||
589 | /* brightness-change events need special | ||
590 | * handling for conversion to key events | ||
591 | */ | ||
592 | if (brn < 0) | ||
593 | brn = event; | ||
594 | else | ||
595 | brn += NOTIFY_BRN_MIN; | ||
596 | if (event < brn) | ||
597 | event = NOTIFY_BRN_MIN; /* brightness down */ | ||
598 | else if (event > brn) | ||
599 | event = NOTIFY_BRN_MIN + 2; /* ... up */ | ||
600 | else | ||
601 | event = NOTIFY_BRN_MIN + 1; /* ... unchanged */ | ||
602 | } | ||
572 | key = eepc_get_entry_by_scancode(event); | 603 | key = eepc_get_entry_by_scancode(event); |
573 | if (key) { | 604 | if (key) { |
574 | switch (key->type) { | 605 | switch (key->type) { |
@@ -649,6 +680,9 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
649 | if (ACPI_FAILURE(status)) | 680 | if (ACPI_FAILURE(status)) |
650 | printk(EEEPC_ERR "Error installing notify handler\n"); | 681 | printk(EEEPC_ERR "Error installing notify handler\n"); |
651 | 682 | ||
683 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
684 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
685 | |||
652 | if (get_acpi(CM_ASL_WLAN) != -1) { | 686 | if (get_acpi(CM_ASL_WLAN) != -1) { |
653 | ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, | 687 | ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, |
654 | RFKILL_TYPE_WLAN); | 688 | RFKILL_TYPE_WLAN); |
@@ -704,9 +738,6 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
704 | goto bluetooth_fail; | 738 | goto bluetooth_fail; |
705 | } | 739 | } |
706 | 740 | ||
707 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
708 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
709 | |||
710 | return 0; | 741 | return 0; |
711 | 742 | ||
712 | bluetooth_fail: | 743 | bluetooth_fail: |
@@ -717,6 +748,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
717 | wlan_fail: | 748 | wlan_fail: |
718 | if (ehotk->eeepc_wlan_rfkill) | 749 | if (ehotk->eeepc_wlan_rfkill) |
719 | rfkill_free(ehotk->eeepc_wlan_rfkill); | 750 | rfkill_free(ehotk->eeepc_wlan_rfkill); |
751 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
752 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
720 | ehotk_fail: | 753 | ehotk_fail: |
721 | kfree(ehotk); | 754 | kfree(ehotk); |
722 | ehotk = NULL; | 755 | ehotk = NULL; |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 9a3a682c6981..9496494f340e 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -110,11 +110,9 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) | |||
110 | 110 | ||
111 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ | 111 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ |
112 | ret = 0; | 112 | ret = 0; |
113 | if (acpi_bus_power_manageable(handle)) { | 113 | if (acpi_bus_power_manageable(handle)) |
114 | ret = acpi_bus_set_power(handle, ACPI_STATE_D3); | 114 | acpi_bus_set_power(handle, ACPI_STATE_D3); |
115 | if (ret) | 115 | /* continue even if acpi_bus_set_power() fails */ |
116 | return ret; | ||
117 | } | ||
118 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) | 116 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) |
119 | ret = -ENODEV; | 117 | ret = -ENODEV; |
120 | return ret; | 118 | return ret; |
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 72b15495183c..c6628f5a0af7 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c | |||
@@ -497,7 +497,7 @@ static struct platform_driver da903x_regulator_driver = { | |||
497 | .owner = THIS_MODULE, | 497 | .owner = THIS_MODULE, |
498 | }, | 498 | }, |
499 | .probe = da903x_regulator_probe, | 499 | .probe = da903x_regulator_probe, |
500 | .remove = da903x_regulator_remove, | 500 | .remove = __devexit_p(da903x_regulator_remove), |
501 | }; | 501 | }; |
502 | 502 | ||
503 | static int __init da903x_regulator_init(void) | 503 | static int __init da903x_regulator_init(void) |
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 826153552157..aaf1f75fa293 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c | |||
@@ -102,7 +102,7 @@ static const struct rtc_class_ops pl030_ops = { | |||
102 | .set_alarm = pl030_set_alarm, | 102 | .set_alarm = pl030_set_alarm, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static int pl030_probe(struct amba_device *dev, void *id) | 105 | static int pl030_probe(struct amba_device *dev, struct amba_id *id) |
106 | { | 106 | { |
107 | struct pl030_rtc *rtc; | 107 | struct pl030_rtc *rtc; |
108 | int ret; | 108 | int ret; |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 333eec689d2f..451fc13784d1 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -127,7 +127,7 @@ static int pl031_remove(struct amba_device *adev) | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | static int pl031_probe(struct amba_device *adev, void *id) | 130 | static int pl031_probe(struct amba_device *adev, struct amba_id *id) |
131 | { | 131 | { |
132 | int ret; | 132 | int ret; |
133 | struct pl031_local *ldata; | 133 | struct pl031_local *ldata; |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 8b7983aba8f7..36c21b19e5d7 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -1978,7 +1978,8 @@ static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id) | |||
1978 | { | 1978 | { |
1979 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; | 1979 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; |
1980 | 1980 | ||
1981 | scsi_dma_unmap(cmd); | 1981 | if (cmd->SCp.phase == TW_PHASE_SGLIST) |
1982 | scsi_dma_unmap(cmd); | ||
1982 | } /* End twa_unmap_scsi_data() */ | 1983 | } /* End twa_unmap_scsi_data() */ |
1983 | 1984 | ||
1984 | /* scsi_host_template initializer */ | 1985 | /* scsi_host_template initializer */ |
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index c03f1d2c9e2e..faa0fcfed71e 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c | |||
@@ -6,7 +6,7 @@ | |||
6 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 6 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
7 | Brad Strand <linux@3ware.com> | 7 | Brad Strand <linux@3ware.com> |
8 | 8 | ||
9 | Copyright (C) 1999-2007 3ware Inc. | 9 | Copyright (C) 1999-2009 3ware Inc. |
10 | 10 | ||
11 | Kernel compatiblity By: Andre Hedrick <andre@suse.com> | 11 | Kernel compatiblity By: Andre Hedrick <andre@suse.com> |
12 | Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> | 12 | Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> |
@@ -1294,7 +1294,8 @@ static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) | |||
1294 | { | 1294 | { |
1295 | dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n"); | 1295 | dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n"); |
1296 | 1296 | ||
1297 | scsi_dma_unmap(cmd); | 1297 | if (cmd->SCp.phase == TW_PHASE_SGLIST) |
1298 | scsi_dma_unmap(cmd); | ||
1298 | } /* End tw_unmap_scsi_data() */ | 1299 | } /* End tw_unmap_scsi_data() */ |
1299 | 1300 | ||
1300 | /* This function will reset a device extension */ | 1301 | /* This function will reset a device extension */ |
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h index 8e71e5e122b3..a5a2ba2561d9 100644 --- a/drivers/scsi/3w-xxxx.h +++ b/drivers/scsi/3w-xxxx.h | |||
@@ -6,7 +6,7 @@ | |||
6 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 6 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
7 | Brad Strand <linux@3ware.com> | 7 | Brad Strand <linux@3ware.com> |
8 | 8 | ||
9 | Copyright (C) 1999-2007 3ware Inc. | 9 | Copyright (C) 1999-2009 3ware Inc. |
10 | 10 | ||
11 | Kernel compatiblity By: Andre Hedrick <andre@suse.com> | 11 | Kernel compatiblity By: Andre Hedrick <andre@suse.com> |
12 | Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> | 12 | Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 8ed2990c826e..fb2740789b68 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -628,6 +628,17 @@ config FCOE | |||
628 | ---help--- | 628 | ---help--- |
629 | Fibre Channel over Ethernet module | 629 | Fibre Channel over Ethernet module |
630 | 630 | ||
631 | config FCOE_FNIC | ||
632 | tristate "Cisco FNIC Driver" | ||
633 | depends on PCI && X86 | ||
634 | select LIBFC | ||
635 | help | ||
636 | This is support for the Cisco PCI-Express FCoE HBA. | ||
637 | |||
638 | To compile this driver as a module, choose M here and read | ||
639 | <file:Documentation/scsi/scsi.txt>. | ||
640 | The module will be called fnic. | ||
641 | |||
631 | config SCSI_DMX3191D | 642 | config SCSI_DMX3191D |
632 | tristate "DMX3191D SCSI support" | 643 | tristate "DMX3191D SCSI support" |
633 | depends on PCI && SCSI | 644 | depends on PCI && SCSI |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index e7c861ac417d..a5049cfb40ed 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -39,6 +39,7 @@ obj-$(CONFIG_SCSI_DH) += device_handler/ | |||
39 | obj-$(CONFIG_LIBFC) += libfc/ | 39 | obj-$(CONFIG_LIBFC) += libfc/ |
40 | obj-$(CONFIG_LIBFCOE) += fcoe/ | 40 | obj-$(CONFIG_LIBFCOE) += fcoe/ |
41 | obj-$(CONFIG_FCOE) += fcoe/ | 41 | obj-$(CONFIG_FCOE) += fcoe/ |
42 | obj-$(CONFIG_FCOE_FNIC) += fnic/ | ||
42 | obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o | 43 | obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o |
43 | obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o | 44 | obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o |
44 | obj-$(CONFIG_SCSI_A4000T) += 53c700.o a4000t.o | 45 | obj-$(CONFIG_SCSI_A4000T) += 53c700.o a4000t.o |
diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile new file mode 100644 index 000000000000..37c3440bc17c --- /dev/null +++ b/drivers/scsi/fnic/Makefile | |||
@@ -0,0 +1,15 @@ | |||
1 | obj-$(CONFIG_FCOE_FNIC) += fnic.o | ||
2 | |||
3 | fnic-y := \ | ||
4 | fnic_attrs.o \ | ||
5 | fnic_isr.o \ | ||
6 | fnic_main.o \ | ||
7 | fnic_res.o \ | ||
8 | fnic_fcs.o \ | ||
9 | fnic_scsi.o \ | ||
10 | vnic_cq.o \ | ||
11 | vnic_dev.o \ | ||
12 | vnic_intr.o \ | ||
13 | vnic_rq.o \ | ||
14 | vnic_wq_copy.o \ | ||
15 | vnic_wq.o | ||
diff --git a/drivers/scsi/fnic/cq_desc.h b/drivers/scsi/fnic/cq_desc.h new file mode 100644 index 000000000000..d1225cf6320e --- /dev/null +++ b/drivers/scsi/fnic/cq_desc.h | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _CQ_DESC_H_ | ||
19 | #define _CQ_DESC_H_ | ||
20 | |||
21 | /* | ||
22 | * Completion queue descriptor types | ||
23 | */ | ||
24 | enum cq_desc_types { | ||
25 | CQ_DESC_TYPE_WQ_ENET = 0, | ||
26 | CQ_DESC_TYPE_DESC_COPY = 1, | ||
27 | CQ_DESC_TYPE_WQ_EXCH = 2, | ||
28 | CQ_DESC_TYPE_RQ_ENET = 3, | ||
29 | CQ_DESC_TYPE_RQ_FCP = 4, | ||
30 | }; | ||
31 | |||
32 | /* Completion queue descriptor: 16B | ||
33 | * | ||
34 | * All completion queues have this basic layout. The | ||
35 | * type_specfic area is unique for each completion | ||
36 | * queue type. | ||
37 | */ | ||
38 | struct cq_desc { | ||
39 | __le16 completed_index; | ||
40 | __le16 q_number; | ||
41 | u8 type_specfic[11]; | ||
42 | u8 type_color; | ||
43 | }; | ||
44 | |||
45 | #define CQ_DESC_TYPE_BITS 4 | ||
46 | #define CQ_DESC_TYPE_MASK ((1 << CQ_DESC_TYPE_BITS) - 1) | ||
47 | #define CQ_DESC_COLOR_MASK 1 | ||
48 | #define CQ_DESC_COLOR_SHIFT 7 | ||
49 | #define CQ_DESC_Q_NUM_BITS 10 | ||
50 | #define CQ_DESC_Q_NUM_MASK ((1 << CQ_DESC_Q_NUM_BITS) - 1) | ||
51 | #define CQ_DESC_COMP_NDX_BITS 12 | ||
52 | #define CQ_DESC_COMP_NDX_MASK ((1 << CQ_DESC_COMP_NDX_BITS) - 1) | ||
53 | |||
54 | static inline void cq_desc_dec(const struct cq_desc *desc_arg, | ||
55 | u8 *type, u8 *color, u16 *q_number, u16 *completed_index) | ||
56 | { | ||
57 | const struct cq_desc *desc = desc_arg; | ||
58 | const u8 type_color = desc->type_color; | ||
59 | |||
60 | *color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK; | ||
61 | |||
62 | /* | ||
63 | * Make sure color bit is read from desc *before* other fields | ||
64 | * are read from desc. Hardware guarantees color bit is last | ||
65 | * bit (byte) written. Adding the rmb() prevents the compiler | ||
66 | * and/or CPU from reordering the reads which would potentially | ||
67 | * result in reading stale values. | ||
68 | */ | ||
69 | |||
70 | rmb(); | ||
71 | |||
72 | *type = type_color & CQ_DESC_TYPE_MASK; | ||
73 | *q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK; | ||
74 | *completed_index = le16_to_cpu(desc->completed_index) & | ||
75 | CQ_DESC_COMP_NDX_MASK; | ||
76 | } | ||
77 | |||
78 | #endif /* _CQ_DESC_H_ */ | ||
diff --git a/drivers/scsi/fnic/cq_enet_desc.h b/drivers/scsi/fnic/cq_enet_desc.h new file mode 100644 index 000000000000..a9fa26f82ddd --- /dev/null +++ b/drivers/scsi/fnic/cq_enet_desc.h | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _CQ_ENET_DESC_H_ | ||
19 | #define _CQ_ENET_DESC_H_ | ||
20 | |||
21 | #include "cq_desc.h" | ||
22 | |||
23 | /* Ethernet completion queue descriptor: 16B */ | ||
24 | struct cq_enet_wq_desc { | ||
25 | __le16 completed_index; | ||
26 | __le16 q_number; | ||
27 | u8 reserved[11]; | ||
28 | u8 type_color; | ||
29 | }; | ||
30 | |||
31 | static inline void cq_enet_wq_desc_dec(struct cq_enet_wq_desc *desc, | ||
32 | u8 *type, u8 *color, u16 *q_number, u16 *completed_index) | ||
33 | { | ||
34 | cq_desc_dec((struct cq_desc *)desc, type, | ||
35 | color, q_number, completed_index); | ||
36 | } | ||
37 | |||
38 | /* Completion queue descriptor: Ethernet receive queue, 16B */ | ||
39 | struct cq_enet_rq_desc { | ||
40 | __le16 completed_index_flags; | ||
41 | __le16 q_number_rss_type_flags; | ||
42 | __le32 rss_hash; | ||
43 | __le16 bytes_written_flags; | ||
44 | __le16 vlan; | ||
45 | __le16 checksum_fcoe; | ||
46 | u8 flags; | ||
47 | u8 type_color; | ||
48 | }; | ||
49 | |||
50 | #define CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT (0x1 << 12) | ||
51 | #define CQ_ENET_RQ_DESC_FLAGS_FCOE (0x1 << 13) | ||
52 | #define CQ_ENET_RQ_DESC_FLAGS_EOP (0x1 << 14) | ||
53 | #define CQ_ENET_RQ_DESC_FLAGS_SOP (0x1 << 15) | ||
54 | |||
55 | #define CQ_ENET_RQ_DESC_RSS_TYPE_BITS 4 | ||
56 | #define CQ_ENET_RQ_DESC_RSS_TYPE_MASK \ | ||
57 | ((1 << CQ_ENET_RQ_DESC_RSS_TYPE_BITS) - 1) | ||
58 | #define CQ_ENET_RQ_DESC_RSS_TYPE_NONE 0 | ||
59 | #define CQ_ENET_RQ_DESC_RSS_TYPE_IPv4 1 | ||
60 | #define CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv4 2 | ||
61 | #define CQ_ENET_RQ_DESC_RSS_TYPE_IPv6 3 | ||
62 | #define CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6 4 | ||
63 | #define CQ_ENET_RQ_DESC_RSS_TYPE_IPv6_EX 5 | ||
64 | #define CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6_EX 6 | ||
65 | |||
66 | #define CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC (0x1 << 14) | ||
67 | |||
68 | #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS 14 | ||
69 | #define CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK \ | ||
70 | ((1 << CQ_ENET_RQ_DESC_BYTES_WRITTEN_BITS) - 1) | ||
71 | #define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14) | ||
72 | #define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15) | ||
73 | |||
74 | #define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 4 | ||
75 | #define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \ | ||
76 | ((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1) | ||
77 | #define CQ_ENET_RQ_DESC_FCOE_EOF_BITS 8 | ||
78 | #define CQ_ENET_RQ_DESC_FCOE_EOF_MASK \ | ||
79 | ((1 << CQ_ENET_RQ_DESC_FCOE_EOF_BITS) - 1) | ||
80 | #define CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT 8 | ||
81 | |||
82 | #define CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK (0x1 << 0) | ||
83 | #define CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK (0x1 << 0) | ||
84 | #define CQ_ENET_RQ_DESC_FLAGS_UDP (0x1 << 1) | ||
85 | #define CQ_ENET_RQ_DESC_FCOE_ENC_ERROR (0x1 << 1) | ||
86 | #define CQ_ENET_RQ_DESC_FLAGS_TCP (0x1 << 2) | ||
87 | #define CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK (0x1 << 3) | ||
88 | #define CQ_ENET_RQ_DESC_FLAGS_IPV6 (0x1 << 4) | ||
89 | #define CQ_ENET_RQ_DESC_FLAGS_IPV4 (0x1 << 5) | ||
90 | #define CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT (0x1 << 6) | ||
91 | #define CQ_ENET_RQ_DESC_FLAGS_FCS_OK (0x1 << 7) | ||
92 | |||
93 | static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, | ||
94 | u8 *type, u8 *color, u16 *q_number, u16 *completed_index, | ||
95 | u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type, | ||
96 | u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error, | ||
97 | u8 *vlan_stripped, u16 *vlan, u16 *checksum, u8 *fcoe_sof, | ||
98 | u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof, | ||
99 | u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok, | ||
100 | u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok) | ||
101 | { | ||
102 | u16 completed_index_flags = le16_to_cpu(desc->completed_index_flags); | ||
103 | u16 q_number_rss_type_flags = | ||
104 | le16_to_cpu(desc->q_number_rss_type_flags); | ||
105 | u16 bytes_written_flags = le16_to_cpu(desc->bytes_written_flags); | ||
106 | |||
107 | cq_desc_dec((struct cq_desc *)desc, type, | ||
108 | color, q_number, completed_index); | ||
109 | |||
110 | *ingress_port = (completed_index_flags & | ||
111 | CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT) ? 1 : 0; | ||
112 | *fcoe = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_FCOE) ? | ||
113 | 1 : 0; | ||
114 | *eop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_EOP) ? | ||
115 | 1 : 0; | ||
116 | *sop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_SOP) ? | ||
117 | 1 : 0; | ||
118 | |||
119 | *rss_type = (u8)((q_number_rss_type_flags >> CQ_DESC_Q_NUM_BITS) & | ||
120 | CQ_ENET_RQ_DESC_RSS_TYPE_MASK); | ||
121 | *csum_not_calc = (q_number_rss_type_flags & | ||
122 | CQ_ENET_RQ_DESC_FLAGS_CSUM_NOT_CALC) ? 1 : 0; | ||
123 | |||
124 | *rss_hash = le32_to_cpu(desc->rss_hash); | ||
125 | |||
126 | *bytes_written = bytes_written_flags & | ||
127 | CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK; | ||
128 | *packet_error = (bytes_written_flags & | ||
129 | CQ_ENET_RQ_DESC_FLAGS_TRUNCATED) ? 1 : 0; | ||
130 | *vlan_stripped = (bytes_written_flags & | ||
131 | CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0; | ||
132 | |||
133 | *vlan = le16_to_cpu(desc->vlan); | ||
134 | |||
135 | if (*fcoe) { | ||
136 | *fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) & | ||
137 | CQ_ENET_RQ_DESC_FCOE_SOF_MASK); | ||
138 | *fcoe_fc_crc_ok = (desc->flags & | ||
139 | CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0; | ||
140 | *fcoe_enc_error = (desc->flags & | ||
141 | CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0; | ||
142 | *fcoe_eof = (u8)((desc->checksum_fcoe >> | ||
143 | CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) & | ||
144 | CQ_ENET_RQ_DESC_FCOE_EOF_MASK); | ||
145 | *checksum = 0; | ||
146 | } else { | ||
147 | *fcoe_sof = 0; | ||
148 | *fcoe_fc_crc_ok = 0; | ||
149 | *fcoe_enc_error = 0; | ||
150 | *fcoe_eof = 0; | ||
151 | *checksum = le16_to_cpu(desc->checksum_fcoe); | ||
152 | } | ||
153 | |||
154 | *tcp_udp_csum_ok = | ||
155 | (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP_UDP_CSUM_OK) ? 1 : 0; | ||
156 | *udp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_UDP) ? 1 : 0; | ||
157 | *tcp = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_TCP) ? 1 : 0; | ||
158 | *ipv4_csum_ok = | ||
159 | (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_CSUM_OK) ? 1 : 0; | ||
160 | *ipv6 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV6) ? 1 : 0; | ||
161 | *ipv4 = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4) ? 1 : 0; | ||
162 | *ipv4_fragment = | ||
163 | (desc->flags & CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT) ? 1 : 0; | ||
164 | *fcs_ok = (desc->flags & CQ_ENET_RQ_DESC_FLAGS_FCS_OK) ? 1 : 0; | ||
165 | } | ||
166 | |||
167 | #endif /* _CQ_ENET_DESC_H_ */ | ||
diff --git a/drivers/scsi/fnic/cq_exch_desc.h b/drivers/scsi/fnic/cq_exch_desc.h new file mode 100644 index 000000000000..501660cfe228 --- /dev/null +++ b/drivers/scsi/fnic/cq_exch_desc.h | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _CQ_EXCH_DESC_H_ | ||
19 | #define _CQ_EXCH_DESC_H_ | ||
20 | |||
21 | #include "cq_desc.h" | ||
22 | |||
23 | /* Exchange completion queue descriptor: 16B */ | ||
24 | struct cq_exch_wq_desc { | ||
25 | u16 completed_index; | ||
26 | u16 q_number; | ||
27 | u16 exchange_id; | ||
28 | u8 tmpl; | ||
29 | u8 reserved0; | ||
30 | u32 reserved1; | ||
31 | u8 exch_status; | ||
32 | u8 reserved2[2]; | ||
33 | u8 type_color; | ||
34 | }; | ||
35 | |||
36 | #define CQ_EXCH_WQ_STATUS_BITS 2 | ||
37 | #define CQ_EXCH_WQ_STATUS_MASK ((1 << CQ_EXCH_WQ_STATUS_BITS) - 1) | ||
38 | |||
39 | enum cq_exch_status_types { | ||
40 | CQ_EXCH_WQ_STATUS_TYPE_COMPLETE = 0, | ||
41 | CQ_EXCH_WQ_STATUS_TYPE_ABORT = 1, | ||
42 | CQ_EXCH_WQ_STATUS_TYPE_SGL_EOF = 2, | ||
43 | CQ_EXCH_WQ_STATUS_TYPE_TMPL_ERR = 3, | ||
44 | }; | ||
45 | |||
46 | static inline void cq_exch_wq_desc_dec(struct cq_exch_wq_desc *desc_ptr, | ||
47 | u8 *type, | ||
48 | u8 *color, | ||
49 | u16 *q_number, | ||
50 | u16 *completed_index, | ||
51 | u8 *exch_status) | ||
52 | { | ||
53 | cq_desc_dec((struct cq_desc *)desc_ptr, type, | ||
54 | color, q_number, completed_index); | ||
55 | *exch_status = desc_ptr->exch_status & CQ_EXCH_WQ_STATUS_MASK; | ||
56 | } | ||
57 | |||
58 | struct cq_fcp_rq_desc { | ||
59 | u16 completed_index_eop_sop_prt; | ||
60 | u16 q_number; | ||
61 | u16 exchange_id; | ||
62 | u16 tmpl; | ||
63 | u16 bytes_written; | ||
64 | u16 vlan; | ||
65 | u8 sof; | ||
66 | u8 eof; | ||
67 | u8 fcs_fer_fck; | ||
68 | u8 type_color; | ||
69 | }; | ||
70 | |||
71 | #define CQ_FCP_RQ_DESC_FLAGS_SOP (1 << 15) | ||
72 | #define CQ_FCP_RQ_DESC_FLAGS_EOP (1 << 14) | ||
73 | #define CQ_FCP_RQ_DESC_FLAGS_PRT (1 << 12) | ||
74 | #define CQ_FCP_RQ_DESC_TMPL_MASK 0x1f | ||
75 | #define CQ_FCP_RQ_DESC_BYTES_WRITTEN_MASK 0x3fff | ||
76 | #define CQ_FCP_RQ_DESC_PACKET_ERR_SHIFT 14 | ||
77 | #define CQ_FCP_RQ_DESC_PACKET_ERR_MASK (1 << CQ_FCP_RQ_DESC_PACKET_ERR_SHIFT) | ||
78 | #define CQ_FCP_RQ_DESC_VS_STRIPPED_SHIFT 15 | ||
79 | #define CQ_FCP_RQ_DESC_VS_STRIPPED_MASK (1 << CQ_FCP_RQ_DESC_VS_STRIPPED_SHIFT) | ||
80 | #define CQ_FCP_RQ_DESC_FC_CRC_OK_MASK 0x1 | ||
81 | #define CQ_FCP_RQ_DESC_FCOE_ERR_SHIFT 1 | ||
82 | #define CQ_FCP_RQ_DESC_FCOE_ERR_MASK (1 << CQ_FCP_RQ_DESC_FCOE_ERR_SHIFT) | ||
83 | #define CQ_FCP_RQ_DESC_FCS_OK_SHIFT 7 | ||
84 | #define CQ_FCP_RQ_DESC_FCS_OK_MASK (1 << CQ_FCP_RQ_DESC_FCS_OK_SHIFT) | ||
85 | |||
86 | static inline void cq_fcp_rq_desc_dec(struct cq_fcp_rq_desc *desc_ptr, | ||
87 | u8 *type, | ||
88 | u8 *color, | ||
89 | u16 *q_number, | ||
90 | u16 *completed_index, | ||
91 | u8 *eop, | ||
92 | u8 *sop, | ||
93 | u8 *fck, | ||
94 | u16 *exchange_id, | ||
95 | u16 *tmpl, | ||
96 | u32 *bytes_written, | ||
97 | u8 *sof, | ||
98 | u8 *eof, | ||
99 | u8 *ingress_port, | ||
100 | u8 *packet_err, | ||
101 | u8 *fcoe_err, | ||
102 | u8 *fcs_ok, | ||
103 | u8 *vlan_stripped, | ||
104 | u16 *vlan) | ||
105 | { | ||
106 | cq_desc_dec((struct cq_desc *)desc_ptr, type, | ||
107 | color, q_number, completed_index); | ||
108 | *eop = (desc_ptr->completed_index_eop_sop_prt & | ||
109 | CQ_FCP_RQ_DESC_FLAGS_EOP) ? 1 : 0; | ||
110 | *sop = (desc_ptr->completed_index_eop_sop_prt & | ||
111 | CQ_FCP_RQ_DESC_FLAGS_SOP) ? 1 : 0; | ||
112 | *ingress_port = | ||
113 | (desc_ptr->completed_index_eop_sop_prt & | ||
114 | CQ_FCP_RQ_DESC_FLAGS_PRT) ? 1 : 0; | ||
115 | *exchange_id = desc_ptr->exchange_id; | ||
116 | *tmpl = desc_ptr->tmpl & CQ_FCP_RQ_DESC_TMPL_MASK; | ||
117 | *bytes_written = | ||
118 | desc_ptr->bytes_written & CQ_FCP_RQ_DESC_BYTES_WRITTEN_MASK; | ||
119 | *packet_err = | ||
120 | (desc_ptr->bytes_written & CQ_FCP_RQ_DESC_PACKET_ERR_MASK) >> | ||
121 | CQ_FCP_RQ_DESC_PACKET_ERR_SHIFT; | ||
122 | *vlan_stripped = | ||
123 | (desc_ptr->bytes_written & CQ_FCP_RQ_DESC_VS_STRIPPED_MASK) >> | ||
124 | CQ_FCP_RQ_DESC_VS_STRIPPED_SHIFT; | ||
125 | *vlan = desc_ptr->vlan; | ||
126 | *sof = desc_ptr->sof; | ||
127 | *fck = desc_ptr->fcs_fer_fck & CQ_FCP_RQ_DESC_FC_CRC_OK_MASK; | ||
128 | *fcoe_err = (desc_ptr->fcs_fer_fck & CQ_FCP_RQ_DESC_FCOE_ERR_MASK) >> | ||
129 | CQ_FCP_RQ_DESC_FCOE_ERR_SHIFT; | ||
130 | *eof = desc_ptr->eof; | ||
131 | *fcs_ok = | ||
132 | (desc_ptr->fcs_fer_fck & CQ_FCP_RQ_DESC_FCS_OK_MASK) >> | ||
133 | CQ_FCP_RQ_DESC_FCS_OK_SHIFT; | ||
134 | } | ||
135 | |||
136 | struct cq_sgl_desc { | ||
137 | u16 exchange_id; | ||
138 | u16 q_number; | ||
139 | u32 active_burst_offset; | ||
140 | u32 tot_data_bytes; | ||
141 | u16 tmpl; | ||
142 | u8 sgl_err; | ||
143 | u8 type_color; | ||
144 | }; | ||
145 | |||
146 | enum cq_sgl_err_types { | ||
147 | CQ_SGL_ERR_NO_ERROR = 0, | ||
148 | CQ_SGL_ERR_OVERFLOW, /* data ran beyond end of SGL */ | ||
149 | CQ_SGL_ERR_SGL_LCL_ADDR_ERR, /* sgl access to local vnic addr illegal*/ | ||
150 | CQ_SGL_ERR_ADDR_RSP_ERR, /* sgl address error */ | ||
151 | CQ_SGL_ERR_DATA_RSP_ERR, /* sgl data rsp error */ | ||
152 | CQ_SGL_ERR_CNT_ZERO_ERR, /* SGL count is 0 */ | ||
153 | CQ_SGL_ERR_CNT_MAX_ERR, /* SGL count is larger than supported */ | ||
154 | CQ_SGL_ERR_ORDER_ERR, /* frames recv on both ports, order err */ | ||
155 | CQ_SGL_ERR_DATA_LCL_ADDR_ERR,/* sgl data buf to local vnic addr ill */ | ||
156 | CQ_SGL_ERR_HOST_CQ_ERR, /* host cq entry to local vnic addr ill */ | ||
157 | }; | ||
158 | |||
159 | #define CQ_SGL_SGL_ERR_MASK 0x1f | ||
160 | #define CQ_SGL_TMPL_MASK 0x1f | ||
161 | |||
162 | static inline void cq_sgl_desc_dec(struct cq_sgl_desc *desc_ptr, | ||
163 | u8 *type, | ||
164 | u8 *color, | ||
165 | u16 *q_number, | ||
166 | u16 *exchange_id, | ||
167 | u32 *active_burst_offset, | ||
168 | u32 *tot_data_bytes, | ||
169 | u16 *tmpl, | ||
170 | u8 *sgl_err) | ||
171 | { | ||
172 | /* Cheat a little by assuming exchange_id is the same as completed | ||
173 | index */ | ||
174 | cq_desc_dec((struct cq_desc *)desc_ptr, type, color, q_number, | ||
175 | exchange_id); | ||
176 | *active_burst_offset = desc_ptr->active_burst_offset; | ||
177 | *tot_data_bytes = desc_ptr->tot_data_bytes; | ||
178 | *tmpl = desc_ptr->tmpl & CQ_SGL_TMPL_MASK; | ||
179 | *sgl_err = desc_ptr->sgl_err & CQ_SGL_SGL_ERR_MASK; | ||
180 | } | ||
181 | |||
182 | #endif /* _CQ_EXCH_DESC_H_ */ | ||
diff --git a/drivers/scsi/fnic/fcpio.h b/drivers/scsi/fnic/fcpio.h new file mode 100644 index 000000000000..12d770d885c5 --- /dev/null +++ b/drivers/scsi/fnic/fcpio.h | |||
@@ -0,0 +1,780 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _FCPIO_H_ | ||
19 | #define _FCPIO_H_ | ||
20 | |||
21 | #include <linux/if_ether.h> | ||
22 | |||
23 | /* | ||
24 | * This header file includes all of the data structures used for | ||
25 | * communication by the host driver to the fcp firmware. | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * Exchange and sequence id space allocated to the host driver | ||
30 | */ | ||
31 | #define FCPIO_HOST_EXCH_RANGE_START 0x1000 | ||
32 | #define FCPIO_HOST_EXCH_RANGE_END 0x1fff | ||
33 | #define FCPIO_HOST_SEQ_ID_RANGE_START 0x80 | ||
34 | #define FCPIO_HOST_SEQ_ID_RANGE_END 0xff | ||
35 | |||
36 | /* | ||
37 | * Command entry type | ||
38 | */ | ||
39 | enum fcpio_type { | ||
40 | /* | ||
41 | * Initiator request types | ||
42 | */ | ||
43 | FCPIO_ICMND_16 = 0x1, | ||
44 | FCPIO_ICMND_32, | ||
45 | FCPIO_ICMND_CMPL, | ||
46 | FCPIO_ITMF, | ||
47 | FCPIO_ITMF_CMPL, | ||
48 | |||
49 | /* | ||
50 | * Target request types | ||
51 | */ | ||
52 | FCPIO_TCMND_16 = 0x11, | ||
53 | FCPIO_TCMND_32, | ||
54 | FCPIO_TDATA, | ||
55 | FCPIO_TXRDY, | ||
56 | FCPIO_TRSP, | ||
57 | FCPIO_TDRSP_CMPL, | ||
58 | FCPIO_TTMF, | ||
59 | FCPIO_TTMF_ACK, | ||
60 | FCPIO_TABORT, | ||
61 | FCPIO_TABORT_CMPL, | ||
62 | |||
63 | /* | ||
64 | * Misc request types | ||
65 | */ | ||
66 | FCPIO_ACK = 0x20, | ||
67 | FCPIO_RESET, | ||
68 | FCPIO_RESET_CMPL, | ||
69 | FCPIO_FLOGI_REG, | ||
70 | FCPIO_FLOGI_REG_CMPL, | ||
71 | FCPIO_ECHO, | ||
72 | FCPIO_ECHO_CMPL, | ||
73 | FCPIO_LUNMAP_CHNG, | ||
74 | FCPIO_LUNMAP_REQ, | ||
75 | FCPIO_LUNMAP_REQ_CMPL, | ||
76 | FCPIO_FLOGI_FIP_REG, | ||
77 | FCPIO_FLOGI_FIP_REG_CMPL, | ||
78 | }; | ||
79 | |||
80 | /* | ||
81 | * Header status codes from the firmware | ||
82 | */ | ||
83 | enum fcpio_status { | ||
84 | FCPIO_SUCCESS = 0, /* request was successful */ | ||
85 | |||
86 | /* | ||
87 | * If a request to the firmware is rejected, the original request | ||
88 | * header will be returned with the status set to one of the following: | ||
89 | */ | ||
90 | FCPIO_INVALID_HEADER, /* header contains invalid data */ | ||
91 | FCPIO_OUT_OF_RESOURCE, /* out of resources to complete request */ | ||
92 | FCPIO_INVALID_PARAM, /* some parameter in request is invalid */ | ||
93 | FCPIO_REQ_NOT_SUPPORTED, /* request type is not supported */ | ||
94 | FCPIO_IO_NOT_FOUND, /* requested I/O was not found */ | ||
95 | |||
96 | /* | ||
97 | * Once a request is processed, the firmware will usually return | ||
98 | * a cmpl message type. In cases where errors occurred, | ||
99 | * the header status field would be filled in with one of the following: | ||
100 | */ | ||
101 | FCPIO_ABORTED = 0x41, /* request was aborted */ | ||
102 | FCPIO_TIMEOUT, /* request was timed out */ | ||
103 | FCPIO_SGL_INVALID, /* request was aborted due to sgl error */ | ||
104 | FCPIO_MSS_INVALID, /* request was aborted due to mss error */ | ||
105 | FCPIO_DATA_CNT_MISMATCH, /* recv/sent more/less data than exp. */ | ||
106 | FCPIO_FW_ERR, /* request was terminated due to fw error */ | ||
107 | FCPIO_ITMF_REJECTED, /* itmf req was rejected by remote node */ | ||
108 | FCPIO_ITMF_FAILED, /* itmf req was failed by remote node */ | ||
109 | FCPIO_ITMF_INCORRECT_LUN, /* itmf req targeted incorrect LUN */ | ||
110 | FCPIO_CMND_REJECTED, /* request was invalid and rejected */ | ||
111 | FCPIO_NO_PATH_AVAIL, /* no paths to the lun was available */ | ||
112 | FCPIO_PATH_FAILED, /* i/o sent to current path failed */ | ||
113 | FCPIO_LUNMAP_CHNG_PEND, /* i/o rejected due to lunmap change */ | ||
114 | }; | ||
115 | |||
116 | /* | ||
117 | * The header command tag. All host requests will use the "tag" field | ||
118 | * to mark commands with a unique tag. When the firmware responds to | ||
119 | * a host request, it will copy the tag field into the response. | ||
120 | * | ||
121 | * The only firmware requests that will use the rx_id/ox_id fields instead | ||
122 | * of the tag field will be the target command and target task management | ||
123 | * requests. These two requests do not have corresponding host requests | ||
124 | * since they come directly from the FC initiator on the network. | ||
125 | */ | ||
126 | struct fcpio_tag { | ||
127 | union { | ||
128 | u32 req_id; | ||
129 | struct { | ||
130 | u16 rx_id; | ||
131 | u16 ox_id; | ||
132 | } ex_id; | ||
133 | } u; | ||
134 | }; | ||
135 | |||
136 | static inline void | ||
137 | fcpio_tag_id_enc(struct fcpio_tag *tag, u32 id) | ||
138 | { | ||
139 | tag->u.req_id = id; | ||
140 | } | ||
141 | |||
142 | static inline void | ||
143 | fcpio_tag_id_dec(struct fcpio_tag *tag, u32 *id) | ||
144 | { | ||
145 | *id = tag->u.req_id; | ||
146 | } | ||
147 | |||
148 | static inline void | ||
149 | fcpio_tag_exid_enc(struct fcpio_tag *tag, u16 ox_id, u16 rx_id) | ||
150 | { | ||
151 | tag->u.ex_id.rx_id = rx_id; | ||
152 | tag->u.ex_id.ox_id = ox_id; | ||
153 | } | ||
154 | |||
155 | static inline void | ||
156 | fcpio_tag_exid_dec(struct fcpio_tag *tag, u16 *ox_id, u16 *rx_id) | ||
157 | { | ||
158 | *rx_id = tag->u.ex_id.rx_id; | ||
159 | *ox_id = tag->u.ex_id.ox_id; | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | * The header for an fcpio request, whether from the firmware or from the | ||
164 | * host driver | ||
165 | */ | ||
166 | struct fcpio_header { | ||
167 | u8 type; /* enum fcpio_type */ | ||
168 | u8 status; /* header status entry */ | ||
169 | u16 _resvd; /* reserved */ | ||
170 | struct fcpio_tag tag; /* header tag */ | ||
171 | }; | ||
172 | |||
173 | static inline void | ||
174 | fcpio_header_enc(struct fcpio_header *hdr, | ||
175 | u8 type, u8 status, | ||
176 | struct fcpio_tag tag) | ||
177 | { | ||
178 | hdr->type = type; | ||
179 | hdr->status = status; | ||
180 | hdr->_resvd = 0; | ||
181 | hdr->tag = tag; | ||
182 | } | ||
183 | |||
184 | static inline void | ||
185 | fcpio_header_dec(struct fcpio_header *hdr, | ||
186 | u8 *type, u8 *status, | ||
187 | struct fcpio_tag *tag) | ||
188 | { | ||
189 | *type = hdr->type; | ||
190 | *status = hdr->status; | ||
191 | *tag = hdr->tag; | ||
192 | } | ||
193 | |||
194 | #define CDB_16 16 | ||
195 | #define CDB_32 32 | ||
196 | #define LUN_ADDRESS 8 | ||
197 | |||
198 | /* | ||
199 | * fcpio_icmnd_16: host -> firmware request | ||
200 | * | ||
201 | * used for sending out an initiator SCSI 16-byte command | ||
202 | */ | ||
203 | struct fcpio_icmnd_16 { | ||
204 | u32 lunmap_id; /* index into lunmap table */ | ||
205 | u8 special_req_flags; /* special exchange request flags */ | ||
206 | u8 _resvd0[3]; /* reserved */ | ||
207 | u32 sgl_cnt; /* scatter-gather list count */ | ||
208 | u32 sense_len; /* sense buffer length */ | ||
209 | u64 sgl_addr; /* scatter-gather list addr */ | ||
210 | u64 sense_addr; /* sense buffer address */ | ||
211 | u8 crn; /* SCSI Command Reference No. */ | ||
212 | u8 pri_ta; /* SCSI Priority and Task attribute */ | ||
213 | u8 _resvd1; /* reserved: should be 0 */ | ||
214 | u8 flags; /* command flags */ | ||
215 | u8 scsi_cdb[CDB_16]; /* SCSI Cmnd Descriptor Block */ | ||
216 | u32 data_len; /* length of data expected */ | ||
217 | u8 lun[LUN_ADDRESS]; /* FC vNIC only: LUN address */ | ||
218 | u8 _resvd2; /* reserved */ | ||
219 | u8 d_id[3]; /* FC vNIC only: Target D_ID */ | ||
220 | u16 mss; /* FC vNIC only: max burst */ | ||
221 | u16 _resvd3; /* reserved */ | ||
222 | u32 r_a_tov; /* FC vNIC only: Res. Alloc Timeout */ | ||
223 | u32 e_d_tov; /* FC vNIC only: Err Detect Timeout */ | ||
224 | }; | ||
225 | |||
226 | /* | ||
227 | * Special request flags | ||
228 | */ | ||
229 | #define FCPIO_ICMND_SRFLAG_RETRY 0x01 /* Enable Retry handling on exchange */ | ||
230 | |||
231 | /* | ||
232 | * Priority/Task Attribute settings | ||
233 | */ | ||
234 | #define FCPIO_ICMND_PTA_SIMPLE 0 /* simple task attribute */ | ||
235 | #define FCPIO_ICMND_PTA_HEADQ 1 /* head of queue task attribute */ | ||
236 | #define FCPIO_ICMND_PTA_ORDERED 2 /* ordered task attribute */ | ||
237 | #define FCPIO_ICMND_PTA_ACA 4 /* auto contingent allegiance */ | ||
238 | #define FCPIO_ICMND_PRI_SHIFT 3 /* priority field starts in bit 3 */ | ||
239 | |||
240 | /* | ||
241 | * Command flags | ||
242 | */ | ||
243 | #define FCPIO_ICMND_RDDATA 0x02 /* read data */ | ||
244 | #define FCPIO_ICMND_WRDATA 0x01 /* write data */ | ||
245 | |||
246 | /* | ||
247 | * fcpio_icmnd_32: host -> firmware request | ||
248 | * | ||
249 | * used for sending out an initiator SCSI 32-byte command | ||
250 | */ | ||
251 | struct fcpio_icmnd_32 { | ||
252 | u32 lunmap_id; /* index into lunmap table */ | ||
253 | u8 special_req_flags; /* special exchange request flags */ | ||
254 | u8 _resvd0[3]; /* reserved */ | ||
255 | u32 sgl_cnt; /* scatter-gather list count */ | ||
256 | u32 sense_len; /* sense buffer length */ | ||
257 | u64 sgl_addr; /* scatter-gather list addr */ | ||
258 | u64 sense_addr; /* sense buffer address */ | ||
259 | u8 crn; /* SCSI Command Reference No. */ | ||
260 | u8 pri_ta; /* SCSI Priority and Task attribute */ | ||
261 | u8 _resvd1; /* reserved: should be 0 */ | ||
262 | u8 flags; /* command flags */ | ||
263 | u8 scsi_cdb[CDB_32]; /* SCSI Cmnd Descriptor Block */ | ||
264 | u32 data_len; /* length of data expected */ | ||
265 | u8 lun[LUN_ADDRESS]; /* FC vNIC only: LUN address */ | ||
266 | u8 _resvd2; /* reserved */ | ||
267 | u8 d_id[3]; /* FC vNIC only: Target D_ID */ | ||
268 | u16 mss; /* FC vNIC only: max burst */ | ||
269 | u16 _resvd3; /* reserved */ | ||
270 | u32 r_a_tov; /* FC vNIC only: Res. Alloc Timeout */ | ||
271 | u32 e_d_tov; /* FC vNIC only: Error Detect Timeout */ | ||
272 | }; | ||
273 | |||
274 | /* | ||
275 | * fcpio_itmf: host -> firmware request | ||
276 | * | ||
277 | * used for requesting the firmware to abort a request and/or send out | ||
278 | * a task management function | ||
279 | * | ||
280 | * The t_tag field is only needed when the request type is ABT_TASK. | ||
281 | */ | ||
282 | struct fcpio_itmf { | ||
283 | u32 lunmap_id; /* index into lunmap table */ | ||
284 | u32 tm_req; /* SCSI Task Management request */ | ||
285 | u32 t_tag; /* header tag of fcpio to be aborted */ | ||
286 | u32 _resvd; /* _reserved */ | ||
287 | u8 lun[LUN_ADDRESS]; /* FC vNIC only: LUN address */ | ||
288 | u8 _resvd1; /* reserved */ | ||
289 | u8 d_id[3]; /* FC vNIC only: Target D_ID */ | ||
290 | u32 r_a_tov; /* FC vNIC only: R_A_TOV in msec */ | ||
291 | u32 e_d_tov; /* FC vNIC only: E_D_TOV in msec */ | ||
292 | }; | ||
293 | |||
294 | /* | ||
295 | * Task Management request | ||
296 | */ | ||
297 | enum fcpio_itmf_tm_req_type { | ||
298 | FCPIO_ITMF_ABT_TASK_TERM = 0x01, /* abort task and terminate */ | ||
299 | FCPIO_ITMF_ABT_TASK, /* abort task and issue abts */ | ||
300 | FCPIO_ITMF_ABT_TASK_SET, /* abort task set */ | ||
301 | FCPIO_ITMF_CLR_TASK_SET, /* clear task set */ | ||
302 | FCPIO_ITMF_LUN_RESET, /* logical unit reset task mgmt */ | ||
303 | FCPIO_ITMF_CLR_ACA, /* Clear ACA condition */ | ||
304 | }; | ||
305 | |||
306 | /* | ||
307 | * fcpio_tdata: host -> firmware request | ||
308 | * | ||
309 | * used for requesting the firmware to send out a read data transfer for a | ||
310 | * target command | ||
311 | */ | ||
312 | struct fcpio_tdata { | ||
313 | u16 rx_id; /* FC rx_id of target command */ | ||
314 | u16 flags; /* command flags */ | ||
315 | u32 rel_offset; /* data sequence relative offset */ | ||
316 | u32 sgl_cnt; /* scatter-gather list count */ | ||
317 | u32 data_len; /* length of data expected to send */ | ||
318 | u64 sgl_addr; /* scatter-gather list address */ | ||
319 | }; | ||
320 | |||
321 | /* | ||
322 | * Command flags | ||
323 | */ | ||
324 | #define FCPIO_TDATA_SCSI_RSP 0x01 /* send a scsi resp. after last frame */ | ||
325 | |||
326 | /* | ||
327 | * fcpio_txrdy: host -> firmware request | ||
328 | * | ||
329 | * used for requesting the firmware to send out a write data transfer for a | ||
330 | * target command | ||
331 | */ | ||
332 | struct fcpio_txrdy { | ||
333 | u16 rx_id; /* FC rx_id of target command */ | ||
334 | u16 _resvd0; /* reserved */ | ||
335 | u32 rel_offset; /* data sequence relative offset */ | ||
336 | u32 sgl_cnt; /* scatter-gather list count */ | ||
337 | u32 data_len; /* length of data expected to send */ | ||
338 | u64 sgl_addr; /* scatter-gather list address */ | ||
339 | }; | ||
340 | |||
341 | /* | ||
342 | * fcpio_trsp: host -> firmware request | ||
343 | * | ||
344 | * used for requesting the firmware to send out a response for a target | ||
345 | * command | ||
346 | */ | ||
347 | struct fcpio_trsp { | ||
348 | u16 rx_id; /* FC rx_id of target command */ | ||
349 | u16 _resvd0; /* reserved */ | ||
350 | u32 sense_len; /* sense data buffer length */ | ||
351 | u64 sense_addr; /* sense data buffer address */ | ||
352 | u16 _resvd1; /* reserved */ | ||
353 | u8 flags; /* response request flags */ | ||
354 | u8 scsi_status; /* SCSI status */ | ||
355 | u32 residual; /* SCSI data residual value of I/O */ | ||
356 | }; | ||
357 | |||
358 | /* | ||
359 | * resposnse request flags | ||
360 | */ | ||
361 | #define FCPIO_TRSP_RESID_UNDER 0x08 /* residual is valid and is underflow */ | ||
362 | #define FCPIO_TRSP_RESID_OVER 0x04 /* residual is valid and is overflow */ | ||
363 | |||
364 | /* | ||
365 | * fcpio_ttmf_ack: host -> firmware response | ||
366 | * | ||
367 | * used by the host to indicate to the firmware it has received and processed | ||
368 | * the target tmf request | ||
369 | */ | ||
370 | struct fcpio_ttmf_ack { | ||
371 | u16 rx_id; /* FC rx_id of target command */ | ||
372 | u16 _resvd0; /* reserved */ | ||
373 | u32 tmf_status; /* SCSI task management status */ | ||
374 | }; | ||
375 | |||
376 | /* | ||
377 | * fcpio_tabort: host -> firmware request | ||
378 | * | ||
379 | * used by the host to request the firmware to abort a target request that was | ||
380 | * received by the firmware | ||
381 | */ | ||
382 | struct fcpio_tabort { | ||
383 | u16 rx_id; /* rx_id of the target request */ | ||
384 | }; | ||
385 | |||
386 | /* | ||
387 | * fcpio_reset: host -> firmware request | ||
388 | * | ||
389 | * used by the host to signal a reset of the driver to the firmware | ||
390 | * and to request firmware to clean up all outstanding I/O | ||
391 | */ | ||
392 | struct fcpio_reset { | ||
393 | u32 _resvd; | ||
394 | }; | ||
395 | |||
396 | enum fcpio_flogi_reg_format_type { | ||
397 | FCPIO_FLOGI_REG_DEF_DEST = 0, /* Use the oui | s_id mac format */ | ||
398 | FCPIO_FLOGI_REG_GW_DEST, /* Use the fixed gateway mac */ | ||
399 | }; | ||
400 | |||
401 | /* | ||
402 | * fcpio_flogi_reg: host -> firmware request | ||
403 | * | ||
404 | * fc vnic only | ||
405 | * used by the host to notify the firmware of the lif's s_id | ||
406 | * and destination mac address format | ||
407 | */ | ||
408 | struct fcpio_flogi_reg { | ||
409 | u8 format; | ||
410 | u8 s_id[3]; /* FC vNIC only: Source S_ID */ | ||
411 | u8 gateway_mac[ETH_ALEN]; /* Destination gateway mac */ | ||
412 | u16 _resvd; | ||
413 | u32 r_a_tov; /* R_A_TOV in msec */ | ||
414 | u32 e_d_tov; /* E_D_TOV in msec */ | ||
415 | }; | ||
416 | |||
417 | /* | ||
418 | * fcpio_echo: host -> firmware request | ||
419 | * | ||
420 | * sends a heartbeat echo request to the firmware | ||
421 | */ | ||
422 | struct fcpio_echo { | ||
423 | u32 _resvd; | ||
424 | }; | ||
425 | |||
426 | /* | ||
427 | * fcpio_lunmap_req: host -> firmware request | ||
428 | * | ||
429 | * scsi vnic only | ||
430 | * sends a request to retrieve the lunmap table for scsi vnics | ||
431 | */ | ||
432 | struct fcpio_lunmap_req { | ||
433 | u64 addr; /* address of the buffer */ | ||
434 | u32 len; /* len of the buffer */ | ||
435 | }; | ||
436 | |||
437 | /* | ||
438 | * fcpio_flogi_fip_reg: host -> firmware request | ||
439 | * | ||
440 | * fc vnic only | ||
441 | * used by the host to notify the firmware of the lif's s_id | ||
442 | * and destination mac address format | ||
443 | */ | ||
444 | struct fcpio_flogi_fip_reg { | ||
445 | u8 _resvd0; | ||
446 | u8 s_id[3]; /* FC vNIC only: Source S_ID */ | ||
447 | u8 fcf_mac[ETH_ALEN]; /* FCF Target destination mac */ | ||
448 | u16 _resvd1; | ||
449 | u32 r_a_tov; /* R_A_TOV in msec */ | ||
450 | u32 e_d_tov; /* E_D_TOV in msec */ | ||
451 | u8 ha_mac[ETH_ALEN]; /* Host adapter source mac */ | ||
452 | u16 _resvd2; | ||
453 | }; | ||
454 | |||
455 | /* | ||
456 | * Basic structure for all fcpio structures that are sent from the host to the | ||
457 | * firmware. They are 128 bytes per structure. | ||
458 | */ | ||
459 | #define FCPIO_HOST_REQ_LEN 128 /* expected length of host requests */ | ||
460 | |||
461 | struct fcpio_host_req { | ||
462 | struct fcpio_header hdr; | ||
463 | |||
464 | union { | ||
465 | /* | ||
466 | * Defines space needed for request | ||
467 | */ | ||
468 | u8 buf[FCPIO_HOST_REQ_LEN - sizeof(struct fcpio_header)]; | ||
469 | |||
470 | /* | ||
471 | * Initiator host requests | ||
472 | */ | ||
473 | struct fcpio_icmnd_16 icmnd_16; | ||
474 | struct fcpio_icmnd_32 icmnd_32; | ||
475 | struct fcpio_itmf itmf; | ||
476 | |||
477 | /* | ||
478 | * Target host requests | ||
479 | */ | ||
480 | struct fcpio_tdata tdata; | ||
481 | struct fcpio_txrdy txrdy; | ||
482 | struct fcpio_trsp trsp; | ||
483 | struct fcpio_ttmf_ack ttmf_ack; | ||
484 | struct fcpio_tabort tabort; | ||
485 | |||
486 | /* | ||
487 | * Misc requests | ||
488 | */ | ||
489 | struct fcpio_reset reset; | ||
490 | struct fcpio_flogi_reg flogi_reg; | ||
491 | struct fcpio_echo echo; | ||
492 | struct fcpio_lunmap_req lunmap_req; | ||
493 | struct fcpio_flogi_fip_reg flogi_fip_reg; | ||
494 | } u; | ||
495 | }; | ||
496 | |||
497 | /* | ||
498 | * fcpio_icmnd_cmpl: firmware -> host response | ||
499 | * | ||
500 | * used for sending the host a response to an initiator command | ||
501 | */ | ||
502 | struct fcpio_icmnd_cmpl { | ||
503 | u8 _resvd0[6]; /* reserved */ | ||
504 | u8 flags; /* response flags */ | ||
505 | u8 scsi_status; /* SCSI status */ | ||
506 | u32 residual; /* SCSI data residual length */ | ||
507 | u32 sense_len; /* SCSI sense length */ | ||
508 | }; | ||
509 | |||
510 | /* | ||
511 | * response flags | ||
512 | */ | ||
513 | #define FCPIO_ICMND_CMPL_RESID_UNDER 0x08 /* resid under and valid */ | ||
514 | #define FCPIO_ICMND_CMPL_RESID_OVER 0x04 /* resid over and valid */ | ||
515 | |||
516 | /* | ||
517 | * fcpio_itmf_cmpl: firmware -> host response | ||
518 | * | ||
519 | * used for sending the host a response for a itmf request | ||
520 | */ | ||
521 | struct fcpio_itmf_cmpl { | ||
522 | u32 _resvd; /* reserved */ | ||
523 | }; | ||
524 | |||
525 | /* | ||
526 | * fcpio_tcmnd_16: firmware -> host request | ||
527 | * | ||
528 | * used by the firmware to notify the host of an incoming target SCSI 16-Byte | ||
529 | * request | ||
530 | */ | ||
531 | struct fcpio_tcmnd_16 { | ||
532 | u8 lun[LUN_ADDRESS]; /* FC vNIC only: LUN address */ | ||
533 | u8 crn; /* SCSI Command Reference No. */ | ||
534 | u8 pri_ta; /* SCSI Priority and Task attribute */ | ||
535 | u8 _resvd2; /* reserved: should be 0 */ | ||
536 | u8 flags; /* command flags */ | ||
537 | u8 scsi_cdb[CDB_16]; /* SCSI Cmnd Descriptor Block */ | ||
538 | u32 data_len; /* length of data expected */ | ||
539 | u8 _resvd1; /* reserved */ | ||
540 | u8 s_id[3]; /* FC vNIC only: Source S_ID */ | ||
541 | }; | ||
542 | |||
543 | /* | ||
544 | * Priority/Task Attribute settings | ||
545 | */ | ||
546 | #define FCPIO_TCMND_PTA_SIMPLE 0 /* simple task attribute */ | ||
547 | #define FCPIO_TCMND_PTA_HEADQ 1 /* head of queue task attribute */ | ||
548 | #define FCPIO_TCMND_PTA_ORDERED 2 /* ordered task attribute */ | ||
549 | #define FCPIO_TCMND_PTA_ACA 4 /* auto contingent allegiance */ | ||
550 | #define FCPIO_TCMND_PRI_SHIFT 3 /* priority field starts in bit 3 */ | ||
551 | |||
552 | /* | ||
553 | * Command flags | ||
554 | */ | ||
555 | #define FCPIO_TCMND_RDDATA 0x02 /* read data */ | ||
556 | #define FCPIO_TCMND_WRDATA 0x01 /* write data */ | ||
557 | |||
558 | /* | ||
559 | * fcpio_tcmnd_32: firmware -> host request | ||
560 | * | ||
561 | * used by the firmware to notify the host of an incoming target SCSI 32-Byte | ||
562 | * request | ||
563 | */ | ||
564 | struct fcpio_tcmnd_32 { | ||
565 | u8 lun[LUN_ADDRESS]; /* FC vNIC only: LUN address */ | ||
566 | u8 crn; /* SCSI Command Reference No. */ | ||
567 | u8 pri_ta; /* SCSI Priority and Task attribute */ | ||
568 | u8 _resvd2; /* reserved: should be 0 */ | ||
569 | u8 flags; /* command flags */ | ||
570 | u8 scsi_cdb[CDB_32]; /* SCSI Cmnd Descriptor Block */ | ||
571 | u32 data_len; /* length of data expected */ | ||
572 | u8 _resvd0; /* reserved */ | ||
573 | u8 s_id[3]; /* FC vNIC only: Source S_ID */ | ||
574 | }; | ||
575 | |||
576 | /* | ||
577 | * fcpio_tdrsp_cmpl: firmware -> host response | ||
578 | * | ||
579 | * used by the firmware to notify the host of a response to a host target | ||
580 | * command | ||
581 | */ | ||
582 | struct fcpio_tdrsp_cmpl { | ||
583 | u16 rx_id; /* rx_id of the target request */ | ||
584 | u16 _resvd0; /* reserved */ | ||
585 | }; | ||
586 | |||
587 | /* | ||
588 | * fcpio_ttmf: firmware -> host request | ||
589 | * | ||
590 | * used by the firmware to notify the host of an incoming task management | ||
591 | * function request | ||
592 | */ | ||
593 | struct fcpio_ttmf { | ||
594 | u8 _resvd0; /* reserved */ | ||
595 | u8 s_id[3]; /* FC vNIC only: Source S_ID */ | ||
596 | u8 lun[LUN_ADDRESS]; /* FC vNIC only: LUN address */ | ||
597 | u8 crn; /* SCSI Command Reference No. */ | ||
598 | u8 _resvd2[3]; /* reserved */ | ||
599 | u32 tmf_type; /* task management request type */ | ||
600 | }; | ||
601 | |||
602 | /* | ||
603 | * Task Management request | ||
604 | */ | ||
605 | #define FCPIO_TTMF_CLR_ACA 0x40 /* Clear ACA condition */ | ||
606 | #define FCPIO_TTMF_LUN_RESET 0x10 /* logical unit reset task mgmt */ | ||
607 | #define FCPIO_TTMF_CLR_TASK_SET 0x04 /* clear task set */ | ||
608 | #define FCPIO_TTMF_ABT_TASK_SET 0x02 /* abort task set */ | ||
609 | #define FCPIO_TTMF_ABT_TASK 0x01 /* abort task */ | ||
610 | |||
611 | /* | ||
612 | * fcpio_tabort_cmpl: firmware -> host response | ||
613 | * | ||
614 | * used by the firmware to respond to a host's tabort request | ||
615 | */ | ||
616 | struct fcpio_tabort_cmpl { | ||
617 | u16 rx_id; /* rx_id of the target request */ | ||
618 | u16 _resvd0; /* reserved */ | ||
619 | }; | ||
620 | |||
621 | /* | ||
622 | * fcpio_ack: firmware -> host response | ||
623 | * | ||
624 | * used by firmware to notify the host of the last work request received | ||
625 | */ | ||
626 | struct fcpio_ack { | ||
627 | u16 request_out; /* last host entry received */ | ||
628 | u16 _resvd; | ||
629 | }; | ||
630 | |||
631 | /* | ||
632 | * fcpio_reset_cmpl: firmware -> host response | ||
633 | * | ||
634 | * use by firmware to respond to the host's reset request | ||
635 | */ | ||
636 | struct fcpio_reset_cmpl { | ||
637 | u16 vnic_id; | ||
638 | }; | ||
639 | |||
640 | /* | ||
641 | * fcpio_flogi_reg_cmpl: firmware -> host response | ||
642 | * | ||
643 | * fc vnic only | ||
644 | * response to the fcpio_flogi_reg request | ||
645 | */ | ||
646 | struct fcpio_flogi_reg_cmpl { | ||
647 | u32 _resvd; | ||
648 | }; | ||
649 | |||
650 | /* | ||
651 | * fcpio_echo_cmpl: firmware -> host response | ||
652 | * | ||
653 | * response to the fcpio_echo request | ||
654 | */ | ||
655 | struct fcpio_echo_cmpl { | ||
656 | u32 _resvd; | ||
657 | }; | ||
658 | |||
659 | /* | ||
660 | * fcpio_lunmap_chng: firmware -> host notification | ||
661 | * | ||
662 | * scsi vnic only | ||
663 | * notifies the host that the lunmap tables have changed | ||
664 | */ | ||
665 | struct fcpio_lunmap_chng { | ||
666 | u32 _resvd; | ||
667 | }; | ||
668 | |||
669 | /* | ||
670 | * fcpio_lunmap_req_cmpl: firmware -> host response | ||
671 | * | ||
672 | * scsi vnic only | ||
673 | * response for lunmap table request from the host | ||
674 | */ | ||
675 | struct fcpio_lunmap_req_cmpl { | ||
676 | u32 _resvd; | ||
677 | }; | ||
678 | |||
679 | /* | ||
680 | * Basic structure for all fcpio structures that are sent from the firmware to | ||
681 | * the host. They are 64 bytes per structure. | ||
682 | */ | ||
683 | #define FCPIO_FW_REQ_LEN 64 /* expected length of fw requests */ | ||
684 | struct fcpio_fw_req { | ||
685 | struct fcpio_header hdr; | ||
686 | |||
687 | union { | ||
688 | /* | ||
689 | * Defines space needed for request | ||
690 | */ | ||
691 | u8 buf[FCPIO_FW_REQ_LEN - sizeof(struct fcpio_header)]; | ||
692 | |||
693 | /* | ||
694 | * Initiator firmware responses | ||
695 | */ | ||
696 | struct fcpio_icmnd_cmpl icmnd_cmpl; | ||
697 | struct fcpio_itmf_cmpl itmf_cmpl; | ||
698 | |||
699 | /* | ||
700 | * Target firmware new requests | ||
701 | */ | ||
702 | struct fcpio_tcmnd_16 tcmnd_16; | ||
703 | struct fcpio_tcmnd_32 tcmnd_32; | ||
704 | |||
705 | /* | ||
706 | * Target firmware responses | ||
707 | */ | ||
708 | struct fcpio_tdrsp_cmpl tdrsp_cmpl; | ||
709 | struct fcpio_ttmf ttmf; | ||
710 | struct fcpio_tabort_cmpl tabort_cmpl; | ||
711 | |||
712 | /* | ||
713 | * Firmware response to work received | ||
714 | */ | ||
715 | struct fcpio_ack ack; | ||
716 | |||
717 | /* | ||
718 | * Misc requests | ||
719 | */ | ||
720 | struct fcpio_reset_cmpl reset_cmpl; | ||
721 | struct fcpio_flogi_reg_cmpl flogi_reg_cmpl; | ||
722 | struct fcpio_echo_cmpl echo_cmpl; | ||
723 | struct fcpio_lunmap_chng lunmap_chng; | ||
724 | struct fcpio_lunmap_req_cmpl lunmap_req_cmpl; | ||
725 | } u; | ||
726 | }; | ||
727 | |||
728 | /* | ||
729 | * Access routines to encode and decode the color bit, which is the most | ||
730 | * significant bit of the MSB of the structure | ||
731 | */ | ||
732 | static inline void fcpio_color_enc(struct fcpio_fw_req *fw_req, u8 color) | ||
733 | { | ||
734 | u8 *c = ((u8 *) fw_req) + sizeof(struct fcpio_fw_req) - 1; | ||
735 | |||
736 | if (color) | ||
737 | *c |= 0x80; | ||
738 | else | ||
739 | *c &= ~0x80; | ||
740 | } | ||
741 | |||
742 | static inline void fcpio_color_dec(struct fcpio_fw_req *fw_req, u8 *color) | ||
743 | { | ||
744 | u8 *c = ((u8 *) fw_req) + sizeof(struct fcpio_fw_req) - 1; | ||
745 | |||
746 | *color = *c >> 7; | ||
747 | |||
748 | /* | ||
749 | * Make sure color bit is read from desc *before* other fields | ||
750 | * are read from desc. Hardware guarantees color bit is last | ||
751 | * bit (byte) written. Adding the rmb() prevents the compiler | ||
752 | * and/or CPU from reordering the reads which would potentially | ||
753 | * result in reading stale values. | ||
754 | */ | ||
755 | |||
756 | rmb(); | ||
757 | |||
758 | } | ||
759 | |||
760 | /* | ||
761 | * Lunmap table entry for scsi vnics | ||
762 | */ | ||
763 | #define FCPIO_LUNMAP_TABLE_SIZE 256 | ||
764 | #define FCPIO_FLAGS_LUNMAP_VALID 0x80 | ||
765 | #define FCPIO_FLAGS_BOOT 0x01 | ||
766 | struct fcpio_lunmap_entry { | ||
767 | u8 bus; | ||
768 | u8 target; | ||
769 | u8 lun; | ||
770 | u8 path_cnt; | ||
771 | u16 flags; | ||
772 | u16 update_cnt; | ||
773 | }; | ||
774 | |||
775 | struct fcpio_lunmap_tbl { | ||
776 | u32 update_cnt; | ||
777 | struct fcpio_lunmap_entry lunmaps[FCPIO_LUNMAP_TABLE_SIZE]; | ||
778 | }; | ||
779 | |||
780 | #endif /* _FCPIO_H_ */ | ||
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h new file mode 100644 index 000000000000..e4c0a3d7d87b --- /dev/null +++ b/drivers/scsi/fnic/fnic.h | |||
@@ -0,0 +1,265 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _FNIC_H_ | ||
19 | #define _FNIC_H_ | ||
20 | |||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/netdevice.h> | ||
23 | #include <linux/workqueue.h> | ||
24 | #include <scsi/libfc.h> | ||
25 | #include "fnic_io.h" | ||
26 | #include "fnic_res.h" | ||
27 | #include "vnic_dev.h" | ||
28 | #include "vnic_wq.h" | ||
29 | #include "vnic_rq.h" | ||
30 | #include "vnic_cq.h" | ||
31 | #include "vnic_wq_copy.h" | ||
32 | #include "vnic_intr.h" | ||
33 | #include "vnic_stats.h" | ||
34 | #include "vnic_scsi.h" | ||
35 | |||
36 | #define DRV_NAME "fnic" | ||
37 | #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" | ||
38 | #define DRV_VERSION "1.0.0.1121" | ||
39 | #define PFX DRV_NAME ": " | ||
40 | #define DFX DRV_NAME "%d: " | ||
41 | |||
42 | #define DESC_CLEAN_LOW_WATERMARK 8 | ||
43 | #define FNIC_MAX_IO_REQ 2048 /* scsi_cmnd tag map entries */ | ||
44 | #define FNIC_IO_LOCKS 64 /* IO locks: power of 2 */ | ||
45 | #define FNIC_DFLT_QUEUE_DEPTH 32 | ||
46 | #define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */ | ||
47 | |||
48 | /* | ||
49 | * Tag bits used for special requests. | ||
50 | */ | ||
51 | #define BIT(nr) (1UL << (nr)) | ||
52 | #define FNIC_TAG_ABORT BIT(30) /* tag bit indicating abort */ | ||
53 | #define FNIC_TAG_DEV_RST BIT(29) /* indicates device reset */ | ||
54 | #define FNIC_TAG_MASK (BIT(24) - 1) /* mask for lookup */ | ||
55 | #define FNIC_NO_TAG -1 | ||
56 | |||
57 | /* | ||
58 | * Usage of the scsi_cmnd scratchpad. | ||
59 | * These fields are locked by the hashed io_req_lock. | ||
60 | */ | ||
61 | #define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr) | ||
62 | #define CMD_STATE(Cmnd) ((Cmnd)->SCp.phase) | ||
63 | #define CMD_ABTS_STATUS(Cmnd) ((Cmnd)->SCp.Message) | ||
64 | #define CMD_LR_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in) | ||
65 | #define CMD_TAG(Cmnd) ((Cmnd)->SCp.sent_command) | ||
66 | |||
67 | #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ | ||
68 | |||
69 | #define FNIC_LUN_RESET_TIMEOUT 10000 /* mSec */ | ||
70 | #define FNIC_HOST_RESET_TIMEOUT 10000 /* mSec */ | ||
71 | #define FNIC_RMDEVICE_TIMEOUT 1000 /* mSec */ | ||
72 | #define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */ | ||
73 | |||
74 | #define FNIC_MAX_FCP_TARGET 256 | ||
75 | |||
76 | extern unsigned int fnic_log_level; | ||
77 | |||
78 | #define FNIC_MAIN_LOGGING 0x01 | ||
79 | #define FNIC_FCS_LOGGING 0x02 | ||
80 | #define FNIC_SCSI_LOGGING 0x04 | ||
81 | #define FNIC_ISR_LOGGING 0x08 | ||
82 | |||
83 | #define FNIC_CHECK_LOGGING(LEVEL, CMD) \ | ||
84 | do { \ | ||
85 | if (unlikely(fnic_log_level & LEVEL)) \ | ||
86 | do { \ | ||
87 | CMD; \ | ||
88 | } while (0); \ | ||
89 | } while (0) | ||
90 | |||
91 | #define FNIC_MAIN_DBG(kern_level, host, fmt, args...) \ | ||
92 | FNIC_CHECK_LOGGING(FNIC_MAIN_LOGGING, \ | ||
93 | shost_printk(kern_level, host, fmt, ##args);) | ||
94 | |||
95 | #define FNIC_FCS_DBG(kern_level, host, fmt, args...) \ | ||
96 | FNIC_CHECK_LOGGING(FNIC_FCS_LOGGING, \ | ||
97 | shost_printk(kern_level, host, fmt, ##args);) | ||
98 | |||
99 | #define FNIC_SCSI_DBG(kern_level, host, fmt, args...) \ | ||
100 | FNIC_CHECK_LOGGING(FNIC_SCSI_LOGGING, \ | ||
101 | shost_printk(kern_level, host, fmt, ##args);) | ||
102 | |||
103 | #define FNIC_ISR_DBG(kern_level, host, fmt, args...) \ | ||
104 | FNIC_CHECK_LOGGING(FNIC_ISR_LOGGING, \ | ||
105 | shost_printk(kern_level, host, fmt, ##args);) | ||
106 | |||
107 | extern const char *fnic_state_str[]; | ||
108 | |||
109 | enum fnic_intx_intr_index { | ||
110 | FNIC_INTX_WQ_RQ_COPYWQ, | ||
111 | FNIC_INTX_ERR, | ||
112 | FNIC_INTX_NOTIFY, | ||
113 | FNIC_INTX_INTR_MAX, | ||
114 | }; | ||
115 | |||
116 | enum fnic_msix_intr_index { | ||
117 | FNIC_MSIX_RQ, | ||
118 | FNIC_MSIX_WQ, | ||
119 | FNIC_MSIX_WQ_COPY, | ||
120 | FNIC_MSIX_ERR_NOTIFY, | ||
121 | FNIC_MSIX_INTR_MAX, | ||
122 | }; | ||
123 | |||
124 | struct fnic_msix_entry { | ||
125 | int requested; | ||
126 | char devname[IFNAMSIZ]; | ||
127 | irqreturn_t (*isr)(int, void *); | ||
128 | void *devid; | ||
129 | }; | ||
130 | |||
131 | enum fnic_state { | ||
132 | FNIC_IN_FC_MODE = 0, | ||
133 | FNIC_IN_FC_TRANS_ETH_MODE, | ||
134 | FNIC_IN_ETH_MODE, | ||
135 | FNIC_IN_ETH_TRANS_FC_MODE, | ||
136 | }; | ||
137 | |||
138 | #define FNIC_WQ_COPY_MAX 1 | ||
139 | #define FNIC_WQ_MAX 1 | ||
140 | #define FNIC_RQ_MAX 1 | ||
141 | #define FNIC_CQ_MAX (FNIC_WQ_COPY_MAX + FNIC_WQ_MAX + FNIC_RQ_MAX) | ||
142 | |||
143 | struct mempool; | ||
144 | |||
145 | /* Per-instance private data structure */ | ||
146 | struct fnic { | ||
147 | struct fc_lport *lport; | ||
148 | struct vnic_dev_bar bar0; | ||
149 | |||
150 | struct msix_entry msix_entry[FNIC_MSIX_INTR_MAX]; | ||
151 | struct fnic_msix_entry msix[FNIC_MSIX_INTR_MAX]; | ||
152 | |||
153 | struct vnic_stats *stats; | ||
154 | unsigned long stats_time; /* time of stats update */ | ||
155 | struct vnic_nic_cfg *nic_cfg; | ||
156 | char name[IFNAMSIZ]; | ||
157 | struct timer_list notify_timer; /* used for MSI interrupts */ | ||
158 | |||
159 | unsigned int err_intr_offset; | ||
160 | unsigned int link_intr_offset; | ||
161 | |||
162 | unsigned int wq_count; | ||
163 | unsigned int cq_count; | ||
164 | |||
165 | u32 fcoui_mode:1; /* use fcoui address*/ | ||
166 | u32 vlan_hw_insert:1; /* let hw insert the tag */ | ||
167 | u32 in_remove:1; /* fnic device in removal */ | ||
168 | u32 stop_rx_link_events:1; /* stop proc. rx frames, link events */ | ||
169 | |||
170 | struct completion *remove_wait; /* device remove thread blocks */ | ||
171 | |||
172 | struct fc_frame *flogi; | ||
173 | struct fc_frame *flogi_resp; | ||
174 | u16 flogi_oxid; | ||
175 | unsigned long s_id; | ||
176 | enum fnic_state state; | ||
177 | spinlock_t fnic_lock; | ||
178 | |||
179 | u16 vlan_id; /* VLAN tag including priority */ | ||
180 | u8 mac_addr[ETH_ALEN]; | ||
181 | u8 dest_addr[ETH_ALEN]; | ||
182 | u8 data_src_addr[ETH_ALEN]; | ||
183 | u64 fcp_input_bytes; /* internal statistic */ | ||
184 | u64 fcp_output_bytes; /* internal statistic */ | ||
185 | u32 link_down_cnt; | ||
186 | int link_status; | ||
187 | |||
188 | struct list_head list; | ||
189 | struct pci_dev *pdev; | ||
190 | struct vnic_fc_config config; | ||
191 | struct vnic_dev *vdev; | ||
192 | unsigned int raw_wq_count; | ||
193 | unsigned int wq_copy_count; | ||
194 | unsigned int rq_count; | ||
195 | int fw_ack_index[FNIC_WQ_COPY_MAX]; | ||
196 | unsigned short fw_ack_recd[FNIC_WQ_COPY_MAX]; | ||
197 | unsigned short wq_copy_desc_low[FNIC_WQ_COPY_MAX]; | ||
198 | unsigned int intr_count; | ||
199 | u32 __iomem *legacy_pba; | ||
200 | struct fnic_host_tag *tags; | ||
201 | mempool_t *io_req_pool; | ||
202 | mempool_t *io_sgl_pool[FNIC_SGL_NUM_CACHES]; | ||
203 | spinlock_t io_req_lock[FNIC_IO_LOCKS]; /* locks for scsi cmnds */ | ||
204 | |||
205 | struct work_struct link_work; | ||
206 | struct work_struct frame_work; | ||
207 | struct sk_buff_head frame_queue; | ||
208 | |||
209 | /* copy work queue cache line section */ | ||
210 | ____cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; | ||
211 | /* completion queue cache line section */ | ||
212 | ____cacheline_aligned struct vnic_cq cq[FNIC_CQ_MAX]; | ||
213 | |||
214 | spinlock_t wq_copy_lock[FNIC_WQ_COPY_MAX]; | ||
215 | |||
216 | /* work queue cache line section */ | ||
217 | ____cacheline_aligned struct vnic_wq wq[FNIC_WQ_MAX]; | ||
218 | spinlock_t wq_lock[FNIC_WQ_MAX]; | ||
219 | |||
220 | /* receive queue cache line section */ | ||
221 | ____cacheline_aligned struct vnic_rq rq[FNIC_RQ_MAX]; | ||
222 | |||
223 | /* interrupt resource cache line section */ | ||
224 | ____cacheline_aligned struct vnic_intr intr[FNIC_MSIX_INTR_MAX]; | ||
225 | }; | ||
226 | |||
227 | extern struct workqueue_struct *fnic_event_queue; | ||
228 | extern struct device_attribute *fnic_attrs[]; | ||
229 | |||
230 | void fnic_clear_intr_mode(struct fnic *fnic); | ||
231 | int fnic_set_intr_mode(struct fnic *fnic); | ||
232 | void fnic_free_intr(struct fnic *fnic); | ||
233 | int fnic_request_intr(struct fnic *fnic); | ||
234 | |||
235 | int fnic_send(struct fc_lport *, struct fc_frame *); | ||
236 | void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); | ||
237 | void fnic_handle_frame(struct work_struct *work); | ||
238 | void fnic_handle_link(struct work_struct *work); | ||
239 | int fnic_rq_cmpl_handler(struct fnic *fnic, int); | ||
240 | int fnic_alloc_rq_frame(struct vnic_rq *rq); | ||
241 | void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); | ||
242 | int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp); | ||
243 | |||
244 | int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); | ||
245 | int fnic_abort_cmd(struct scsi_cmnd *); | ||
246 | int fnic_device_reset(struct scsi_cmnd *); | ||
247 | int fnic_host_reset(struct scsi_cmnd *); | ||
248 | int fnic_reset(struct Scsi_Host *); | ||
249 | void fnic_scsi_cleanup(struct fc_lport *); | ||
250 | void fnic_scsi_abort_io(struct fc_lport *); | ||
251 | void fnic_empty_scsi_cleanup(struct fc_lport *); | ||
252 | void fnic_exch_mgr_reset(struct fc_lport *, u32, u32); | ||
253 | int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int); | ||
254 | int fnic_wq_cmpl_handler(struct fnic *fnic, int); | ||
255 | int fnic_flogi_reg_handler(struct fnic *fnic); | ||
256 | void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq, | ||
257 | struct fcpio_host_req *desc); | ||
258 | int fnic_fw_reset_handler(struct fnic *fnic); | ||
259 | void fnic_terminate_rport_io(struct fc_rport *); | ||
260 | const char *fnic_state_to_str(unsigned int state); | ||
261 | |||
262 | void fnic_log_q_error(struct fnic *fnic); | ||
263 | void fnic_handle_link_event(struct fnic *fnic); | ||
264 | |||
265 | #endif /* _FNIC_H_ */ | ||
diff --git a/drivers/scsi/fnic/fnic_attrs.c b/drivers/scsi/fnic/fnic_attrs.c new file mode 100644 index 000000000000..aea0c3becfd4 --- /dev/null +++ b/drivers/scsi/fnic/fnic_attrs.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <scsi/scsi_host.h> | ||
21 | #include "fnic.h" | ||
22 | |||
23 | static ssize_t fnic_show_state(struct device *dev, | ||
24 | struct device_attribute *attr, char *buf) | ||
25 | { | ||
26 | struct fc_lport *lp = shost_priv(class_to_shost(dev)); | ||
27 | struct fnic *fnic = lport_priv(lp); | ||
28 | |||
29 | return snprintf(buf, PAGE_SIZE, "%s\n", fnic_state_str[fnic->state]); | ||
30 | } | ||
31 | |||
32 | static ssize_t fnic_show_drv_version(struct device *dev, | ||
33 | struct device_attribute *attr, char *buf) | ||
34 | { | ||
35 | return snprintf(buf, PAGE_SIZE, "%s\n", DRV_VERSION); | ||
36 | } | ||
37 | |||
38 | static ssize_t fnic_show_link_state(struct device *dev, | ||
39 | struct device_attribute *attr, char *buf) | ||
40 | { | ||
41 | struct fc_lport *lp = shost_priv(class_to_shost(dev)); | ||
42 | |||
43 | return snprintf(buf, PAGE_SIZE, "%s\n", (lp->link_up) | ||
44 | ? "Link Up" : "Link Down"); | ||
45 | } | ||
46 | |||
47 | static DEVICE_ATTR(fnic_state, S_IRUGO, fnic_show_state, NULL); | ||
48 | static DEVICE_ATTR(drv_version, S_IRUGO, fnic_show_drv_version, NULL); | ||
49 | static DEVICE_ATTR(link_state, S_IRUGO, fnic_show_link_state, NULL); | ||
50 | |||
51 | struct device_attribute *fnic_attrs[] = { | ||
52 | &dev_attr_fnic_state, | ||
53 | &dev_attr_drv_version, | ||
54 | &dev_attr_link_state, | ||
55 | NULL, | ||
56 | }; | ||
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c new file mode 100644 index 000000000000..07e6eedb83ce --- /dev/null +++ b/drivers/scsi/fnic/fnic_fcs.c | |||
@@ -0,0 +1,742 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/skbuff.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/if_ether.h> | ||
24 | #include <linux/if_vlan.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | #include <scsi/fc/fc_els.h> | ||
27 | #include <scsi/fc/fc_fcoe.h> | ||
28 | #include <scsi/fc_frame.h> | ||
29 | #include <scsi/libfc.h> | ||
30 | #include "fnic_io.h" | ||
31 | #include "fnic.h" | ||
32 | #include "cq_enet_desc.h" | ||
33 | #include "cq_exch_desc.h" | ||
34 | |||
35 | struct workqueue_struct *fnic_event_queue; | ||
36 | |||
37 | void fnic_handle_link(struct work_struct *work) | ||
38 | { | ||
39 | struct fnic *fnic = container_of(work, struct fnic, link_work); | ||
40 | unsigned long flags; | ||
41 | int old_link_status; | ||
42 | u32 old_link_down_cnt; | ||
43 | |||
44 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
45 | |||
46 | if (fnic->stop_rx_link_events) { | ||
47 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | old_link_down_cnt = fnic->link_down_cnt; | ||
52 | old_link_status = fnic->link_status; | ||
53 | fnic->link_status = vnic_dev_link_status(fnic->vdev); | ||
54 | fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev); | ||
55 | |||
56 | if (old_link_status == fnic->link_status) { | ||
57 | if (!fnic->link_status) | ||
58 | /* DOWN -> DOWN */ | ||
59 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
60 | else { | ||
61 | if (old_link_down_cnt != fnic->link_down_cnt) { | ||
62 | /* UP -> DOWN -> UP */ | ||
63 | fnic->lport->host_stats.link_failure_count++; | ||
64 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
65 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, | ||
66 | "link down\n"); | ||
67 | fc_linkdown(fnic->lport); | ||
68 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, | ||
69 | "link up\n"); | ||
70 | fc_linkup(fnic->lport); | ||
71 | } else | ||
72 | /* UP -> UP */ | ||
73 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
74 | } | ||
75 | } else if (fnic->link_status) { | ||
76 | /* DOWN -> UP */ | ||
77 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
78 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n"); | ||
79 | fc_linkup(fnic->lport); | ||
80 | } else { | ||
81 | /* UP -> DOWN */ | ||
82 | fnic->lport->host_stats.link_failure_count++; | ||
83 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
84 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n"); | ||
85 | fc_linkdown(fnic->lport); | ||
86 | } | ||
87 | |||
88 | } | ||
89 | |||
90 | /* | ||
91 | * This function passes incoming fabric frames to libFC | ||
92 | */ | ||
93 | void fnic_handle_frame(struct work_struct *work) | ||
94 | { | ||
95 | struct fnic *fnic = container_of(work, struct fnic, frame_work); | ||
96 | struct fc_lport *lp = fnic->lport; | ||
97 | unsigned long flags; | ||
98 | struct sk_buff *skb; | ||
99 | struct fc_frame *fp; | ||
100 | |||
101 | while ((skb = skb_dequeue(&fnic->frame_queue))) { | ||
102 | |||
103 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
104 | if (fnic->stop_rx_link_events) { | ||
105 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
106 | dev_kfree_skb(skb); | ||
107 | return; | ||
108 | } | ||
109 | fp = (struct fc_frame *)skb; | ||
110 | /* if Flogi resp frame, register the address */ | ||
111 | if (fr_flags(fp)) { | ||
112 | vnic_dev_add_addr(fnic->vdev, | ||
113 | fnic->data_src_addr); | ||
114 | fr_flags(fp) = 0; | ||
115 | } | ||
116 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
117 | |||
118 | fc_exch_recv(lp, lp->emp, fp); | ||
119 | } | ||
120 | |||
121 | } | ||
122 | |||
123 | static inline void fnic_import_rq_fc_frame(struct sk_buff *skb, | ||
124 | u32 len, u8 sof, u8 eof) | ||
125 | { | ||
126 | struct fc_frame *fp = (struct fc_frame *)skb; | ||
127 | |||
128 | skb_trim(skb, len); | ||
129 | fr_eof(fp) = eof; | ||
130 | fr_sof(fp) = sof; | ||
131 | } | ||
132 | |||
133 | |||
134 | static inline int fnic_import_rq_eth_pkt(struct sk_buff *skb, u32 len) | ||
135 | { | ||
136 | struct fc_frame *fp; | ||
137 | struct ethhdr *eh; | ||
138 | struct vlan_ethhdr *vh; | ||
139 | struct fcoe_hdr *fcoe_hdr; | ||
140 | struct fcoe_crc_eof *ft; | ||
141 | u32 transport_len = 0; | ||
142 | |||
143 | eh = (struct ethhdr *)skb->data; | ||
144 | vh = (struct vlan_ethhdr *)skb->data; | ||
145 | if (vh->h_vlan_proto == htons(ETH_P_8021Q) && | ||
146 | vh->h_vlan_encapsulated_proto == htons(ETH_P_FCOE)) { | ||
147 | skb_pull(skb, sizeof(struct vlan_ethhdr)); | ||
148 | transport_len += sizeof(struct vlan_ethhdr); | ||
149 | } else if (eh->h_proto == htons(ETH_P_FCOE)) { | ||
150 | transport_len += sizeof(struct ethhdr); | ||
151 | skb_pull(skb, sizeof(struct ethhdr)); | ||
152 | } else | ||
153 | return -1; | ||
154 | |||
155 | fcoe_hdr = (struct fcoe_hdr *)skb->data; | ||
156 | if (FC_FCOE_DECAPS_VER(fcoe_hdr) != FC_FCOE_VER) | ||
157 | return -1; | ||
158 | |||
159 | fp = (struct fc_frame *)skb; | ||
160 | fc_frame_init(fp); | ||
161 | fr_sof(fp) = fcoe_hdr->fcoe_sof; | ||
162 | skb_pull(skb, sizeof(struct fcoe_hdr)); | ||
163 | transport_len += sizeof(struct fcoe_hdr); | ||
164 | |||
165 | ft = (struct fcoe_crc_eof *)(skb->data + len - | ||
166 | transport_len - sizeof(*ft)); | ||
167 | fr_eof(fp) = ft->fcoe_eof; | ||
168 | skb_trim(skb, len - transport_len - sizeof(*ft)); | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static inline int fnic_handle_flogi_resp(struct fnic *fnic, | ||
173 | struct fc_frame *fp) | ||
174 | { | ||
175 | u8 mac[ETH_ALEN] = FC_FCOE_FLOGI_MAC; | ||
176 | struct ethhdr *eth_hdr; | ||
177 | struct fc_frame_header *fh; | ||
178 | int ret = 0; | ||
179 | unsigned long flags; | ||
180 | struct fc_frame *old_flogi_resp = NULL; | ||
181 | |||
182 | fh = (struct fc_frame_header *)fr_hdr(fp); | ||
183 | |||
184 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
185 | |||
186 | if (fnic->state == FNIC_IN_ETH_MODE) { | ||
187 | |||
188 | /* | ||
189 | * Check if oxid matches on taking the lock. A new Flogi | ||
190 | * issued by libFC might have changed the fnic cached oxid | ||
191 | */ | ||
192 | if (fnic->flogi_oxid != ntohs(fh->fh_ox_id)) { | ||
193 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, | ||
194 | "Flogi response oxid not" | ||
195 | " matching cached oxid, dropping frame" | ||
196 | "\n"); | ||
197 | ret = -1; | ||
198 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
199 | dev_kfree_skb_irq(fp_skb(fp)); | ||
200 | goto handle_flogi_resp_end; | ||
201 | } | ||
202 | |||
203 | /* Drop older cached flogi response frame, cache this frame */ | ||
204 | old_flogi_resp = fnic->flogi_resp; | ||
205 | fnic->flogi_resp = fp; | ||
206 | fnic->flogi_oxid = FC_XID_UNKNOWN; | ||
207 | |||
208 | /* | ||
209 | * this frame is part of flogi get the src mac addr from this | ||
210 | * frame if the src mac is fcoui based then we mark the | ||
211 | * address mode flag to use fcoui base for dst mac addr | ||
212 | * otherwise we have to store the fcoe gateway addr | ||
213 | */ | ||
214 | eth_hdr = (struct ethhdr *)skb_mac_header(fp_skb(fp)); | ||
215 | memcpy(mac, eth_hdr->h_source, ETH_ALEN); | ||
216 | |||
217 | if (ntoh24(mac) == FC_FCOE_OUI) | ||
218 | fnic->fcoui_mode = 1; | ||
219 | else { | ||
220 | fnic->fcoui_mode = 0; | ||
221 | memcpy(fnic->dest_addr, mac, ETH_ALEN); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Except for Flogi frame, all outbound frames from us have the | ||
226 | * Eth Src address as FC_FCOE_OUI"our_sid". Flogi frame uses | ||
227 | * the vnic MAC address as the Eth Src address | ||
228 | */ | ||
229 | fc_fcoe_set_mac(fnic->data_src_addr, fh->fh_d_id); | ||
230 | |||
231 | /* We get our s_id from the d_id of the flogi resp frame */ | ||
232 | fnic->s_id = ntoh24(fh->fh_d_id); | ||
233 | |||
234 | /* Change state to reflect transition from Eth to FC mode */ | ||
235 | fnic->state = FNIC_IN_ETH_TRANS_FC_MODE; | ||
236 | |||
237 | } else { | ||
238 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, | ||
239 | "Unexpected fnic state %s while" | ||
240 | " processing flogi resp\n", | ||
241 | fnic_state_to_str(fnic->state)); | ||
242 | ret = -1; | ||
243 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
244 | dev_kfree_skb_irq(fp_skb(fp)); | ||
245 | goto handle_flogi_resp_end; | ||
246 | } | ||
247 | |||
248 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
249 | |||
250 | /* Drop older cached frame */ | ||
251 | if (old_flogi_resp) | ||
252 | dev_kfree_skb_irq(fp_skb(old_flogi_resp)); | ||
253 | |||
254 | /* | ||
255 | * send flogi reg request to firmware, this will put the fnic in | ||
256 | * in FC mode | ||
257 | */ | ||
258 | ret = fnic_flogi_reg_handler(fnic); | ||
259 | |||
260 | if (ret < 0) { | ||
261 | int free_fp = 1; | ||
262 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
263 | /* | ||
264 | * free the frame is some other thread is not | ||
265 | * pointing to it | ||
266 | */ | ||
267 | if (fnic->flogi_resp != fp) | ||
268 | free_fp = 0; | ||
269 | else | ||
270 | fnic->flogi_resp = NULL; | ||
271 | |||
272 | if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) | ||
273 | fnic->state = FNIC_IN_ETH_MODE; | ||
274 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
275 | if (free_fp) | ||
276 | dev_kfree_skb_irq(fp_skb(fp)); | ||
277 | } | ||
278 | |||
279 | handle_flogi_resp_end: | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | /* Returns 1 for a response that matches cached flogi oxid */ | ||
284 | static inline int is_matching_flogi_resp_frame(struct fnic *fnic, | ||
285 | struct fc_frame *fp) | ||
286 | { | ||
287 | struct fc_frame_header *fh; | ||
288 | int ret = 0; | ||
289 | u32 f_ctl; | ||
290 | |||
291 | fh = fc_frame_header_get(fp); | ||
292 | f_ctl = ntoh24(fh->fh_f_ctl); | ||
293 | |||
294 | if (fnic->flogi_oxid == ntohs(fh->fh_ox_id) && | ||
295 | fh->fh_r_ctl == FC_RCTL_ELS_REP && | ||
296 | (f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) == FC_FC_EX_CTX && | ||
297 | fh->fh_type == FC_TYPE_ELS) | ||
298 | ret = 1; | ||
299 | |||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc | ||
304 | *cq_desc, struct vnic_rq_buf *buf, | ||
305 | int skipped __attribute__((unused)), | ||
306 | void *opaque) | ||
307 | { | ||
308 | struct fnic *fnic = vnic_dev_priv(rq->vdev); | ||
309 | struct sk_buff *skb; | ||
310 | struct fc_frame *fp; | ||
311 | unsigned int eth_hdrs_stripped; | ||
312 | u8 type, color, eop, sop, ingress_port, vlan_stripped; | ||
313 | u8 fcoe = 0, fcoe_sof, fcoe_eof; | ||
314 | u8 fcoe_fc_crc_ok = 1, fcoe_enc_error = 0; | ||
315 | u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok; | ||
316 | u8 ipv6, ipv4, ipv4_fragment, rss_type, csum_not_calc; | ||
317 | u8 fcs_ok = 1, packet_error = 0; | ||
318 | u16 q_number, completed_index, bytes_written = 0, vlan, checksum; | ||
319 | u32 rss_hash; | ||
320 | u16 exchange_id, tmpl; | ||
321 | u8 sof = 0; | ||
322 | u8 eof = 0; | ||
323 | u32 fcp_bytes_written = 0; | ||
324 | unsigned long flags; | ||
325 | |||
326 | pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len, | ||
327 | PCI_DMA_FROMDEVICE); | ||
328 | skb = buf->os_buf; | ||
329 | buf->os_buf = NULL; | ||
330 | |||
331 | cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index); | ||
332 | if (type == CQ_DESC_TYPE_RQ_FCP) { | ||
333 | cq_fcp_rq_desc_dec((struct cq_fcp_rq_desc *)cq_desc, | ||
334 | &type, &color, &q_number, &completed_index, | ||
335 | &eop, &sop, &fcoe_fc_crc_ok, &exchange_id, | ||
336 | &tmpl, &fcp_bytes_written, &sof, &eof, | ||
337 | &ingress_port, &packet_error, | ||
338 | &fcoe_enc_error, &fcs_ok, &vlan_stripped, | ||
339 | &vlan); | ||
340 | eth_hdrs_stripped = 1; | ||
341 | |||
342 | } else if (type == CQ_DESC_TYPE_RQ_ENET) { | ||
343 | cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc, | ||
344 | &type, &color, &q_number, &completed_index, | ||
345 | &ingress_port, &fcoe, &eop, &sop, | ||
346 | &rss_type, &csum_not_calc, &rss_hash, | ||
347 | &bytes_written, &packet_error, | ||
348 | &vlan_stripped, &vlan, &checksum, | ||
349 | &fcoe_sof, &fcoe_fc_crc_ok, | ||
350 | &fcoe_enc_error, &fcoe_eof, | ||
351 | &tcp_udp_csum_ok, &udp, &tcp, | ||
352 | &ipv4_csum_ok, &ipv6, &ipv4, | ||
353 | &ipv4_fragment, &fcs_ok); | ||
354 | eth_hdrs_stripped = 0; | ||
355 | |||
356 | } else { | ||
357 | /* wrong CQ type*/ | ||
358 | shost_printk(KERN_ERR, fnic->lport->host, | ||
359 | "fnic rq_cmpl wrong cq type x%x\n", type); | ||
360 | goto drop; | ||
361 | } | ||
362 | |||
363 | if (!fcs_ok || packet_error || !fcoe_fc_crc_ok || fcoe_enc_error) { | ||
364 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, | ||
365 | "fnic rq_cmpl fcoe x%x fcsok x%x" | ||
366 | " pkterr x%x fcoe_fc_crc_ok x%x, fcoe_enc_err" | ||
367 | " x%x\n", | ||
368 | fcoe, fcs_ok, packet_error, | ||
369 | fcoe_fc_crc_ok, fcoe_enc_error); | ||
370 | goto drop; | ||
371 | } | ||
372 | |||
373 | if (eth_hdrs_stripped) | ||
374 | fnic_import_rq_fc_frame(skb, fcp_bytes_written, sof, eof); | ||
375 | else if (fnic_import_rq_eth_pkt(skb, bytes_written)) | ||
376 | goto drop; | ||
377 | |||
378 | fp = (struct fc_frame *)skb; | ||
379 | |||
380 | /* | ||
381 | * If frame is an ELS response that matches the cached FLOGI OX_ID, | ||
382 | * and is accept, issue flogi_reg_request copy wq request to firmware | ||
383 | * to register the S_ID and determine whether FC_OUI mode or GW mode. | ||
384 | */ | ||
385 | if (is_matching_flogi_resp_frame(fnic, fp)) { | ||
386 | if (!eth_hdrs_stripped) { | ||
387 | if (fc_frame_payload_op(fp) == ELS_LS_ACC) { | ||
388 | fnic_handle_flogi_resp(fnic, fp); | ||
389 | return; | ||
390 | } | ||
391 | /* | ||
392 | * Recd. Flogi reject. No point registering | ||
393 | * with fw, but forward to libFC | ||
394 | */ | ||
395 | goto forward; | ||
396 | } | ||
397 | goto drop; | ||
398 | } | ||
399 | if (!eth_hdrs_stripped) | ||
400 | goto drop; | ||
401 | |||
402 | forward: | ||
403 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
404 | if (fnic->stop_rx_link_events) { | ||
405 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
406 | goto drop; | ||
407 | } | ||
408 | /* Use fr_flags to indicate whether succ. flogi resp or not */ | ||
409 | fr_flags(fp) = 0; | ||
410 | fr_dev(fp) = fnic->lport; | ||
411 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
412 | |||
413 | skb_queue_tail(&fnic->frame_queue, skb); | ||
414 | queue_work(fnic_event_queue, &fnic->frame_work); | ||
415 | |||
416 | return; | ||
417 | drop: | ||
418 | dev_kfree_skb_irq(skb); | ||
419 | } | ||
420 | |||
421 | static int fnic_rq_cmpl_handler_cont(struct vnic_dev *vdev, | ||
422 | struct cq_desc *cq_desc, u8 type, | ||
423 | u16 q_number, u16 completed_index, | ||
424 | void *opaque) | ||
425 | { | ||
426 | struct fnic *fnic = vnic_dev_priv(vdev); | ||
427 | |||
428 | vnic_rq_service(&fnic->rq[q_number], cq_desc, completed_index, | ||
429 | VNIC_RQ_RETURN_DESC, fnic_rq_cmpl_frame_recv, | ||
430 | NULL); | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | int fnic_rq_cmpl_handler(struct fnic *fnic, int rq_work_to_do) | ||
435 | { | ||
436 | unsigned int tot_rq_work_done = 0, cur_work_done; | ||
437 | unsigned int i; | ||
438 | int err; | ||
439 | |||
440 | for (i = 0; i < fnic->rq_count; i++) { | ||
441 | cur_work_done = vnic_cq_service(&fnic->cq[i], rq_work_to_do, | ||
442 | fnic_rq_cmpl_handler_cont, | ||
443 | NULL); | ||
444 | if (cur_work_done) { | ||
445 | err = vnic_rq_fill(&fnic->rq[i], fnic_alloc_rq_frame); | ||
446 | if (err) | ||
447 | shost_printk(KERN_ERR, fnic->lport->host, | ||
448 | "fnic_alloc_rq_frame cant alloc" | ||
449 | " frame\n"); | ||
450 | } | ||
451 | tot_rq_work_done += cur_work_done; | ||
452 | } | ||
453 | |||
454 | return tot_rq_work_done; | ||
455 | } | ||
456 | |||
457 | /* | ||
458 | * This function is called once at init time to allocate and fill RQ | ||
459 | * buffers. Subsequently, it is called in the interrupt context after RQ | ||
460 | * buffer processing to replenish the buffers in the RQ | ||
461 | */ | ||
462 | int fnic_alloc_rq_frame(struct vnic_rq *rq) | ||
463 | { | ||
464 | struct fnic *fnic = vnic_dev_priv(rq->vdev); | ||
465 | struct sk_buff *skb; | ||
466 | u16 len; | ||
467 | dma_addr_t pa; | ||
468 | |||
469 | len = FC_FRAME_HEADROOM + FC_MAX_FRAME + FC_FRAME_TAILROOM; | ||
470 | skb = dev_alloc_skb(len); | ||
471 | if (!skb) { | ||
472 | FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, | ||
473 | "Unable to allocate RQ sk_buff\n"); | ||
474 | return -ENOMEM; | ||
475 | } | ||
476 | skb_reset_mac_header(skb); | ||
477 | skb_reset_transport_header(skb); | ||
478 | skb_reset_network_header(skb); | ||
479 | skb_put(skb, len); | ||
480 | pa = pci_map_single(fnic->pdev, skb->data, len, PCI_DMA_FROMDEVICE); | ||
481 | fnic_queue_rq_desc(rq, skb, pa, len); | ||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf) | ||
486 | { | ||
487 | struct fc_frame *fp = buf->os_buf; | ||
488 | struct fnic *fnic = vnic_dev_priv(rq->vdev); | ||
489 | |||
490 | pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len, | ||
491 | PCI_DMA_FROMDEVICE); | ||
492 | |||
493 | dev_kfree_skb(fp_skb(fp)); | ||
494 | buf->os_buf = NULL; | ||
495 | } | ||
496 | |||
497 | static inline int is_flogi_frame(struct fc_frame_header *fh) | ||
498 | { | ||
499 | return fh->fh_r_ctl == FC_RCTL_ELS_REQ && *(u8 *)(fh + 1) == ELS_FLOGI; | ||
500 | } | ||
501 | |||
502 | int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp) | ||
503 | { | ||
504 | struct vnic_wq *wq = &fnic->wq[0]; | ||
505 | struct sk_buff *skb; | ||
506 | dma_addr_t pa; | ||
507 | struct ethhdr *eth_hdr; | ||
508 | struct vlan_ethhdr *vlan_hdr; | ||
509 | struct fcoe_hdr *fcoe_hdr; | ||
510 | struct fc_frame_header *fh; | ||
511 | u32 tot_len, eth_hdr_len; | ||
512 | int ret = 0; | ||
513 | unsigned long flags; | ||
514 | |||
515 | fh = fc_frame_header_get(fp); | ||
516 | skb = fp_skb(fp); | ||
517 | |||
518 | if (!fnic->vlan_hw_insert) { | ||
519 | eth_hdr_len = sizeof(*vlan_hdr) + sizeof(*fcoe_hdr); | ||
520 | vlan_hdr = (struct vlan_ethhdr *)skb_push(skb, eth_hdr_len); | ||
521 | eth_hdr = (struct ethhdr *)vlan_hdr; | ||
522 | vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q); | ||
523 | vlan_hdr->h_vlan_encapsulated_proto = htons(ETH_P_FCOE); | ||
524 | vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id); | ||
525 | fcoe_hdr = (struct fcoe_hdr *)(vlan_hdr + 1); | ||
526 | } else { | ||
527 | eth_hdr_len = sizeof(*eth_hdr) + sizeof(*fcoe_hdr); | ||
528 | eth_hdr = (struct ethhdr *)skb_push(skb, eth_hdr_len); | ||
529 | eth_hdr->h_proto = htons(ETH_P_FCOE); | ||
530 | fcoe_hdr = (struct fcoe_hdr *)(eth_hdr + 1); | ||
531 | } | ||
532 | |||
533 | if (is_flogi_frame(fh)) { | ||
534 | fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id); | ||
535 | memcpy(eth_hdr->h_source, fnic->mac_addr, ETH_ALEN); | ||
536 | } else { | ||
537 | if (fnic->fcoui_mode) | ||
538 | fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id); | ||
539 | else | ||
540 | memcpy(eth_hdr->h_dest, fnic->dest_addr, ETH_ALEN); | ||
541 | memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN); | ||
542 | } | ||
543 | |||
544 | tot_len = skb->len; | ||
545 | BUG_ON(tot_len % 4); | ||
546 | |||
547 | memset(fcoe_hdr, 0, sizeof(*fcoe_hdr)); | ||
548 | fcoe_hdr->fcoe_sof = fr_sof(fp); | ||
549 | if (FC_FCOE_VER) | ||
550 | FC_FCOE_ENCAPS_VER(fcoe_hdr, FC_FCOE_VER); | ||
551 | |||
552 | pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE); | ||
553 | |||
554 | spin_lock_irqsave(&fnic->wq_lock[0], flags); | ||
555 | |||
556 | if (!vnic_wq_desc_avail(wq)) { | ||
557 | pci_unmap_single(fnic->pdev, pa, | ||
558 | tot_len, PCI_DMA_TODEVICE); | ||
559 | ret = -1; | ||
560 | goto fnic_send_frame_end; | ||
561 | } | ||
562 | |||
563 | fnic_queue_wq_desc(wq, skb, pa, tot_len, fr_eof(fp), | ||
564 | fnic->vlan_hw_insert, fnic->vlan_id, 1, 1, 1); | ||
565 | fnic_send_frame_end: | ||
566 | spin_unlock_irqrestore(&fnic->wq_lock[0], flags); | ||
567 | |||
568 | if (ret) | ||
569 | dev_kfree_skb_any(fp_skb(fp)); | ||
570 | |||
571 | return ret; | ||
572 | } | ||
573 | |||
574 | /* | ||
575 | * fnic_send | ||
576 | * Routine to send a raw frame | ||
577 | */ | ||
578 | int fnic_send(struct fc_lport *lp, struct fc_frame *fp) | ||
579 | { | ||
580 | struct fnic *fnic = lport_priv(lp); | ||
581 | struct fc_frame_header *fh; | ||
582 | int ret = 0; | ||
583 | enum fnic_state old_state; | ||
584 | unsigned long flags; | ||
585 | struct fc_frame *old_flogi = NULL; | ||
586 | struct fc_frame *old_flogi_resp = NULL; | ||
587 | |||
588 | if (fnic->in_remove) { | ||
589 | dev_kfree_skb(fp_skb(fp)); | ||
590 | ret = -1; | ||
591 | goto fnic_send_end; | ||
592 | } | ||
593 | |||
594 | fh = fc_frame_header_get(fp); | ||
595 | /* if not an Flogi frame, send it out, this is the common case */ | ||
596 | if (!is_flogi_frame(fh)) | ||
597 | return fnic_send_frame(fnic, fp); | ||
598 | |||
599 | /* Flogi frame, now enter the state machine */ | ||
600 | |||
601 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
602 | again: | ||
603 | /* Get any old cached frames, free them after dropping lock */ | ||
604 | old_flogi = fnic->flogi; | ||
605 | fnic->flogi = NULL; | ||
606 | old_flogi_resp = fnic->flogi_resp; | ||
607 | fnic->flogi_resp = NULL; | ||
608 | |||
609 | fnic->flogi_oxid = FC_XID_UNKNOWN; | ||
610 | |||
611 | old_state = fnic->state; | ||
612 | switch (old_state) { | ||
613 | case FNIC_IN_FC_MODE: | ||
614 | case FNIC_IN_ETH_TRANS_FC_MODE: | ||
615 | default: | ||
616 | fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; | ||
617 | vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); | ||
618 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
619 | |||
620 | if (old_flogi) { | ||
621 | dev_kfree_skb(fp_skb(old_flogi)); | ||
622 | old_flogi = NULL; | ||
623 | } | ||
624 | if (old_flogi_resp) { | ||
625 | dev_kfree_skb(fp_skb(old_flogi_resp)); | ||
626 | old_flogi_resp = NULL; | ||
627 | } | ||
628 | |||
629 | ret = fnic_fw_reset_handler(fnic); | ||
630 | |||
631 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
632 | if (fnic->state != FNIC_IN_FC_TRANS_ETH_MODE) | ||
633 | goto again; | ||
634 | if (ret) { | ||
635 | fnic->state = old_state; | ||
636 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
637 | dev_kfree_skb(fp_skb(fp)); | ||
638 | goto fnic_send_end; | ||
639 | } | ||
640 | old_flogi = fnic->flogi; | ||
641 | fnic->flogi = fp; | ||
642 | fnic->flogi_oxid = ntohs(fh->fh_ox_id); | ||
643 | old_flogi_resp = fnic->flogi_resp; | ||
644 | fnic->flogi_resp = NULL; | ||
645 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
646 | break; | ||
647 | |||
648 | case FNIC_IN_FC_TRANS_ETH_MODE: | ||
649 | /* | ||
650 | * A reset is pending with the firmware. Store the flogi | ||
651 | * and its oxid. The transition out of this state happens | ||
652 | * only when Firmware completes the reset, either with | ||
653 | * success or failed. If success, transition to | ||
654 | * FNIC_IN_ETH_MODE, if fail, then transition to | ||
655 | * FNIC_IN_FC_MODE | ||
656 | */ | ||
657 | fnic->flogi = fp; | ||
658 | fnic->flogi_oxid = ntohs(fh->fh_ox_id); | ||
659 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
660 | break; | ||
661 | |||
662 | case FNIC_IN_ETH_MODE: | ||
663 | /* | ||
664 | * The fw/hw is already in eth mode. Store the oxid, | ||
665 | * and send the flogi frame out. The transition out of this | ||
666 | * state happens only we receive flogi response from the | ||
667 | * network, and the oxid matches the cached oxid when the | ||
668 | * flogi frame was sent out. If they match, then we issue | ||
669 | * a flogi_reg request and transition to state | ||
670 | * FNIC_IN_ETH_TRANS_FC_MODE | ||
671 | */ | ||
672 | fnic->flogi_oxid = ntohs(fh->fh_ox_id); | ||
673 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
674 | ret = fnic_send_frame(fnic, fp); | ||
675 | break; | ||
676 | } | ||
677 | |||
678 | fnic_send_end: | ||
679 | if (old_flogi) | ||
680 | dev_kfree_skb(fp_skb(old_flogi)); | ||
681 | if (old_flogi_resp) | ||
682 | dev_kfree_skb(fp_skb(old_flogi_resp)); | ||
683 | return ret; | ||
684 | } | ||
685 | |||
686 | static void fnic_wq_complete_frame_send(struct vnic_wq *wq, | ||
687 | struct cq_desc *cq_desc, | ||
688 | struct vnic_wq_buf *buf, void *opaque) | ||
689 | { | ||
690 | struct sk_buff *skb = buf->os_buf; | ||
691 | struct fc_frame *fp = (struct fc_frame *)skb; | ||
692 | struct fnic *fnic = vnic_dev_priv(wq->vdev); | ||
693 | |||
694 | pci_unmap_single(fnic->pdev, buf->dma_addr, | ||
695 | buf->len, PCI_DMA_TODEVICE); | ||
696 | dev_kfree_skb_irq(fp_skb(fp)); | ||
697 | buf->os_buf = NULL; | ||
698 | } | ||
699 | |||
700 | static int fnic_wq_cmpl_handler_cont(struct vnic_dev *vdev, | ||
701 | struct cq_desc *cq_desc, u8 type, | ||
702 | u16 q_number, u16 completed_index, | ||
703 | void *opaque) | ||
704 | { | ||
705 | struct fnic *fnic = vnic_dev_priv(vdev); | ||
706 | unsigned long flags; | ||
707 | |||
708 | spin_lock_irqsave(&fnic->wq_lock[q_number], flags); | ||
709 | vnic_wq_service(&fnic->wq[q_number], cq_desc, completed_index, | ||
710 | fnic_wq_complete_frame_send, NULL); | ||
711 | spin_unlock_irqrestore(&fnic->wq_lock[q_number], flags); | ||
712 | |||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | int fnic_wq_cmpl_handler(struct fnic *fnic, int work_to_do) | ||
717 | { | ||
718 | unsigned int wq_work_done = 0; | ||
719 | unsigned int i; | ||
720 | |||
721 | for (i = 0; i < fnic->raw_wq_count; i++) { | ||
722 | wq_work_done += vnic_cq_service(&fnic->cq[fnic->rq_count+i], | ||
723 | work_to_do, | ||
724 | fnic_wq_cmpl_handler_cont, | ||
725 | NULL); | ||
726 | } | ||
727 | |||
728 | return wq_work_done; | ||
729 | } | ||
730 | |||
731 | |||
732 | void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) | ||
733 | { | ||
734 | struct fc_frame *fp = buf->os_buf; | ||
735 | struct fnic *fnic = vnic_dev_priv(wq->vdev); | ||
736 | |||
737 | pci_unmap_single(fnic->pdev, buf->dma_addr, | ||
738 | buf->len, PCI_DMA_TODEVICE); | ||
739 | |||
740 | dev_kfree_skb(fp_skb(fp)); | ||
741 | buf->os_buf = NULL; | ||
742 | } | ||
diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h new file mode 100644 index 000000000000..f0b896988cd5 --- /dev/null +++ b/drivers/scsi/fnic/fnic_io.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _FNIC_IO_H_ | ||
19 | #define _FNIC_IO_H_ | ||
20 | |||
21 | #include <scsi/fc/fc_fcp.h> | ||
22 | |||
23 | #define FNIC_DFLT_SG_DESC_CNT 32 | ||
24 | #define FNIC_MAX_SG_DESC_CNT 1024 /* Maximum descriptors per sgl */ | ||
25 | #define FNIC_SG_DESC_ALIGN 16 /* Descriptor address alignment */ | ||
26 | |||
27 | struct host_sg_desc { | ||
28 | __le64 addr; | ||
29 | __le32 len; | ||
30 | u32 _resvd; | ||
31 | }; | ||
32 | |||
33 | struct fnic_dflt_sgl_list { | ||
34 | struct host_sg_desc sg_desc[FNIC_DFLT_SG_DESC_CNT]; | ||
35 | }; | ||
36 | |||
37 | struct fnic_sgl_list { | ||
38 | struct host_sg_desc sg_desc[FNIC_MAX_SG_DESC_CNT]; | ||
39 | }; | ||
40 | |||
41 | enum fnic_sgl_list_type { | ||
42 | FNIC_SGL_CACHE_DFLT = 0, /* cache with default size sgl */ | ||
43 | FNIC_SGL_CACHE_MAX, /* cache with max size sgl */ | ||
44 | FNIC_SGL_NUM_CACHES /* number of sgl caches */ | ||
45 | }; | ||
46 | |||
47 | enum fnic_ioreq_state { | ||
48 | FNIC_IOREQ_CMD_PENDING = 0, | ||
49 | FNIC_IOREQ_ABTS_PENDING, | ||
50 | FNIC_IOREQ_ABTS_COMPLETE, | ||
51 | FNIC_IOREQ_CMD_COMPLETE, | ||
52 | }; | ||
53 | |||
54 | struct fnic_io_req { | ||
55 | struct host_sg_desc *sgl_list; /* sgl list */ | ||
56 | void *sgl_list_alloc; /* sgl list address used for free */ | ||
57 | dma_addr_t sense_buf_pa; /* dma address for sense buffer*/ | ||
58 | dma_addr_t sgl_list_pa; /* dma address for sgl list */ | ||
59 | u16 sgl_cnt; | ||
60 | u8 sgl_type; /* device DMA descriptor list type */ | ||
61 | u8 io_completed:1; /* set to 1 when fw completes IO */ | ||
62 | u32 port_id; /* remote port DID */ | ||
63 | struct completion *abts_done; /* completion for abts */ | ||
64 | struct completion *dr_done; /* completion for device reset */ | ||
65 | }; | ||
66 | |||
67 | #endif /* _FNIC_IO_H_ */ | ||
diff --git a/drivers/scsi/fnic/fnic_isr.c b/drivers/scsi/fnic/fnic_isr.c new file mode 100644 index 000000000000..2b3064828aea --- /dev/null +++ b/drivers/scsi/fnic/fnic_isr.c | |||
@@ -0,0 +1,332 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <scsi/libfc.h> | ||
23 | #include <scsi/fc_frame.h> | ||
24 | #include "vnic_dev.h" | ||
25 | #include "vnic_intr.h" | ||
26 | #include "vnic_stats.h" | ||
27 | #include "fnic_io.h" | ||
28 | #include "fnic.h" | ||
29 | |||
30 | static irqreturn_t fnic_isr_legacy(int irq, void *data) | ||
31 | { | ||
32 | struct fnic *fnic = data; | ||
33 | u32 pba; | ||
34 | unsigned long work_done = 0; | ||
35 | |||
36 | pba = vnic_intr_legacy_pba(fnic->legacy_pba); | ||
37 | if (!pba) | ||
38 | return IRQ_NONE; | ||
39 | |||
40 | if (pba & (1 << FNIC_INTX_NOTIFY)) { | ||
41 | vnic_intr_return_all_credits(&fnic->intr[FNIC_INTX_NOTIFY]); | ||
42 | fnic_handle_link_event(fnic); | ||
43 | } | ||
44 | |||
45 | if (pba & (1 << FNIC_INTX_ERR)) { | ||
46 | vnic_intr_return_all_credits(&fnic->intr[FNIC_INTX_ERR]); | ||
47 | fnic_log_q_error(fnic); | ||
48 | } | ||
49 | |||
50 | if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ)) { | ||
51 | work_done += fnic_wq_copy_cmpl_handler(fnic, 8); | ||
52 | work_done += fnic_wq_cmpl_handler(fnic, 4); | ||
53 | work_done += fnic_rq_cmpl_handler(fnic, 4); | ||
54 | |||
55 | vnic_intr_return_credits(&fnic->intr[FNIC_INTX_WQ_RQ_COPYWQ], | ||
56 | work_done, | ||
57 | 1 /* unmask intr */, | ||
58 | 1 /* reset intr timer */); | ||
59 | } | ||
60 | |||
61 | return IRQ_HANDLED; | ||
62 | } | ||
63 | |||
64 | static irqreturn_t fnic_isr_msi(int irq, void *data) | ||
65 | { | ||
66 | struct fnic *fnic = data; | ||
67 | unsigned long work_done = 0; | ||
68 | |||
69 | work_done += fnic_wq_copy_cmpl_handler(fnic, 8); | ||
70 | work_done += fnic_wq_cmpl_handler(fnic, 4); | ||
71 | work_done += fnic_rq_cmpl_handler(fnic, 4); | ||
72 | |||
73 | vnic_intr_return_credits(&fnic->intr[0], | ||
74 | work_done, | ||
75 | 1 /* unmask intr */, | ||
76 | 1 /* reset intr timer */); | ||
77 | |||
78 | return IRQ_HANDLED; | ||
79 | } | ||
80 | |||
81 | static irqreturn_t fnic_isr_msix_rq(int irq, void *data) | ||
82 | { | ||
83 | struct fnic *fnic = data; | ||
84 | unsigned long rq_work_done = 0; | ||
85 | |||
86 | rq_work_done = fnic_rq_cmpl_handler(fnic, 4); | ||
87 | vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ], | ||
88 | rq_work_done, | ||
89 | 1 /* unmask intr */, | ||
90 | 1 /* reset intr timer */); | ||
91 | |||
92 | return IRQ_HANDLED; | ||
93 | } | ||
94 | |||
95 | static irqreturn_t fnic_isr_msix_wq(int irq, void *data) | ||
96 | { | ||
97 | struct fnic *fnic = data; | ||
98 | unsigned long wq_work_done = 0; | ||
99 | |||
100 | wq_work_done = fnic_wq_cmpl_handler(fnic, 4); | ||
101 | vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ], | ||
102 | wq_work_done, | ||
103 | 1 /* unmask intr */, | ||
104 | 1 /* reset intr timer */); | ||
105 | return IRQ_HANDLED; | ||
106 | } | ||
107 | |||
108 | static irqreturn_t fnic_isr_msix_wq_copy(int irq, void *data) | ||
109 | { | ||
110 | struct fnic *fnic = data; | ||
111 | unsigned long wq_copy_work_done = 0; | ||
112 | |||
113 | wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, 8); | ||
114 | vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY], | ||
115 | wq_copy_work_done, | ||
116 | 1 /* unmask intr */, | ||
117 | 1 /* reset intr timer */); | ||
118 | return IRQ_HANDLED; | ||
119 | } | ||
120 | |||
121 | static irqreturn_t fnic_isr_msix_err_notify(int irq, void *data) | ||
122 | { | ||
123 | struct fnic *fnic = data; | ||
124 | |||
125 | vnic_intr_return_all_credits(&fnic->intr[FNIC_MSIX_ERR_NOTIFY]); | ||
126 | fnic_log_q_error(fnic); | ||
127 | fnic_handle_link_event(fnic); | ||
128 | |||
129 | return IRQ_HANDLED; | ||
130 | } | ||
131 | |||
132 | void fnic_free_intr(struct fnic *fnic) | ||
133 | { | ||
134 | int i; | ||
135 | |||
136 | switch (vnic_dev_get_intr_mode(fnic->vdev)) { | ||
137 | case VNIC_DEV_INTR_MODE_INTX: | ||
138 | case VNIC_DEV_INTR_MODE_MSI: | ||
139 | free_irq(fnic->pdev->irq, fnic); | ||
140 | break; | ||
141 | |||
142 | case VNIC_DEV_INTR_MODE_MSIX: | ||
143 | for (i = 0; i < ARRAY_SIZE(fnic->msix); i++) | ||
144 | if (fnic->msix[i].requested) | ||
145 | free_irq(fnic->msix_entry[i].vector, | ||
146 | fnic->msix[i].devid); | ||
147 | break; | ||
148 | |||
149 | default: | ||
150 | break; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | int fnic_request_intr(struct fnic *fnic) | ||
155 | { | ||
156 | int err = 0; | ||
157 | int i; | ||
158 | |||
159 | switch (vnic_dev_get_intr_mode(fnic->vdev)) { | ||
160 | |||
161 | case VNIC_DEV_INTR_MODE_INTX: | ||
162 | err = request_irq(fnic->pdev->irq, &fnic_isr_legacy, | ||
163 | IRQF_SHARED, DRV_NAME, fnic); | ||
164 | break; | ||
165 | |||
166 | case VNIC_DEV_INTR_MODE_MSI: | ||
167 | err = request_irq(fnic->pdev->irq, &fnic_isr_msi, | ||
168 | 0, fnic->name, fnic); | ||
169 | break; | ||
170 | |||
171 | case VNIC_DEV_INTR_MODE_MSIX: | ||
172 | |||
173 | sprintf(fnic->msix[FNIC_MSIX_RQ].devname, | ||
174 | "%.11s-fcs-rq", fnic->name); | ||
175 | fnic->msix[FNIC_MSIX_RQ].isr = fnic_isr_msix_rq; | ||
176 | fnic->msix[FNIC_MSIX_RQ].devid = fnic; | ||
177 | |||
178 | sprintf(fnic->msix[FNIC_MSIX_WQ].devname, | ||
179 | "%.11s-fcs-wq", fnic->name); | ||
180 | fnic->msix[FNIC_MSIX_WQ].isr = fnic_isr_msix_wq; | ||
181 | fnic->msix[FNIC_MSIX_WQ].devid = fnic; | ||
182 | |||
183 | sprintf(fnic->msix[FNIC_MSIX_WQ_COPY].devname, | ||
184 | "%.11s-scsi-wq", fnic->name); | ||
185 | fnic->msix[FNIC_MSIX_WQ_COPY].isr = fnic_isr_msix_wq_copy; | ||
186 | fnic->msix[FNIC_MSIX_WQ_COPY].devid = fnic; | ||
187 | |||
188 | sprintf(fnic->msix[FNIC_MSIX_ERR_NOTIFY].devname, | ||
189 | "%.11s-err-notify", fnic->name); | ||
190 | fnic->msix[FNIC_MSIX_ERR_NOTIFY].isr = | ||
191 | fnic_isr_msix_err_notify; | ||
192 | fnic->msix[FNIC_MSIX_ERR_NOTIFY].devid = fnic; | ||
193 | |||
194 | for (i = 0; i < ARRAY_SIZE(fnic->msix); i++) { | ||
195 | err = request_irq(fnic->msix_entry[i].vector, | ||
196 | fnic->msix[i].isr, 0, | ||
197 | fnic->msix[i].devname, | ||
198 | fnic->msix[i].devid); | ||
199 | if (err) { | ||
200 | shost_printk(KERN_ERR, fnic->lport->host, | ||
201 | "MSIX: request_irq" | ||
202 | " failed %d\n", err); | ||
203 | fnic_free_intr(fnic); | ||
204 | break; | ||
205 | } | ||
206 | fnic->msix[i].requested = 1; | ||
207 | } | ||
208 | break; | ||
209 | |||
210 | default: | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | return err; | ||
215 | } | ||
216 | |||
217 | int fnic_set_intr_mode(struct fnic *fnic) | ||
218 | { | ||
219 | unsigned int n = ARRAY_SIZE(fnic->rq); | ||
220 | unsigned int m = ARRAY_SIZE(fnic->wq); | ||
221 | unsigned int o = ARRAY_SIZE(fnic->wq_copy); | ||
222 | unsigned int i; | ||
223 | |||
224 | /* | ||
225 | * Set interrupt mode (INTx, MSI, MSI-X) depending | ||
226 | * system capabilities. | ||
227 | * | ||
228 | * Try MSI-X first | ||
229 | * | ||
230 | * We need n RQs, m WQs, o Copy WQs, n+m+o CQs, and n+m+o+1 INTRs | ||
231 | * (last INTR is used for WQ/RQ errors and notification area) | ||
232 | */ | ||
233 | |||
234 | BUG_ON(ARRAY_SIZE(fnic->msix_entry) < n + m + o + 1); | ||
235 | for (i = 0; i < n + m + o + 1; i++) | ||
236 | fnic->msix_entry[i].entry = i; | ||
237 | |||
238 | if (fnic->rq_count >= n && | ||
239 | fnic->raw_wq_count >= m && | ||
240 | fnic->wq_copy_count >= o && | ||
241 | fnic->cq_count >= n + m + o) { | ||
242 | if (!pci_enable_msix(fnic->pdev, fnic->msix_entry, | ||
243 | n + m + o + 1)) { | ||
244 | fnic->rq_count = n; | ||
245 | fnic->raw_wq_count = m; | ||
246 | fnic->wq_copy_count = o; | ||
247 | fnic->wq_count = m + o; | ||
248 | fnic->cq_count = n + m + o; | ||
249 | fnic->intr_count = n + m + o + 1; | ||
250 | fnic->err_intr_offset = FNIC_MSIX_ERR_NOTIFY; | ||
251 | |||
252 | FNIC_ISR_DBG(KERN_DEBUG, fnic->lport->host, | ||
253 | "Using MSI-X Interrupts\n"); | ||
254 | vnic_dev_set_intr_mode(fnic->vdev, | ||
255 | VNIC_DEV_INTR_MODE_MSIX); | ||
256 | return 0; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * Next try MSI | ||
262 | * We need 1 RQ, 1 WQ, 1 WQ_COPY, 3 CQs, and 1 INTR | ||
263 | */ | ||
264 | if (fnic->rq_count >= 1 && | ||
265 | fnic->raw_wq_count >= 1 && | ||
266 | fnic->wq_copy_count >= 1 && | ||
267 | fnic->cq_count >= 3 && | ||
268 | fnic->intr_count >= 1 && | ||
269 | !pci_enable_msi(fnic->pdev)) { | ||
270 | |||
271 | fnic->rq_count = 1; | ||
272 | fnic->raw_wq_count = 1; | ||
273 | fnic->wq_copy_count = 1; | ||
274 | fnic->wq_count = 2; | ||
275 | fnic->cq_count = 3; | ||
276 | fnic->intr_count = 1; | ||
277 | fnic->err_intr_offset = 0; | ||
278 | |||
279 | FNIC_ISR_DBG(KERN_DEBUG, fnic->lport->host, | ||
280 | "Using MSI Interrupts\n"); | ||
281 | vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_MSI); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | * Next try INTx | ||
288 | * We need 1 RQ, 1 WQ, 1 WQ_COPY, 3 CQs, and 3 INTRs | ||
289 | * 1 INTR is used for all 3 queues, 1 INTR for queue errors | ||
290 | * 1 INTR for notification area | ||
291 | */ | ||
292 | |||
293 | if (fnic->rq_count >= 1 && | ||
294 | fnic->raw_wq_count >= 1 && | ||
295 | fnic->wq_copy_count >= 1 && | ||
296 | fnic->cq_count >= 3 && | ||
297 | fnic->intr_count >= 3) { | ||
298 | |||
299 | fnic->rq_count = 1; | ||
300 | fnic->raw_wq_count = 1; | ||
301 | fnic->wq_copy_count = 1; | ||
302 | fnic->cq_count = 3; | ||
303 | fnic->intr_count = 3; | ||
304 | |||
305 | FNIC_ISR_DBG(KERN_DEBUG, fnic->lport->host, | ||
306 | "Using Legacy Interrupts\n"); | ||
307 | vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_INTX); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_UNKNOWN); | ||
313 | |||
314 | return -EINVAL; | ||
315 | } | ||
316 | |||
317 | void fnic_clear_intr_mode(struct fnic *fnic) | ||
318 | { | ||
319 | switch (vnic_dev_get_intr_mode(fnic->vdev)) { | ||
320 | case VNIC_DEV_INTR_MODE_MSIX: | ||
321 | pci_disable_msix(fnic->pdev); | ||
322 | break; | ||
323 | case VNIC_DEV_INTR_MODE_MSI: | ||
324 | pci_disable_msi(fnic->pdev); | ||
325 | break; | ||
326 | default: | ||
327 | break; | ||
328 | } | ||
329 | |||
330 | vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_INTX); | ||
331 | } | ||
332 | |||
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c new file mode 100644 index 000000000000..32ef6b87d895 --- /dev/null +++ b/drivers/scsi/fnic/fnic_main.c | |||
@@ -0,0 +1,942 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/mempool.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/skbuff.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | #include <scsi/scsi_host.h> | ||
29 | #include <scsi/scsi_transport.h> | ||
30 | #include <scsi/scsi_transport_fc.h> | ||
31 | #include <scsi/scsi_tcq.h> | ||
32 | #include <scsi/libfc.h> | ||
33 | #include <scsi/fc_frame.h> | ||
34 | |||
35 | #include "vnic_dev.h" | ||
36 | #include "vnic_intr.h" | ||
37 | #include "vnic_stats.h" | ||
38 | #include "fnic_io.h" | ||
39 | #include "fnic.h" | ||
40 | |||
41 | #define PCI_DEVICE_ID_CISCO_FNIC 0x0045 | ||
42 | |||
43 | /* Timer to poll notification area for events. Used for MSI interrupts */ | ||
44 | #define FNIC_NOTIFY_TIMER_PERIOD (2 * HZ) | ||
45 | |||
46 | static struct kmem_cache *fnic_sgl_cache[FNIC_SGL_NUM_CACHES]; | ||
47 | static struct kmem_cache *fnic_io_req_cache; | ||
48 | LIST_HEAD(fnic_list); | ||
49 | DEFINE_SPINLOCK(fnic_list_lock); | ||
50 | |||
51 | /* Supported devices by fnic module */ | ||
52 | static struct pci_device_id fnic_id_table[] = { | ||
53 | { PCI_DEVICE(PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_CISCO_FNIC) }, | ||
54 | { 0, } | ||
55 | }; | ||
56 | |||
57 | MODULE_DESCRIPTION(DRV_DESCRIPTION); | ||
58 | MODULE_AUTHOR("Abhijeet Joglekar <abjoglek@cisco.com>, " | ||
59 | "Joseph R. Eykholt <jeykholt@cisco.com>"); | ||
60 | MODULE_LICENSE("GPL v2"); | ||
61 | MODULE_VERSION(DRV_VERSION); | ||
62 | MODULE_DEVICE_TABLE(pci, fnic_id_table); | ||
63 | |||
64 | unsigned int fnic_log_level; | ||
65 | module_param(fnic_log_level, int, S_IRUGO|S_IWUSR); | ||
66 | MODULE_PARM_DESC(fnic_log_level, "bit mask of fnic logging levels"); | ||
67 | |||
68 | |||
69 | static struct libfc_function_template fnic_transport_template = { | ||
70 | .frame_send = fnic_send, | ||
71 | .fcp_abort_io = fnic_empty_scsi_cleanup, | ||
72 | .fcp_cleanup = fnic_empty_scsi_cleanup, | ||
73 | .exch_mgr_reset = fnic_exch_mgr_reset | ||
74 | }; | ||
75 | |||
76 | static int fnic_slave_alloc(struct scsi_device *sdev) | ||
77 | { | ||
78 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | ||
79 | struct fc_lport *lp = shost_priv(sdev->host); | ||
80 | struct fnic *fnic = lport_priv(lp); | ||
81 | |||
82 | sdev->tagged_supported = 1; | ||
83 | |||
84 | if (!rport || fc_remote_port_chkready(rport)) | ||
85 | return -ENXIO; | ||
86 | |||
87 | scsi_activate_tcq(sdev, FNIC_DFLT_QUEUE_DEPTH); | ||
88 | rport->dev_loss_tmo = fnic->config.port_down_timeout / 1000; | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static struct scsi_host_template fnic_host_template = { | ||
94 | .module = THIS_MODULE, | ||
95 | .name = DRV_NAME, | ||
96 | .queuecommand = fnic_queuecommand, | ||
97 | .eh_abort_handler = fnic_abort_cmd, | ||
98 | .eh_device_reset_handler = fnic_device_reset, | ||
99 | .eh_host_reset_handler = fnic_host_reset, | ||
100 | .slave_alloc = fnic_slave_alloc, | ||
101 | .change_queue_depth = fc_change_queue_depth, | ||
102 | .change_queue_type = fc_change_queue_type, | ||
103 | .this_id = -1, | ||
104 | .cmd_per_lun = 3, | ||
105 | .can_queue = FNIC_MAX_IO_REQ, | ||
106 | .use_clustering = ENABLE_CLUSTERING, | ||
107 | .sg_tablesize = FNIC_MAX_SG_DESC_CNT, | ||
108 | .max_sectors = 0xffff, | ||
109 | .shost_attrs = fnic_attrs, | ||
110 | }; | ||
111 | |||
112 | static void fnic_get_host_speed(struct Scsi_Host *shost); | ||
113 | static struct scsi_transport_template *fnic_fc_transport; | ||
114 | static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *); | ||
115 | |||
116 | static struct fc_function_template fnic_fc_functions = { | ||
117 | |||
118 | .show_host_node_name = 1, | ||
119 | .show_host_port_name = 1, | ||
120 | .show_host_supported_classes = 1, | ||
121 | .show_host_supported_fc4s = 1, | ||
122 | .show_host_active_fc4s = 1, | ||
123 | .show_host_maxframe_size = 1, | ||
124 | .show_host_port_id = 1, | ||
125 | .show_host_supported_speeds = 1, | ||
126 | .get_host_speed = fnic_get_host_speed, | ||
127 | .show_host_speed = 1, | ||
128 | .show_host_port_type = 1, | ||
129 | .get_host_port_state = fc_get_host_port_state, | ||
130 | .show_host_port_state = 1, | ||
131 | .show_host_symbolic_name = 1, | ||
132 | .show_rport_maxframe_size = 1, | ||
133 | .show_rport_supported_classes = 1, | ||
134 | .show_host_fabric_name = 1, | ||
135 | .show_starget_node_name = 1, | ||
136 | .show_starget_port_name = 1, | ||
137 | .show_starget_port_id = 1, | ||
138 | .show_rport_dev_loss_tmo = 1, | ||
139 | .issue_fc_host_lip = fnic_reset, | ||
140 | .get_fc_host_stats = fnic_get_stats, | ||
141 | .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), | ||
142 | .terminate_rport_io = fnic_terminate_rport_io, | ||
143 | }; | ||
144 | |||
145 | static void fnic_get_host_speed(struct Scsi_Host *shost) | ||
146 | { | ||
147 | struct fc_lport *lp = shost_priv(shost); | ||
148 | struct fnic *fnic = lport_priv(lp); | ||
149 | u32 port_speed = vnic_dev_port_speed(fnic->vdev); | ||
150 | |||
151 | /* Add in other values as they get defined in fw */ | ||
152 | switch (port_speed) { | ||
153 | case 10000: | ||
154 | fc_host_speed(shost) = FC_PORTSPEED_10GBIT; | ||
155 | break; | ||
156 | default: | ||
157 | fc_host_speed(shost) = FC_PORTSPEED_10GBIT; | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host) | ||
163 | { | ||
164 | int ret; | ||
165 | struct fc_lport *lp = shost_priv(host); | ||
166 | struct fnic *fnic = lport_priv(lp); | ||
167 | struct fc_host_statistics *stats = &lp->host_stats; | ||
168 | struct vnic_stats *vs; | ||
169 | unsigned long flags; | ||
170 | |||
171 | if (time_before(jiffies, fnic->stats_time + HZ / FNIC_STATS_RATE_LIMIT)) | ||
172 | return stats; | ||
173 | fnic->stats_time = jiffies; | ||
174 | |||
175 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
176 | ret = vnic_dev_stats_dump(fnic->vdev, &fnic->stats); | ||
177 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
178 | |||
179 | if (ret) { | ||
180 | FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host, | ||
181 | "fnic: Get vnic stats failed" | ||
182 | " 0x%x", ret); | ||
183 | return stats; | ||
184 | } | ||
185 | vs = fnic->stats; | ||
186 | stats->tx_frames = vs->tx.tx_unicast_frames_ok; | ||
187 | stats->tx_words = vs->tx.tx_unicast_bytes_ok / 4; | ||
188 | stats->rx_frames = vs->rx.rx_unicast_frames_ok; | ||
189 | stats->rx_words = vs->rx.rx_unicast_bytes_ok / 4; | ||
190 | stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors; | ||
191 | stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop; | ||
192 | stats->invalid_crc_count = vs->rx.rx_crc_errors; | ||
193 | stats->seconds_since_last_reset = (jiffies - lp->boot_time) / HZ; | ||
194 | stats->fcp_input_megabytes = div_u64(fnic->fcp_input_bytes, 1000000); | ||
195 | stats->fcp_output_megabytes = div_u64(fnic->fcp_output_bytes, 1000000); | ||
196 | |||
197 | return stats; | ||
198 | } | ||
199 | |||
200 | void fnic_log_q_error(struct fnic *fnic) | ||
201 | { | ||
202 | unsigned int i; | ||
203 | u32 error_status; | ||
204 | |||
205 | for (i = 0; i < fnic->raw_wq_count; i++) { | ||
206 | error_status = ioread32(&fnic->wq[i].ctrl->error_status); | ||
207 | if (error_status) | ||
208 | shost_printk(KERN_ERR, fnic->lport->host, | ||
209 | "WQ[%d] error_status" | ||
210 | " %d\n", i, error_status); | ||
211 | } | ||
212 | |||
213 | for (i = 0; i < fnic->rq_count; i++) { | ||
214 | error_status = ioread32(&fnic->rq[i].ctrl->error_status); | ||
215 | if (error_status) | ||
216 | shost_printk(KERN_ERR, fnic->lport->host, | ||
217 | "RQ[%d] error_status" | ||
218 | " %d\n", i, error_status); | ||
219 | } | ||
220 | |||
221 | for (i = 0; i < fnic->wq_copy_count; i++) { | ||
222 | error_status = ioread32(&fnic->wq_copy[i].ctrl->error_status); | ||
223 | if (error_status) | ||
224 | shost_printk(KERN_ERR, fnic->lport->host, | ||
225 | "CWQ[%d] error_status" | ||
226 | " %d\n", i, error_status); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | void fnic_handle_link_event(struct fnic *fnic) | ||
231 | { | ||
232 | unsigned long flags; | ||
233 | |||
234 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
235 | if (fnic->stop_rx_link_events) { | ||
236 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
237 | return; | ||
238 | } | ||
239 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
240 | |||
241 | queue_work(fnic_event_queue, &fnic->link_work); | ||
242 | |||
243 | } | ||
244 | |||
245 | static int fnic_notify_set(struct fnic *fnic) | ||
246 | { | ||
247 | int err; | ||
248 | |||
249 | switch (vnic_dev_get_intr_mode(fnic->vdev)) { | ||
250 | case VNIC_DEV_INTR_MODE_INTX: | ||
251 | err = vnic_dev_notify_set(fnic->vdev, FNIC_INTX_NOTIFY); | ||
252 | break; | ||
253 | case VNIC_DEV_INTR_MODE_MSI: | ||
254 | err = vnic_dev_notify_set(fnic->vdev, -1); | ||
255 | break; | ||
256 | case VNIC_DEV_INTR_MODE_MSIX: | ||
257 | err = vnic_dev_notify_set(fnic->vdev, FNIC_MSIX_ERR_NOTIFY); | ||
258 | break; | ||
259 | default: | ||
260 | shost_printk(KERN_ERR, fnic->lport->host, | ||
261 | "Interrupt mode should be set up" | ||
262 | " before devcmd notify set %d\n", | ||
263 | vnic_dev_get_intr_mode(fnic->vdev)); | ||
264 | err = -1; | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | return err; | ||
269 | } | ||
270 | |||
271 | static void fnic_notify_timer(unsigned long data) | ||
272 | { | ||
273 | struct fnic *fnic = (struct fnic *)data; | ||
274 | |||
275 | fnic_handle_link_event(fnic); | ||
276 | mod_timer(&fnic->notify_timer, | ||
277 | round_jiffies(jiffies + FNIC_NOTIFY_TIMER_PERIOD)); | ||
278 | } | ||
279 | |||
280 | static void fnic_notify_timer_start(struct fnic *fnic) | ||
281 | { | ||
282 | switch (vnic_dev_get_intr_mode(fnic->vdev)) { | ||
283 | case VNIC_DEV_INTR_MODE_MSI: | ||
284 | /* | ||
285 | * Schedule first timeout immediately. The driver is | ||
286 | * initiatialized and ready to look for link up notification | ||
287 | */ | ||
288 | mod_timer(&fnic->notify_timer, jiffies); | ||
289 | break; | ||
290 | default: | ||
291 | /* Using intr for notification for INTx/MSI-X */ | ||
292 | break; | ||
293 | }; | ||
294 | } | ||
295 | |||
296 | static int fnic_dev_wait(struct vnic_dev *vdev, | ||
297 | int (*start)(struct vnic_dev *, int), | ||
298 | int (*finished)(struct vnic_dev *, int *), | ||
299 | int arg) | ||
300 | { | ||
301 | unsigned long time; | ||
302 | int done; | ||
303 | int err; | ||
304 | |||
305 | err = start(vdev, arg); | ||
306 | if (err) | ||
307 | return err; | ||
308 | |||
309 | /* Wait for func to complete...2 seconds max */ | ||
310 | time = jiffies + (HZ * 2); | ||
311 | do { | ||
312 | err = finished(vdev, &done); | ||
313 | if (err) | ||
314 | return err; | ||
315 | if (done) | ||
316 | return 0; | ||
317 | schedule_timeout_uninterruptible(HZ / 10); | ||
318 | } while (time_after(time, jiffies)); | ||
319 | |||
320 | return -ETIMEDOUT; | ||
321 | } | ||
322 | |||
323 | static int fnic_cleanup(struct fnic *fnic) | ||
324 | { | ||
325 | unsigned int i; | ||
326 | int err; | ||
327 | unsigned long flags; | ||
328 | struct fc_frame *flogi = NULL; | ||
329 | struct fc_frame *flogi_resp = NULL; | ||
330 | |||
331 | vnic_dev_disable(fnic->vdev); | ||
332 | for (i = 0; i < fnic->intr_count; i++) | ||
333 | vnic_intr_mask(&fnic->intr[i]); | ||
334 | |||
335 | for (i = 0; i < fnic->rq_count; i++) { | ||
336 | err = vnic_rq_disable(&fnic->rq[i]); | ||
337 | if (err) | ||
338 | return err; | ||
339 | } | ||
340 | for (i = 0; i < fnic->raw_wq_count; i++) { | ||
341 | err = vnic_wq_disable(&fnic->wq[i]); | ||
342 | if (err) | ||
343 | return err; | ||
344 | } | ||
345 | for (i = 0; i < fnic->wq_copy_count; i++) { | ||
346 | err = vnic_wq_copy_disable(&fnic->wq_copy[i]); | ||
347 | if (err) | ||
348 | return err; | ||
349 | } | ||
350 | |||
351 | /* Clean up completed IOs and FCS frames */ | ||
352 | fnic_wq_copy_cmpl_handler(fnic, -1); | ||
353 | fnic_wq_cmpl_handler(fnic, -1); | ||
354 | fnic_rq_cmpl_handler(fnic, -1); | ||
355 | |||
356 | /* Clean up the IOs and FCS frames that have not completed */ | ||
357 | for (i = 0; i < fnic->raw_wq_count; i++) | ||
358 | vnic_wq_clean(&fnic->wq[i], fnic_free_wq_buf); | ||
359 | for (i = 0; i < fnic->rq_count; i++) | ||
360 | vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf); | ||
361 | for (i = 0; i < fnic->wq_copy_count; i++) | ||
362 | vnic_wq_copy_clean(&fnic->wq_copy[i], | ||
363 | fnic_wq_copy_cleanup_handler); | ||
364 | |||
365 | for (i = 0; i < fnic->cq_count; i++) | ||
366 | vnic_cq_clean(&fnic->cq[i]); | ||
367 | for (i = 0; i < fnic->intr_count; i++) | ||
368 | vnic_intr_clean(&fnic->intr[i]); | ||
369 | |||
370 | /* | ||
371 | * Remove cached flogi and flogi resp frames if any | ||
372 | * These frames are not in any queue, and therefore queue | ||
373 | * cleanup does not clean them. So clean them explicitly | ||
374 | */ | ||
375 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
376 | flogi = fnic->flogi; | ||
377 | fnic->flogi = NULL; | ||
378 | flogi_resp = fnic->flogi_resp; | ||
379 | fnic->flogi_resp = NULL; | ||
380 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
381 | |||
382 | if (flogi) | ||
383 | dev_kfree_skb(fp_skb(flogi)); | ||
384 | |||
385 | if (flogi_resp) | ||
386 | dev_kfree_skb(fp_skb(flogi_resp)); | ||
387 | |||
388 | mempool_destroy(fnic->io_req_pool); | ||
389 | for (i = 0; i < FNIC_SGL_NUM_CACHES; i++) | ||
390 | mempool_destroy(fnic->io_sgl_pool[i]); | ||
391 | |||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static void fnic_iounmap(struct fnic *fnic) | ||
396 | { | ||
397 | if (fnic->bar0.vaddr) | ||
398 | iounmap(fnic->bar0.vaddr); | ||
399 | } | ||
400 | |||
401 | /* | ||
402 | * Allocate element for mempools requiring GFP_DMA flag. | ||
403 | * Otherwise, checks in kmem_flagcheck() hit BUG_ON(). | ||
404 | */ | ||
405 | static void *fnic_alloc_slab_dma(gfp_t gfp_mask, void *pool_data) | ||
406 | { | ||
407 | struct kmem_cache *mem = pool_data; | ||
408 | |||
409 | return kmem_cache_alloc(mem, gfp_mask | GFP_ATOMIC | GFP_DMA); | ||
410 | } | ||
411 | |||
412 | static int __devinit fnic_probe(struct pci_dev *pdev, | ||
413 | const struct pci_device_id *ent) | ||
414 | { | ||
415 | struct Scsi_Host *host; | ||
416 | struct fc_lport *lp; | ||
417 | struct fnic *fnic; | ||
418 | mempool_t *pool; | ||
419 | int err; | ||
420 | int i; | ||
421 | unsigned long flags; | ||
422 | |||
423 | /* | ||
424 | * Allocate SCSI Host and set up association between host, | ||
425 | * local port, and fnic | ||
426 | */ | ||
427 | host = scsi_host_alloc(&fnic_host_template, | ||
428 | sizeof(struct fc_lport) + sizeof(struct fnic)); | ||
429 | if (!host) { | ||
430 | printk(KERN_ERR PFX "Unable to alloc SCSI host\n"); | ||
431 | err = -ENOMEM; | ||
432 | goto err_out; | ||
433 | } | ||
434 | lp = shost_priv(host); | ||
435 | lp->host = host; | ||
436 | fnic = lport_priv(lp); | ||
437 | fnic->lport = lp; | ||
438 | |||
439 | snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME, | ||
440 | host->host_no); | ||
441 | |||
442 | host->transportt = fnic_fc_transport; | ||
443 | |||
444 | err = scsi_init_shared_tag_map(host, FNIC_MAX_IO_REQ); | ||
445 | if (err) { | ||
446 | shost_printk(KERN_ERR, fnic->lport->host, | ||
447 | "Unable to alloc shared tag map\n"); | ||
448 | goto err_out_free_hba; | ||
449 | } | ||
450 | |||
451 | /* Setup PCI resources */ | ||
452 | pci_set_drvdata(pdev, fnic); | ||
453 | |||
454 | fnic->pdev = pdev; | ||
455 | |||
456 | err = pci_enable_device(pdev); | ||
457 | if (err) { | ||
458 | shost_printk(KERN_ERR, fnic->lport->host, | ||
459 | "Cannot enable PCI device, aborting.\n"); | ||
460 | goto err_out_free_hba; | ||
461 | } | ||
462 | |||
463 | err = pci_request_regions(pdev, DRV_NAME); | ||
464 | if (err) { | ||
465 | shost_printk(KERN_ERR, fnic->lport->host, | ||
466 | "Cannot enable PCI resources, aborting\n"); | ||
467 | goto err_out_disable_device; | ||
468 | } | ||
469 | |||
470 | pci_set_master(pdev); | ||
471 | |||
472 | /* Query PCI controller on system for DMA addressing | ||
473 | * limitation for the device. Try 40-bit first, and | ||
474 | * fail to 32-bit. | ||
475 | */ | ||
476 | err = pci_set_dma_mask(pdev, DMA_40BIT_MASK); | ||
477 | if (err) { | ||
478 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
479 | if (err) { | ||
480 | shost_printk(KERN_ERR, fnic->lport->host, | ||
481 | "No usable DMA configuration " | ||
482 | "aborting\n"); | ||
483 | goto err_out_release_regions; | ||
484 | } | ||
485 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
486 | if (err) { | ||
487 | shost_printk(KERN_ERR, fnic->lport->host, | ||
488 | "Unable to obtain 32-bit DMA " | ||
489 | "for consistent allocations, aborting.\n"); | ||
490 | goto err_out_release_regions; | ||
491 | } | ||
492 | } else { | ||
493 | err = pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK); | ||
494 | if (err) { | ||
495 | shost_printk(KERN_ERR, fnic->lport->host, | ||
496 | "Unable to obtain 40-bit DMA " | ||
497 | "for consistent allocations, aborting.\n"); | ||
498 | goto err_out_release_regions; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | /* Map vNIC resources from BAR0 */ | ||
503 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | ||
504 | shost_printk(KERN_ERR, fnic->lport->host, | ||
505 | "BAR0 not memory-map'able, aborting.\n"); | ||
506 | err = -ENODEV; | ||
507 | goto err_out_release_regions; | ||
508 | } | ||
509 | |||
510 | fnic->bar0.vaddr = pci_iomap(pdev, 0, 0); | ||
511 | fnic->bar0.bus_addr = pci_resource_start(pdev, 0); | ||
512 | fnic->bar0.len = pci_resource_len(pdev, 0); | ||
513 | |||
514 | if (!fnic->bar0.vaddr) { | ||
515 | shost_printk(KERN_ERR, fnic->lport->host, | ||
516 | "Cannot memory-map BAR0 res hdr, " | ||
517 | "aborting.\n"); | ||
518 | err = -ENODEV; | ||
519 | goto err_out_release_regions; | ||
520 | } | ||
521 | |||
522 | fnic->vdev = vnic_dev_register(NULL, fnic, pdev, &fnic->bar0); | ||
523 | if (!fnic->vdev) { | ||
524 | shost_printk(KERN_ERR, fnic->lport->host, | ||
525 | "vNIC registration failed, " | ||
526 | "aborting.\n"); | ||
527 | err = -ENODEV; | ||
528 | goto err_out_iounmap; | ||
529 | } | ||
530 | |||
531 | err = fnic_dev_wait(fnic->vdev, vnic_dev_open, | ||
532 | vnic_dev_open_done, 0); | ||
533 | if (err) { | ||
534 | shost_printk(KERN_ERR, fnic->lport->host, | ||
535 | "vNIC dev open failed, aborting.\n"); | ||
536 | goto err_out_vnic_unregister; | ||
537 | } | ||
538 | |||
539 | err = vnic_dev_init(fnic->vdev, 0); | ||
540 | if (err) { | ||
541 | shost_printk(KERN_ERR, fnic->lport->host, | ||
542 | "vNIC dev init failed, aborting.\n"); | ||
543 | goto err_out_dev_close; | ||
544 | } | ||
545 | |||
546 | err = vnic_dev_mac_addr(fnic->vdev, fnic->mac_addr); | ||
547 | if (err) { | ||
548 | shost_printk(KERN_ERR, fnic->lport->host, | ||
549 | "vNIC get MAC addr failed \n"); | ||
550 | goto err_out_dev_close; | ||
551 | } | ||
552 | |||
553 | /* Get vNIC configuration */ | ||
554 | err = fnic_get_vnic_config(fnic); | ||
555 | if (err) { | ||
556 | shost_printk(KERN_ERR, fnic->lport->host, | ||
557 | "Get vNIC configuration failed, " | ||
558 | "aborting.\n"); | ||
559 | goto err_out_dev_close; | ||
560 | } | ||
561 | host->max_lun = fnic->config.luns_per_tgt; | ||
562 | host->max_id = FNIC_MAX_FCP_TARGET; | ||
563 | |||
564 | fnic_get_res_counts(fnic); | ||
565 | |||
566 | err = fnic_set_intr_mode(fnic); | ||
567 | if (err) { | ||
568 | shost_printk(KERN_ERR, fnic->lport->host, | ||
569 | "Failed to set intr mode, " | ||
570 | "aborting.\n"); | ||
571 | goto err_out_dev_close; | ||
572 | } | ||
573 | |||
574 | err = fnic_request_intr(fnic); | ||
575 | if (err) { | ||
576 | shost_printk(KERN_ERR, fnic->lport->host, | ||
577 | "Unable to request irq.\n"); | ||
578 | goto err_out_clear_intr; | ||
579 | } | ||
580 | |||
581 | err = fnic_alloc_vnic_resources(fnic); | ||
582 | if (err) { | ||
583 | shost_printk(KERN_ERR, fnic->lport->host, | ||
584 | "Failed to alloc vNIC resources, " | ||
585 | "aborting.\n"); | ||
586 | goto err_out_free_intr; | ||
587 | } | ||
588 | |||
589 | |||
590 | /* initialize all fnic locks */ | ||
591 | spin_lock_init(&fnic->fnic_lock); | ||
592 | |||
593 | for (i = 0; i < FNIC_WQ_MAX; i++) | ||
594 | spin_lock_init(&fnic->wq_lock[i]); | ||
595 | |||
596 | for (i = 0; i < FNIC_WQ_COPY_MAX; i++) { | ||
597 | spin_lock_init(&fnic->wq_copy_lock[i]); | ||
598 | fnic->wq_copy_desc_low[i] = DESC_CLEAN_LOW_WATERMARK; | ||
599 | fnic->fw_ack_recd[i] = 0; | ||
600 | fnic->fw_ack_index[i] = -1; | ||
601 | } | ||
602 | |||
603 | for (i = 0; i < FNIC_IO_LOCKS; i++) | ||
604 | spin_lock_init(&fnic->io_req_lock[i]); | ||
605 | |||
606 | fnic->io_req_pool = mempool_create_slab_pool(2, fnic_io_req_cache); | ||
607 | if (!fnic->io_req_pool) | ||
608 | goto err_out_free_resources; | ||
609 | |||
610 | pool = mempool_create(2, fnic_alloc_slab_dma, mempool_free_slab, | ||
611 | fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); | ||
612 | if (!pool) | ||
613 | goto err_out_free_ioreq_pool; | ||
614 | fnic->io_sgl_pool[FNIC_SGL_CACHE_DFLT] = pool; | ||
615 | |||
616 | pool = mempool_create(2, fnic_alloc_slab_dma, mempool_free_slab, | ||
617 | fnic_sgl_cache[FNIC_SGL_CACHE_MAX]); | ||
618 | if (!pool) | ||
619 | goto err_out_free_dflt_pool; | ||
620 | fnic->io_sgl_pool[FNIC_SGL_CACHE_MAX] = pool; | ||
621 | |||
622 | /* setup vlan config, hw inserts vlan header */ | ||
623 | fnic->vlan_hw_insert = 1; | ||
624 | fnic->vlan_id = 0; | ||
625 | |||
626 | fnic->flogi_oxid = FC_XID_UNKNOWN; | ||
627 | fnic->flogi = NULL; | ||
628 | fnic->flogi_resp = NULL; | ||
629 | fnic->state = FNIC_IN_FC_MODE; | ||
630 | |||
631 | /* Enable hardware stripping of vlan header on ingress */ | ||
632 | fnic_set_nic_config(fnic, 0, 0, 0, 0, 0, 0, 1); | ||
633 | |||
634 | /* Setup notification buffer area */ | ||
635 | err = fnic_notify_set(fnic); | ||
636 | if (err) { | ||
637 | shost_printk(KERN_ERR, fnic->lport->host, | ||
638 | "Failed to alloc notify buffer, aborting.\n"); | ||
639 | goto err_out_free_max_pool; | ||
640 | } | ||
641 | |||
642 | /* Setup notify timer when using MSI interrupts */ | ||
643 | if (vnic_dev_get_intr_mode(fnic->vdev) == VNIC_DEV_INTR_MODE_MSI) | ||
644 | setup_timer(&fnic->notify_timer, | ||
645 | fnic_notify_timer, (unsigned long)fnic); | ||
646 | |||
647 | /* allocate RQ buffers and post them to RQ*/ | ||
648 | for (i = 0; i < fnic->rq_count; i++) { | ||
649 | err = vnic_rq_fill(&fnic->rq[i], fnic_alloc_rq_frame); | ||
650 | if (err) { | ||
651 | shost_printk(KERN_ERR, fnic->lport->host, | ||
652 | "fnic_alloc_rq_frame can't alloc " | ||
653 | "frame\n"); | ||
654 | goto err_out_free_rq_buf; | ||
655 | } | ||
656 | } | ||
657 | |||
658 | /* | ||
659 | * Initialization done with PCI system, hardware, firmware. | ||
660 | * Add host to SCSI | ||
661 | */ | ||
662 | err = scsi_add_host(lp->host, &pdev->dev); | ||
663 | if (err) { | ||
664 | shost_printk(KERN_ERR, fnic->lport->host, | ||
665 | "fnic: scsi_add_host failed...exiting\n"); | ||
666 | goto err_out_free_rq_buf; | ||
667 | } | ||
668 | |||
669 | /* Start local port initiatialization */ | ||
670 | |||
671 | lp->link_up = 0; | ||
672 | lp->tt = fnic_transport_template; | ||
673 | |||
674 | lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3, | ||
675 | FCPIO_HOST_EXCH_RANGE_START, | ||
676 | FCPIO_HOST_EXCH_RANGE_END); | ||
677 | if (!lp->emp) { | ||
678 | err = -ENOMEM; | ||
679 | goto err_out_remove_scsi_host; | ||
680 | } | ||
681 | |||
682 | lp->max_retry_count = fnic->config.flogi_retries; | ||
683 | lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS | | ||
684 | FCP_SPPF_CONF_COMPL); | ||
685 | if (fnic->config.flags & VFCF_FCP_SEQ_LVL_ERR) | ||
686 | lp->service_params |= FCP_SPPF_RETRY; | ||
687 | |||
688 | lp->boot_time = jiffies; | ||
689 | lp->e_d_tov = fnic->config.ed_tov; | ||
690 | lp->r_a_tov = fnic->config.ra_tov; | ||
691 | lp->link_supported_speeds = FC_PORTSPEED_10GBIT; | ||
692 | fc_set_wwnn(lp, fnic->config.node_wwn); | ||
693 | fc_set_wwpn(lp, fnic->config.port_wwn); | ||
694 | |||
695 | fc_exch_init(lp); | ||
696 | fc_lport_init(lp); | ||
697 | fc_elsct_init(lp); | ||
698 | fc_rport_init(lp); | ||
699 | fc_disc_init(lp); | ||
700 | |||
701 | fc_lport_config(lp); | ||
702 | |||
703 | if (fc_set_mfs(lp, fnic->config.maxdatafieldsize + | ||
704 | sizeof(struct fc_frame_header))) { | ||
705 | err = -EINVAL; | ||
706 | goto err_out_free_exch_mgr; | ||
707 | } | ||
708 | fc_host_maxframe_size(lp->host) = lp->mfs; | ||
709 | |||
710 | sprintf(fc_host_symbolic_name(lp->host), | ||
711 | DRV_NAME " v" DRV_VERSION " over %s", fnic->name); | ||
712 | |||
713 | spin_lock_irqsave(&fnic_list_lock, flags); | ||
714 | list_add_tail(&fnic->list, &fnic_list); | ||
715 | spin_unlock_irqrestore(&fnic_list_lock, flags); | ||
716 | |||
717 | INIT_WORK(&fnic->link_work, fnic_handle_link); | ||
718 | INIT_WORK(&fnic->frame_work, fnic_handle_frame); | ||
719 | skb_queue_head_init(&fnic->frame_queue); | ||
720 | |||
721 | /* Enable all queues */ | ||
722 | for (i = 0; i < fnic->raw_wq_count; i++) | ||
723 | vnic_wq_enable(&fnic->wq[i]); | ||
724 | for (i = 0; i < fnic->rq_count; i++) | ||
725 | vnic_rq_enable(&fnic->rq[i]); | ||
726 | for (i = 0; i < fnic->wq_copy_count; i++) | ||
727 | vnic_wq_copy_enable(&fnic->wq_copy[i]); | ||
728 | |||
729 | fc_fabric_login(lp); | ||
730 | |||
731 | vnic_dev_enable(fnic->vdev); | ||
732 | for (i = 0; i < fnic->intr_count; i++) | ||
733 | vnic_intr_unmask(&fnic->intr[i]); | ||
734 | |||
735 | fnic_notify_timer_start(fnic); | ||
736 | |||
737 | return 0; | ||
738 | |||
739 | err_out_free_exch_mgr: | ||
740 | fc_exch_mgr_free(lp->emp); | ||
741 | err_out_remove_scsi_host: | ||
742 | fc_remove_host(fnic->lport->host); | ||
743 | scsi_remove_host(fnic->lport->host); | ||
744 | err_out_free_rq_buf: | ||
745 | for (i = 0; i < fnic->rq_count; i++) | ||
746 | vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf); | ||
747 | vnic_dev_notify_unset(fnic->vdev); | ||
748 | err_out_free_max_pool: | ||
749 | mempool_destroy(fnic->io_sgl_pool[FNIC_SGL_CACHE_MAX]); | ||
750 | err_out_free_dflt_pool: | ||
751 | mempool_destroy(fnic->io_sgl_pool[FNIC_SGL_CACHE_DFLT]); | ||
752 | err_out_free_ioreq_pool: | ||
753 | mempool_destroy(fnic->io_req_pool); | ||
754 | err_out_free_resources: | ||
755 | fnic_free_vnic_resources(fnic); | ||
756 | err_out_free_intr: | ||
757 | fnic_free_intr(fnic); | ||
758 | err_out_clear_intr: | ||
759 | fnic_clear_intr_mode(fnic); | ||
760 | err_out_dev_close: | ||
761 | vnic_dev_close(fnic->vdev); | ||
762 | err_out_vnic_unregister: | ||
763 | vnic_dev_unregister(fnic->vdev); | ||
764 | err_out_iounmap: | ||
765 | fnic_iounmap(fnic); | ||
766 | err_out_release_regions: | ||
767 | pci_release_regions(pdev); | ||
768 | err_out_disable_device: | ||
769 | pci_disable_device(pdev); | ||
770 | err_out_free_hba: | ||
771 | scsi_host_put(lp->host); | ||
772 | err_out: | ||
773 | return err; | ||
774 | } | ||
775 | |||
776 | static void __devexit fnic_remove(struct pci_dev *pdev) | ||
777 | { | ||
778 | struct fnic *fnic = pci_get_drvdata(pdev); | ||
779 | unsigned long flags; | ||
780 | |||
781 | /* | ||
782 | * Mark state so that the workqueue thread stops forwarding | ||
783 | * received frames and link events to the local port. ISR and | ||
784 | * other threads that can queue work items will also stop | ||
785 | * creating work items on the fnic workqueue | ||
786 | */ | ||
787 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
788 | fnic->stop_rx_link_events = 1; | ||
789 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
790 | |||
791 | if (vnic_dev_get_intr_mode(fnic->vdev) == VNIC_DEV_INTR_MODE_MSI) | ||
792 | del_timer_sync(&fnic->notify_timer); | ||
793 | |||
794 | /* | ||
795 | * Flush the fnic event queue. After this call, there should | ||
796 | * be no event queued for this fnic device in the workqueue | ||
797 | */ | ||
798 | flush_workqueue(fnic_event_queue); | ||
799 | skb_queue_purge(&fnic->frame_queue); | ||
800 | |||
801 | /* | ||
802 | * Log off the fabric. This stops all remote ports, dns port, | ||
803 | * logs off the fabric. This flushes all rport, disc, lport work | ||
804 | * before returning | ||
805 | */ | ||
806 | fc_fabric_logoff(fnic->lport); | ||
807 | |||
808 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
809 | fnic->in_remove = 1; | ||
810 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
811 | |||
812 | fc_lport_destroy(fnic->lport); | ||
813 | |||
814 | /* | ||
815 | * This stops the fnic device, masks all interrupts. Completed | ||
816 | * CQ entries are drained. Posted WQ/RQ/Copy-WQ entries are | ||
817 | * cleaned up | ||
818 | */ | ||
819 | fnic_cleanup(fnic); | ||
820 | |||
821 | BUG_ON(!skb_queue_empty(&fnic->frame_queue)); | ||
822 | |||
823 | spin_lock_irqsave(&fnic_list_lock, flags); | ||
824 | list_del(&fnic->list); | ||
825 | spin_unlock_irqrestore(&fnic_list_lock, flags); | ||
826 | |||
827 | fc_remove_host(fnic->lport->host); | ||
828 | scsi_remove_host(fnic->lport->host); | ||
829 | fc_exch_mgr_free(fnic->lport->emp); | ||
830 | vnic_dev_notify_unset(fnic->vdev); | ||
831 | fnic_free_vnic_resources(fnic); | ||
832 | fnic_free_intr(fnic); | ||
833 | fnic_clear_intr_mode(fnic); | ||
834 | vnic_dev_close(fnic->vdev); | ||
835 | vnic_dev_unregister(fnic->vdev); | ||
836 | fnic_iounmap(fnic); | ||
837 | pci_release_regions(pdev); | ||
838 | pci_disable_device(pdev); | ||
839 | pci_set_drvdata(pdev, NULL); | ||
840 | scsi_host_put(fnic->lport->host); | ||
841 | } | ||
842 | |||
843 | static struct pci_driver fnic_driver = { | ||
844 | .name = DRV_NAME, | ||
845 | .id_table = fnic_id_table, | ||
846 | .probe = fnic_probe, | ||
847 | .remove = __devexit_p(fnic_remove), | ||
848 | }; | ||
849 | |||
850 | static int __init fnic_init_module(void) | ||
851 | { | ||
852 | size_t len; | ||
853 | int err = 0; | ||
854 | |||
855 | printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION); | ||
856 | |||
857 | /* Create a cache for allocation of default size sgls */ | ||
858 | len = sizeof(struct fnic_dflt_sgl_list); | ||
859 | fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create | ||
860 | ("fnic_sgl_dflt", len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN, | ||
861 | SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA, | ||
862 | NULL); | ||
863 | if (!fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]) { | ||
864 | printk(KERN_ERR PFX "failed to create fnic dflt sgl slab\n"); | ||
865 | err = -ENOMEM; | ||
866 | goto err_create_fnic_sgl_slab_dflt; | ||
867 | } | ||
868 | |||
869 | /* Create a cache for allocation of max size sgls*/ | ||
870 | len = sizeof(struct fnic_sgl_list); | ||
871 | fnic_sgl_cache[FNIC_SGL_CACHE_MAX] = kmem_cache_create | ||
872 | ("fnic_sgl_max", len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN, | ||
873 | SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA, | ||
874 | NULL); | ||
875 | if (!fnic_sgl_cache[FNIC_SGL_CACHE_MAX]) { | ||
876 | printk(KERN_ERR PFX "failed to create fnic max sgl slab\n"); | ||
877 | err = -ENOMEM; | ||
878 | goto err_create_fnic_sgl_slab_max; | ||
879 | } | ||
880 | |||
881 | /* Create a cache of io_req structs for use via mempool */ | ||
882 | fnic_io_req_cache = kmem_cache_create("fnic_io_req", | ||
883 | sizeof(struct fnic_io_req), | ||
884 | 0, SLAB_HWCACHE_ALIGN, NULL); | ||
885 | if (!fnic_io_req_cache) { | ||
886 | printk(KERN_ERR PFX "failed to create fnic io_req slab\n"); | ||
887 | err = -ENOMEM; | ||
888 | goto err_create_fnic_ioreq_slab; | ||
889 | } | ||
890 | |||
891 | fnic_event_queue = create_singlethread_workqueue("fnic_event_wq"); | ||
892 | if (!fnic_event_queue) { | ||
893 | printk(KERN_ERR PFX "fnic work queue create failed\n"); | ||
894 | err = -ENOMEM; | ||
895 | goto err_create_fnic_workq; | ||
896 | } | ||
897 | |||
898 | spin_lock_init(&fnic_list_lock); | ||
899 | INIT_LIST_HEAD(&fnic_list); | ||
900 | |||
901 | fnic_fc_transport = fc_attach_transport(&fnic_fc_functions); | ||
902 | if (!fnic_fc_transport) { | ||
903 | printk(KERN_ERR PFX "fc_attach_transport error\n"); | ||
904 | err = -ENOMEM; | ||
905 | goto err_fc_transport; | ||
906 | } | ||
907 | |||
908 | /* register the driver with PCI system */ | ||
909 | err = pci_register_driver(&fnic_driver); | ||
910 | if (err < 0) { | ||
911 | printk(KERN_ERR PFX "pci register error\n"); | ||
912 | goto err_pci_register; | ||
913 | } | ||
914 | return err; | ||
915 | |||
916 | err_pci_register: | ||
917 | fc_release_transport(fnic_fc_transport); | ||
918 | err_fc_transport: | ||
919 | destroy_workqueue(fnic_event_queue); | ||
920 | err_create_fnic_workq: | ||
921 | kmem_cache_destroy(fnic_io_req_cache); | ||
922 | err_create_fnic_ioreq_slab: | ||
923 | kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_MAX]); | ||
924 | err_create_fnic_sgl_slab_max: | ||
925 | kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); | ||
926 | err_create_fnic_sgl_slab_dflt: | ||
927 | return err; | ||
928 | } | ||
929 | |||
930 | static void __exit fnic_cleanup_module(void) | ||
931 | { | ||
932 | pci_unregister_driver(&fnic_driver); | ||
933 | destroy_workqueue(fnic_event_queue); | ||
934 | kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_MAX]); | ||
935 | kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); | ||
936 | kmem_cache_destroy(fnic_io_req_cache); | ||
937 | fc_release_transport(fnic_fc_transport); | ||
938 | } | ||
939 | |||
940 | module_init(fnic_init_module); | ||
941 | module_exit(fnic_cleanup_module); | ||
942 | |||
diff --git a/drivers/scsi/fnic/fnic_res.c b/drivers/scsi/fnic/fnic_res.c new file mode 100644 index 000000000000..7ba61ec715d2 --- /dev/null +++ b/drivers/scsi/fnic/fnic_res.c | |||
@@ -0,0 +1,444 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include "wq_enet_desc.h" | ||
22 | #include "rq_enet_desc.h" | ||
23 | #include "cq_enet_desc.h" | ||
24 | #include "vnic_resource.h" | ||
25 | #include "vnic_dev.h" | ||
26 | #include "vnic_wq.h" | ||
27 | #include "vnic_rq.h" | ||
28 | #include "vnic_cq.h" | ||
29 | #include "vnic_intr.h" | ||
30 | #include "vnic_stats.h" | ||
31 | #include "vnic_nic.h" | ||
32 | #include "fnic.h" | ||
33 | |||
34 | int fnic_get_vnic_config(struct fnic *fnic) | ||
35 | { | ||
36 | struct vnic_fc_config *c = &fnic->config; | ||
37 | int err; | ||
38 | |||
39 | #define GET_CONFIG(m) \ | ||
40 | do { \ | ||
41 | err = vnic_dev_spec(fnic->vdev, \ | ||
42 | offsetof(struct vnic_fc_config, m), \ | ||
43 | sizeof(c->m), &c->m); \ | ||
44 | if (err) { \ | ||
45 | shost_printk(KERN_ERR, fnic->lport->host, \ | ||
46 | "Error getting %s, %d\n", #m, \ | ||
47 | err); \ | ||
48 | return err; \ | ||
49 | } \ | ||
50 | } while (0); | ||
51 | |||
52 | GET_CONFIG(node_wwn); | ||
53 | GET_CONFIG(port_wwn); | ||
54 | GET_CONFIG(wq_enet_desc_count); | ||
55 | GET_CONFIG(wq_copy_desc_count); | ||
56 | GET_CONFIG(rq_desc_count); | ||
57 | GET_CONFIG(maxdatafieldsize); | ||
58 | GET_CONFIG(ed_tov); | ||
59 | GET_CONFIG(ra_tov); | ||
60 | GET_CONFIG(intr_timer); | ||
61 | GET_CONFIG(intr_timer_type); | ||
62 | GET_CONFIG(flags); | ||
63 | GET_CONFIG(flogi_retries); | ||
64 | GET_CONFIG(flogi_timeout); | ||
65 | GET_CONFIG(plogi_retries); | ||
66 | GET_CONFIG(plogi_timeout); | ||
67 | GET_CONFIG(io_throttle_count); | ||
68 | GET_CONFIG(link_down_timeout); | ||
69 | GET_CONFIG(port_down_timeout); | ||
70 | GET_CONFIG(port_down_io_retries); | ||
71 | GET_CONFIG(luns_per_tgt); | ||
72 | |||
73 | c->wq_enet_desc_count = | ||
74 | min_t(u32, VNIC_FNIC_WQ_DESCS_MAX, | ||
75 | max_t(u32, VNIC_FNIC_WQ_DESCS_MIN, | ||
76 | c->wq_enet_desc_count)); | ||
77 | c->wq_enet_desc_count = ALIGN(c->wq_enet_desc_count, 16); | ||
78 | |||
79 | c->wq_copy_desc_count = | ||
80 | min_t(u32, VNIC_FNIC_WQ_COPY_DESCS_MAX, | ||
81 | max_t(u32, VNIC_FNIC_WQ_COPY_DESCS_MIN, | ||
82 | c->wq_copy_desc_count)); | ||
83 | c->wq_copy_desc_count = ALIGN(c->wq_copy_desc_count, 16); | ||
84 | |||
85 | c->rq_desc_count = | ||
86 | min_t(u32, VNIC_FNIC_RQ_DESCS_MAX, | ||
87 | max_t(u32, VNIC_FNIC_RQ_DESCS_MIN, | ||
88 | c->rq_desc_count)); | ||
89 | c->rq_desc_count = ALIGN(c->rq_desc_count, 16); | ||
90 | |||
91 | c->maxdatafieldsize = | ||
92 | min_t(u16, VNIC_FNIC_MAXDATAFIELDSIZE_MAX, | ||
93 | max_t(u16, VNIC_FNIC_MAXDATAFIELDSIZE_MIN, | ||
94 | c->maxdatafieldsize)); | ||
95 | c->ed_tov = | ||
96 | min_t(u32, VNIC_FNIC_EDTOV_MAX, | ||
97 | max_t(u32, VNIC_FNIC_EDTOV_MIN, | ||
98 | c->ed_tov)); | ||
99 | |||
100 | c->ra_tov = | ||
101 | min_t(u32, VNIC_FNIC_RATOV_MAX, | ||
102 | max_t(u32, VNIC_FNIC_RATOV_MIN, | ||
103 | c->ra_tov)); | ||
104 | |||
105 | c->flogi_retries = | ||
106 | min_t(u32, VNIC_FNIC_FLOGI_RETRIES_MAX, c->flogi_retries); | ||
107 | |||
108 | c->flogi_timeout = | ||
109 | min_t(u32, VNIC_FNIC_FLOGI_TIMEOUT_MAX, | ||
110 | max_t(u32, VNIC_FNIC_FLOGI_TIMEOUT_MIN, | ||
111 | c->flogi_timeout)); | ||
112 | |||
113 | c->plogi_retries = | ||
114 | min_t(u32, VNIC_FNIC_PLOGI_RETRIES_MAX, c->plogi_retries); | ||
115 | |||
116 | c->plogi_timeout = | ||
117 | min_t(u32, VNIC_FNIC_PLOGI_TIMEOUT_MAX, | ||
118 | max_t(u32, VNIC_FNIC_PLOGI_TIMEOUT_MIN, | ||
119 | c->plogi_timeout)); | ||
120 | |||
121 | c->io_throttle_count = | ||
122 | min_t(u32, VNIC_FNIC_IO_THROTTLE_COUNT_MAX, | ||
123 | max_t(u32, VNIC_FNIC_IO_THROTTLE_COUNT_MIN, | ||
124 | c->io_throttle_count)); | ||
125 | |||
126 | c->link_down_timeout = | ||
127 | min_t(u32, VNIC_FNIC_LINK_DOWN_TIMEOUT_MAX, | ||
128 | c->link_down_timeout); | ||
129 | |||
130 | c->port_down_timeout = | ||
131 | min_t(u32, VNIC_FNIC_PORT_DOWN_TIMEOUT_MAX, | ||
132 | c->port_down_timeout); | ||
133 | |||
134 | c->port_down_io_retries = | ||
135 | min_t(u32, VNIC_FNIC_PORT_DOWN_IO_RETRIES_MAX, | ||
136 | c->port_down_io_retries); | ||
137 | |||
138 | c->luns_per_tgt = | ||
139 | min_t(u32, VNIC_FNIC_LUNS_PER_TARGET_MAX, | ||
140 | max_t(u32, VNIC_FNIC_LUNS_PER_TARGET_MIN, | ||
141 | c->luns_per_tgt)); | ||
142 | |||
143 | c->intr_timer = min_t(u16, VNIC_INTR_TIMER_MAX, c->intr_timer); | ||
144 | c->intr_timer_type = c->intr_timer_type; | ||
145 | |||
146 | shost_printk(KERN_INFO, fnic->lport->host, | ||
147 | "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x " | ||
148 | "wq/wq_copy/rq %d/%d/%d\n", | ||
149 | fnic->mac_addr[0], fnic->mac_addr[1], fnic->mac_addr[2], | ||
150 | fnic->mac_addr[3], fnic->mac_addr[4], fnic->mac_addr[5], | ||
151 | c->wq_enet_desc_count, c->wq_copy_desc_count, | ||
152 | c->rq_desc_count); | ||
153 | shost_printk(KERN_INFO, fnic->lport->host, | ||
154 | "vNIC node wwn %llx port wwn %llx\n", | ||
155 | c->node_wwn, c->port_wwn); | ||
156 | shost_printk(KERN_INFO, fnic->lport->host, | ||
157 | "vNIC ed_tov %d ra_tov %d\n", | ||
158 | c->ed_tov, c->ra_tov); | ||
159 | shost_printk(KERN_INFO, fnic->lport->host, | ||
160 | "vNIC mtu %d intr timer %d\n", | ||
161 | c->maxdatafieldsize, c->intr_timer); | ||
162 | shost_printk(KERN_INFO, fnic->lport->host, | ||
163 | "vNIC flags 0x%x luns per tgt %d\n", | ||
164 | c->flags, c->luns_per_tgt); | ||
165 | shost_printk(KERN_INFO, fnic->lport->host, | ||
166 | "vNIC flogi_retries %d flogi timeout %d\n", | ||
167 | c->flogi_retries, c->flogi_timeout); | ||
168 | shost_printk(KERN_INFO, fnic->lport->host, | ||
169 | "vNIC plogi retries %d plogi timeout %d\n", | ||
170 | c->plogi_retries, c->plogi_timeout); | ||
171 | shost_printk(KERN_INFO, fnic->lport->host, | ||
172 | "vNIC io throttle count %d link dn timeout %d\n", | ||
173 | c->io_throttle_count, c->link_down_timeout); | ||
174 | shost_printk(KERN_INFO, fnic->lport->host, | ||
175 | "vNIC port dn io retries %d port dn timeout %d\n", | ||
176 | c->port_down_io_retries, c->port_down_timeout); | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | int fnic_set_nic_config(struct fnic *fnic, u8 rss_default_cpu, | ||
182 | u8 rss_hash_type, | ||
183 | u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, | ||
184 | u8 tso_ipid_split_en, u8 ig_vlan_strip_en) | ||
185 | { | ||
186 | u64 a0, a1; | ||
187 | u32 nic_cfg; | ||
188 | int wait = 1000; | ||
189 | |||
190 | vnic_set_nic_cfg(&nic_cfg, rss_default_cpu, | ||
191 | rss_hash_type, rss_hash_bits, rss_base_cpu, | ||
192 | rss_enable, tso_ipid_split_en, ig_vlan_strip_en); | ||
193 | |||
194 | a0 = nic_cfg; | ||
195 | a1 = 0; | ||
196 | |||
197 | return vnic_dev_cmd(fnic->vdev, CMD_NIC_CFG, &a0, &a1, wait); | ||
198 | } | ||
199 | |||
200 | void fnic_get_res_counts(struct fnic *fnic) | ||
201 | { | ||
202 | fnic->wq_count = vnic_dev_get_res_count(fnic->vdev, RES_TYPE_WQ); | ||
203 | fnic->raw_wq_count = fnic->wq_count - 1; | ||
204 | fnic->wq_copy_count = fnic->wq_count - fnic->raw_wq_count; | ||
205 | fnic->rq_count = vnic_dev_get_res_count(fnic->vdev, RES_TYPE_RQ); | ||
206 | fnic->cq_count = vnic_dev_get_res_count(fnic->vdev, RES_TYPE_CQ); | ||
207 | fnic->intr_count = vnic_dev_get_res_count(fnic->vdev, | ||
208 | RES_TYPE_INTR_CTRL); | ||
209 | } | ||
210 | |||
211 | void fnic_free_vnic_resources(struct fnic *fnic) | ||
212 | { | ||
213 | unsigned int i; | ||
214 | |||
215 | for (i = 0; i < fnic->raw_wq_count; i++) | ||
216 | vnic_wq_free(&fnic->wq[i]); | ||
217 | |||
218 | for (i = 0; i < fnic->wq_copy_count; i++) | ||
219 | vnic_wq_copy_free(&fnic->wq_copy[i]); | ||
220 | |||
221 | for (i = 0; i < fnic->rq_count; i++) | ||
222 | vnic_rq_free(&fnic->rq[i]); | ||
223 | |||
224 | for (i = 0; i < fnic->cq_count; i++) | ||
225 | vnic_cq_free(&fnic->cq[i]); | ||
226 | |||
227 | for (i = 0; i < fnic->intr_count; i++) | ||
228 | vnic_intr_free(&fnic->intr[i]); | ||
229 | } | ||
230 | |||
231 | int fnic_alloc_vnic_resources(struct fnic *fnic) | ||
232 | { | ||
233 | enum vnic_dev_intr_mode intr_mode; | ||
234 | unsigned int mask_on_assertion; | ||
235 | unsigned int interrupt_offset; | ||
236 | unsigned int error_interrupt_enable; | ||
237 | unsigned int error_interrupt_offset; | ||
238 | unsigned int i, cq_index; | ||
239 | unsigned int wq_copy_cq_desc_count; | ||
240 | int err; | ||
241 | |||
242 | intr_mode = vnic_dev_get_intr_mode(fnic->vdev); | ||
243 | |||
244 | shost_printk(KERN_INFO, fnic->lport->host, "vNIC interrupt mode: %s\n", | ||
245 | intr_mode == VNIC_DEV_INTR_MODE_INTX ? "legacy PCI INTx" : | ||
246 | intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" : | ||
247 | intr_mode == VNIC_DEV_INTR_MODE_MSIX ? | ||
248 | "MSI-X" : "unknown"); | ||
249 | |||
250 | shost_printk(KERN_INFO, fnic->lport->host, "vNIC resources avail: " | ||
251 | "wq %d cp_wq %d raw_wq %d rq %d cq %d intr %d\n", | ||
252 | fnic->wq_count, fnic->wq_copy_count, fnic->raw_wq_count, | ||
253 | fnic->rq_count, fnic->cq_count, fnic->intr_count); | ||
254 | |||
255 | /* Allocate Raw WQ used for FCS frames */ | ||
256 | for (i = 0; i < fnic->raw_wq_count; i++) { | ||
257 | err = vnic_wq_alloc(fnic->vdev, &fnic->wq[i], i, | ||
258 | fnic->config.wq_enet_desc_count, | ||
259 | sizeof(struct wq_enet_desc)); | ||
260 | if (err) | ||
261 | goto err_out_cleanup; | ||
262 | } | ||
263 | |||
264 | /* Allocate Copy WQs used for SCSI IOs */ | ||
265 | for (i = 0; i < fnic->wq_copy_count; i++) { | ||
266 | err = vnic_wq_copy_alloc(fnic->vdev, &fnic->wq_copy[i], | ||
267 | (fnic->raw_wq_count + i), | ||
268 | fnic->config.wq_copy_desc_count, | ||
269 | sizeof(struct fcpio_host_req)); | ||
270 | if (err) | ||
271 | goto err_out_cleanup; | ||
272 | } | ||
273 | |||
274 | /* RQ for receiving FCS frames */ | ||
275 | for (i = 0; i < fnic->rq_count; i++) { | ||
276 | err = vnic_rq_alloc(fnic->vdev, &fnic->rq[i], i, | ||
277 | fnic->config.rq_desc_count, | ||
278 | sizeof(struct rq_enet_desc)); | ||
279 | if (err) | ||
280 | goto err_out_cleanup; | ||
281 | } | ||
282 | |||
283 | /* CQ for each RQ */ | ||
284 | for (i = 0; i < fnic->rq_count; i++) { | ||
285 | cq_index = i; | ||
286 | err = vnic_cq_alloc(fnic->vdev, | ||
287 | &fnic->cq[cq_index], cq_index, | ||
288 | fnic->config.rq_desc_count, | ||
289 | sizeof(struct cq_enet_rq_desc)); | ||
290 | if (err) | ||
291 | goto err_out_cleanup; | ||
292 | } | ||
293 | |||
294 | /* CQ for each WQ */ | ||
295 | for (i = 0; i < fnic->raw_wq_count; i++) { | ||
296 | cq_index = fnic->rq_count + i; | ||
297 | err = vnic_cq_alloc(fnic->vdev, &fnic->cq[cq_index], cq_index, | ||
298 | fnic->config.wq_enet_desc_count, | ||
299 | sizeof(struct cq_enet_wq_desc)); | ||
300 | if (err) | ||
301 | goto err_out_cleanup; | ||
302 | } | ||
303 | |||
304 | /* CQ for each COPY WQ */ | ||
305 | wq_copy_cq_desc_count = (fnic->config.wq_copy_desc_count * 3); | ||
306 | for (i = 0; i < fnic->wq_copy_count; i++) { | ||
307 | cq_index = fnic->raw_wq_count + fnic->rq_count + i; | ||
308 | err = vnic_cq_alloc(fnic->vdev, &fnic->cq[cq_index], | ||
309 | cq_index, | ||
310 | wq_copy_cq_desc_count, | ||
311 | sizeof(struct fcpio_fw_req)); | ||
312 | if (err) | ||
313 | goto err_out_cleanup; | ||
314 | } | ||
315 | |||
316 | for (i = 0; i < fnic->intr_count; i++) { | ||
317 | err = vnic_intr_alloc(fnic->vdev, &fnic->intr[i], i); | ||
318 | if (err) | ||
319 | goto err_out_cleanup; | ||
320 | } | ||
321 | |||
322 | fnic->legacy_pba = vnic_dev_get_res(fnic->vdev, | ||
323 | RES_TYPE_INTR_PBA_LEGACY, 0); | ||
324 | |||
325 | if (!fnic->legacy_pba && intr_mode == VNIC_DEV_INTR_MODE_INTX) { | ||
326 | shost_printk(KERN_ERR, fnic->lport->host, | ||
327 | "Failed to hook legacy pba resource\n"); | ||
328 | err = -ENODEV; | ||
329 | goto err_out_cleanup; | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * Init RQ/WQ resources. | ||
334 | * | ||
335 | * RQ[0 to n-1] point to CQ[0 to n-1] | ||
336 | * WQ[0 to m-1] point to CQ[n to n+m-1] | ||
337 | * WQ_COPY[0 to k-1] points to CQ[n+m to n+m+k-1] | ||
338 | * | ||
339 | * Note for copy wq we always initialize with cq_index = 0 | ||
340 | * | ||
341 | * Error interrupt is not enabled for MSI. | ||
342 | */ | ||
343 | |||
344 | switch (intr_mode) { | ||
345 | case VNIC_DEV_INTR_MODE_INTX: | ||
346 | case VNIC_DEV_INTR_MODE_MSIX: | ||
347 | error_interrupt_enable = 1; | ||
348 | error_interrupt_offset = fnic->err_intr_offset; | ||
349 | break; | ||
350 | default: | ||
351 | error_interrupt_enable = 0; | ||
352 | error_interrupt_offset = 0; | ||
353 | break; | ||
354 | } | ||
355 | |||
356 | for (i = 0; i < fnic->rq_count; i++) { | ||
357 | cq_index = i; | ||
358 | vnic_rq_init(&fnic->rq[i], | ||
359 | cq_index, | ||
360 | error_interrupt_enable, | ||
361 | error_interrupt_offset); | ||
362 | } | ||
363 | |||
364 | for (i = 0; i < fnic->raw_wq_count; i++) { | ||
365 | cq_index = i + fnic->rq_count; | ||
366 | vnic_wq_init(&fnic->wq[i], | ||
367 | cq_index, | ||
368 | error_interrupt_enable, | ||
369 | error_interrupt_offset); | ||
370 | } | ||
371 | |||
372 | for (i = 0; i < fnic->wq_copy_count; i++) { | ||
373 | vnic_wq_copy_init(&fnic->wq_copy[i], | ||
374 | 0 /* cq_index 0 - always */, | ||
375 | error_interrupt_enable, | ||
376 | error_interrupt_offset); | ||
377 | } | ||
378 | |||
379 | for (i = 0; i < fnic->cq_count; i++) { | ||
380 | |||
381 | switch (intr_mode) { | ||
382 | case VNIC_DEV_INTR_MODE_MSIX: | ||
383 | interrupt_offset = i; | ||
384 | break; | ||
385 | default: | ||
386 | interrupt_offset = 0; | ||
387 | break; | ||
388 | } | ||
389 | |||
390 | vnic_cq_init(&fnic->cq[i], | ||
391 | 0 /* flow_control_enable */, | ||
392 | 1 /* color_enable */, | ||
393 | 0 /* cq_head */, | ||
394 | 0 /* cq_tail */, | ||
395 | 1 /* cq_tail_color */, | ||
396 | 1 /* interrupt_enable */, | ||
397 | 1 /* cq_entry_enable */, | ||
398 | 0 /* cq_message_enable */, | ||
399 | interrupt_offset, | ||
400 | 0 /* cq_message_addr */); | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Init INTR resources | ||
405 | * | ||
406 | * mask_on_assertion is not used for INTx due to the level- | ||
407 | * triggered nature of INTx | ||
408 | */ | ||
409 | |||
410 | switch (intr_mode) { | ||
411 | case VNIC_DEV_INTR_MODE_MSI: | ||
412 | case VNIC_DEV_INTR_MODE_MSIX: | ||
413 | mask_on_assertion = 1; | ||
414 | break; | ||
415 | default: | ||
416 | mask_on_assertion = 0; | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | for (i = 0; i < fnic->intr_count; i++) { | ||
421 | vnic_intr_init(&fnic->intr[i], | ||
422 | fnic->config.intr_timer, | ||
423 | fnic->config.intr_timer_type, | ||
424 | mask_on_assertion); | ||
425 | } | ||
426 | |||
427 | /* init the stats memory by making the first call here */ | ||
428 | err = vnic_dev_stats_dump(fnic->vdev, &fnic->stats); | ||
429 | if (err) { | ||
430 | shost_printk(KERN_ERR, fnic->lport->host, | ||
431 | "vnic_dev_stats_dump failed - x%x\n", err); | ||
432 | goto err_out_cleanup; | ||
433 | } | ||
434 | |||
435 | /* Clear LIF stats */ | ||
436 | vnic_dev_stats_clear(fnic->vdev); | ||
437 | |||
438 | return 0; | ||
439 | |||
440 | err_out_cleanup: | ||
441 | fnic_free_vnic_resources(fnic); | ||
442 | |||
443 | return err; | ||
444 | } | ||
diff --git a/drivers/scsi/fnic/fnic_res.h b/drivers/scsi/fnic/fnic_res.h new file mode 100644 index 000000000000..b6f310262534 --- /dev/null +++ b/drivers/scsi/fnic/fnic_res.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _FNIC_RES_H_ | ||
19 | #define _FNIC_RES_H_ | ||
20 | |||
21 | #include "wq_enet_desc.h" | ||
22 | #include "rq_enet_desc.h" | ||
23 | #include "vnic_wq.h" | ||
24 | #include "vnic_rq.h" | ||
25 | #include "fnic_io.h" | ||
26 | #include "fcpio.h" | ||
27 | #include "vnic_wq_copy.h" | ||
28 | #include "vnic_cq_copy.h" | ||
29 | |||
30 | static inline void fnic_queue_wq_desc(struct vnic_wq *wq, | ||
31 | void *os_buf, dma_addr_t dma_addr, | ||
32 | unsigned int len, unsigned int fc_eof, | ||
33 | int vlan_tag_insert, | ||
34 | unsigned int vlan_tag, | ||
35 | int cq_entry, int sop, int eop) | ||
36 | { | ||
37 | struct wq_enet_desc *desc = vnic_wq_next_desc(wq); | ||
38 | |||
39 | wq_enet_desc_enc(desc, | ||
40 | (u64)dma_addr | VNIC_PADDR_TARGET, | ||
41 | (u16)len, | ||
42 | 0, /* mss_or_csum_offset */ | ||
43 | (u16)fc_eof, | ||
44 | 0, /* offload_mode */ | ||
45 | (u8)eop, (u8)cq_entry, | ||
46 | 1, /* fcoe_encap */ | ||
47 | (u8)vlan_tag_insert, | ||
48 | (u16)vlan_tag, | ||
49 | 0 /* loopback */); | ||
50 | |||
51 | vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop); | ||
52 | } | ||
53 | |||
54 | static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq, | ||
55 | u32 req_id, | ||
56 | u32 lunmap_id, u8 spl_flags, | ||
57 | u32 sgl_cnt, u32 sense_len, | ||
58 | u64 sgl_addr, u64 sns_addr, | ||
59 | u8 crn, u8 pri_ta, | ||
60 | u8 flags, u8 *scsi_cdb, | ||
61 | u32 data_len, u8 *lun, | ||
62 | u32 d_id, u16 mss, | ||
63 | u32 ratov, u32 edtov) | ||
64 | { | ||
65 | struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq); | ||
66 | |||
67 | desc->hdr.type = FCPIO_ICMND_16; /* enum fcpio_type */ | ||
68 | desc->hdr.status = 0; /* header status entry */ | ||
69 | desc->hdr._resvd = 0; /* reserved */ | ||
70 | desc->hdr.tag.u.req_id = req_id; /* id for this request */ | ||
71 | |||
72 | desc->u.icmnd_16.lunmap_id = lunmap_id; /* index into lunmap table */ | ||
73 | desc->u.icmnd_16.special_req_flags = spl_flags; /* exch req flags */ | ||
74 | desc->u.icmnd_16._resvd0[0] = 0; /* reserved */ | ||
75 | desc->u.icmnd_16._resvd0[1] = 0; /* reserved */ | ||
76 | desc->u.icmnd_16._resvd0[2] = 0; /* reserved */ | ||
77 | desc->u.icmnd_16.sgl_cnt = sgl_cnt; /* scatter-gather list count */ | ||
78 | desc->u.icmnd_16.sense_len = sense_len; /* sense buffer length */ | ||
79 | desc->u.icmnd_16.sgl_addr = sgl_addr; /* scatter-gather list addr */ | ||
80 | desc->u.icmnd_16.sense_addr = sns_addr; /* sense buffer address */ | ||
81 | desc->u.icmnd_16.crn = crn; /* SCSI Command Reference No.*/ | ||
82 | desc->u.icmnd_16.pri_ta = pri_ta; /* SCSI Pri & Task attribute */ | ||
83 | desc->u.icmnd_16._resvd1 = 0; /* reserved: should be 0 */ | ||
84 | desc->u.icmnd_16.flags = flags; /* command flags */ | ||
85 | memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, CDB_16); /* SCSI CDB */ | ||
86 | desc->u.icmnd_16.data_len = data_len; /* length of data expected */ | ||
87 | memcpy(desc->u.icmnd_16.lun, lun, LUN_ADDRESS); /* LUN address */ | ||
88 | desc->u.icmnd_16._resvd2 = 0; /* reserved */ | ||
89 | hton24(desc->u.icmnd_16.d_id, d_id); /* FC vNIC only: Target D_ID */ | ||
90 | desc->u.icmnd_16.mss = mss; /* FC vNIC only: max burst */ | ||
91 | desc->u.icmnd_16.r_a_tov = ratov; /*FC vNIC only: Res. Alloc Timeout */ | ||
92 | desc->u.icmnd_16.e_d_tov = edtov; /*FC vNIC only: Err Detect Timeout */ | ||
93 | |||
94 | vnic_wq_copy_post(wq); | ||
95 | } | ||
96 | |||
97 | static inline void fnic_queue_wq_copy_desc_itmf(struct vnic_wq_copy *wq, | ||
98 | u32 req_id, u32 lunmap_id, | ||
99 | u32 tm_req, u32 tm_id, u8 *lun, | ||
100 | u32 d_id, u32 r_a_tov, | ||
101 | u32 e_d_tov) | ||
102 | { | ||
103 | struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq); | ||
104 | |||
105 | desc->hdr.type = FCPIO_ITMF; /* enum fcpio_type */ | ||
106 | desc->hdr.status = 0; /* header status entry */ | ||
107 | desc->hdr._resvd = 0; /* reserved */ | ||
108 | desc->hdr.tag.u.req_id = req_id; /* id for this request */ | ||
109 | |||
110 | desc->u.itmf.lunmap_id = lunmap_id; /* index into lunmap table */ | ||
111 | desc->u.itmf.tm_req = tm_req; /* SCSI Task Management request */ | ||
112 | desc->u.itmf.t_tag = tm_id; /* tag of fcpio to be aborted */ | ||
113 | desc->u.itmf._resvd = 0; | ||
114 | memcpy(desc->u.itmf.lun, lun, LUN_ADDRESS); /* LUN address */ | ||
115 | desc->u.itmf._resvd1 = 0; | ||
116 | hton24(desc->u.itmf.d_id, d_id); /* FC vNIC only: Target D_ID */ | ||
117 | desc->u.itmf.r_a_tov = r_a_tov; /* FC vNIC only: R_A_TOV in msec */ | ||
118 | desc->u.itmf.e_d_tov = e_d_tov; /* FC vNIC only: E_D_TOV in msec */ | ||
119 | |||
120 | vnic_wq_copy_post(wq); | ||
121 | } | ||
122 | |||
123 | static inline void fnic_queue_wq_copy_desc_flogi_reg(struct vnic_wq_copy *wq, | ||
124 | u32 req_id, u8 format, | ||
125 | u32 s_id, u8 *gw_mac) | ||
126 | { | ||
127 | struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq); | ||
128 | |||
129 | desc->hdr.type = FCPIO_FLOGI_REG; /* enum fcpio_type */ | ||
130 | desc->hdr.status = 0; /* header status entry */ | ||
131 | desc->hdr._resvd = 0; /* reserved */ | ||
132 | desc->hdr.tag.u.req_id = req_id; /* id for this request */ | ||
133 | |||
134 | desc->u.flogi_reg.format = format; | ||
135 | hton24(desc->u.flogi_reg.s_id, s_id); | ||
136 | memcpy(desc->u.flogi_reg.gateway_mac, gw_mac, ETH_ALEN); | ||
137 | |||
138 | vnic_wq_copy_post(wq); | ||
139 | } | ||
140 | |||
141 | static inline void fnic_queue_wq_copy_desc_fw_reset(struct vnic_wq_copy *wq, | ||
142 | u32 req_id) | ||
143 | { | ||
144 | struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq); | ||
145 | |||
146 | desc->hdr.type = FCPIO_RESET; /* enum fcpio_type */ | ||
147 | desc->hdr.status = 0; /* header status entry */ | ||
148 | desc->hdr._resvd = 0; /* reserved */ | ||
149 | desc->hdr.tag.u.req_id = req_id; /* id for this request */ | ||
150 | |||
151 | vnic_wq_copy_post(wq); | ||
152 | } | ||
153 | |||
154 | static inline void fnic_queue_wq_copy_desc_lunmap(struct vnic_wq_copy *wq, | ||
155 | u32 req_id, u64 lunmap_addr, | ||
156 | u32 lunmap_len) | ||
157 | { | ||
158 | struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq); | ||
159 | |||
160 | desc->hdr.type = FCPIO_LUNMAP_REQ; /* enum fcpio_type */ | ||
161 | desc->hdr.status = 0; /* header status entry */ | ||
162 | desc->hdr._resvd = 0; /* reserved */ | ||
163 | desc->hdr.tag.u.req_id = req_id; /* id for this request */ | ||
164 | |||
165 | desc->u.lunmap_req.addr = lunmap_addr; /* address of the buffer */ | ||
166 | desc->u.lunmap_req.len = lunmap_len; /* len of the buffer */ | ||
167 | |||
168 | vnic_wq_copy_post(wq); | ||
169 | } | ||
170 | |||
171 | static inline void fnic_queue_rq_desc(struct vnic_rq *rq, | ||
172 | void *os_buf, dma_addr_t dma_addr, | ||
173 | u16 len) | ||
174 | { | ||
175 | struct rq_enet_desc *desc = vnic_rq_next_desc(rq); | ||
176 | |||
177 | rq_enet_desc_enc(desc, | ||
178 | (u64)dma_addr | VNIC_PADDR_TARGET, | ||
179 | RQ_ENET_TYPE_ONLY_SOP, | ||
180 | (u16)len); | ||
181 | |||
182 | vnic_rq_post(rq, os_buf, 0, dma_addr, len); | ||
183 | } | ||
184 | |||
185 | |||
186 | struct fnic; | ||
187 | |||
188 | int fnic_get_vnic_config(struct fnic *); | ||
189 | int fnic_alloc_vnic_resources(struct fnic *); | ||
190 | void fnic_free_vnic_resources(struct fnic *); | ||
191 | void fnic_get_res_counts(struct fnic *); | ||
192 | int fnic_set_nic_config(struct fnic *fnic, u8 rss_default_cpu, | ||
193 | u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, | ||
194 | u8 rss_enable, u8 tso_ipid_split_en, | ||
195 | u8 ig_vlan_strip_en); | ||
196 | |||
197 | #endif /* _FNIC_RES_H_ */ | ||
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c new file mode 100644 index 000000000000..eabf36502856 --- /dev/null +++ b/drivers/scsi/fnic/fnic_scsi.c | |||
@@ -0,0 +1,1850 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #include <linux/mempool.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/workqueue.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/scatterlist.h> | ||
24 | #include <linux/skbuff.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <linux/if_ether.h> | ||
27 | #include <linux/if_vlan.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <scsi/scsi.h> | ||
30 | #include <scsi/scsi_host.h> | ||
31 | #include <scsi/scsi_device.h> | ||
32 | #include <scsi/scsi_cmnd.h> | ||
33 | #include <scsi/scsi_tcq.h> | ||
34 | #include <scsi/fc/fc_els.h> | ||
35 | #include <scsi/fc/fc_fcoe.h> | ||
36 | #include <scsi/libfc.h> | ||
37 | #include <scsi/fc_frame.h> | ||
38 | #include "fnic_io.h" | ||
39 | #include "fnic.h" | ||
40 | |||
41 | const char *fnic_state_str[] = { | ||
42 | [FNIC_IN_FC_MODE] = "FNIC_IN_FC_MODE", | ||
43 | [FNIC_IN_FC_TRANS_ETH_MODE] = "FNIC_IN_FC_TRANS_ETH_MODE", | ||
44 | [FNIC_IN_ETH_MODE] = "FNIC_IN_ETH_MODE", | ||
45 | [FNIC_IN_ETH_TRANS_FC_MODE] = "FNIC_IN_ETH_TRANS_FC_MODE", | ||
46 | }; | ||
47 | |||
48 | static const char *fnic_ioreq_state_str[] = { | ||
49 | [FNIC_IOREQ_CMD_PENDING] = "FNIC_IOREQ_CMD_PENDING", | ||
50 | [FNIC_IOREQ_ABTS_PENDING] = "FNIC_IOREQ_ABTS_PENDING", | ||
51 | [FNIC_IOREQ_ABTS_COMPLETE] = "FNIC_IOREQ_ABTS_COMPLETE", | ||
52 | [FNIC_IOREQ_CMD_COMPLETE] = "FNIC_IOREQ_CMD_COMPLETE", | ||
53 | }; | ||
54 | |||
55 | static const char *fcpio_status_str[] = { | ||
56 | [FCPIO_SUCCESS] = "FCPIO_SUCCESS", /*0x0*/ | ||
57 | [FCPIO_INVALID_HEADER] = "FCPIO_INVALID_HEADER", | ||
58 | [FCPIO_OUT_OF_RESOURCE] = "FCPIO_OUT_OF_RESOURCE", | ||
59 | [FCPIO_INVALID_PARAM] = "FCPIO_INVALID_PARAM]", | ||
60 | [FCPIO_REQ_NOT_SUPPORTED] = "FCPIO_REQ_NOT_SUPPORTED", | ||
61 | [FCPIO_IO_NOT_FOUND] = "FCPIO_IO_NOT_FOUND", | ||
62 | [FCPIO_ABORTED] = "FCPIO_ABORTED", /*0x41*/ | ||
63 | [FCPIO_TIMEOUT] = "FCPIO_TIMEOUT", | ||
64 | [FCPIO_SGL_INVALID] = "FCPIO_SGL_INVALID", | ||
65 | [FCPIO_MSS_INVALID] = "FCPIO_MSS_INVALID", | ||
66 | [FCPIO_DATA_CNT_MISMATCH] = "FCPIO_DATA_CNT_MISMATCH", | ||
67 | [FCPIO_FW_ERR] = "FCPIO_FW_ERR", | ||
68 | [FCPIO_ITMF_REJECTED] = "FCPIO_ITMF_REJECTED", | ||
69 | [FCPIO_ITMF_FAILED] = "FCPIO_ITMF_FAILED", | ||
70 | [FCPIO_ITMF_INCORRECT_LUN] = "FCPIO_ITMF_INCORRECT_LUN", | ||
71 | [FCPIO_CMND_REJECTED] = "FCPIO_CMND_REJECTED", | ||
72 | [FCPIO_NO_PATH_AVAIL] = "FCPIO_NO_PATH_AVAIL", | ||
73 | [FCPIO_PATH_FAILED] = "FCPIO_PATH_FAILED", | ||
74 | [FCPIO_LUNMAP_CHNG_PEND] = "FCPIO_LUNHMAP_CHNG_PEND", | ||
75 | }; | ||
76 | |||
77 | const char *fnic_state_to_str(unsigned int state) | ||
78 | { | ||
79 | if (state >= ARRAY_SIZE(fnic_state_str) || !fnic_state_str[state]) | ||
80 | return "unknown"; | ||
81 | |||
82 | return fnic_state_str[state]; | ||
83 | } | ||
84 | |||
85 | static const char *fnic_ioreq_state_to_str(unsigned int state) | ||
86 | { | ||
87 | if (state >= ARRAY_SIZE(fnic_ioreq_state_str) || | ||
88 | !fnic_ioreq_state_str[state]) | ||
89 | return "unknown"; | ||
90 | |||
91 | return fnic_ioreq_state_str[state]; | ||
92 | } | ||
93 | |||
94 | static const char *fnic_fcpio_status_to_str(unsigned int status) | ||
95 | { | ||
96 | if (status >= ARRAY_SIZE(fcpio_status_str) || !fcpio_status_str[status]) | ||
97 | return "unknown"; | ||
98 | |||
99 | return fcpio_status_str[status]; | ||
100 | } | ||
101 | |||
102 | static void fnic_cleanup_io(struct fnic *fnic, int exclude_id); | ||
103 | |||
104 | static inline spinlock_t *fnic_io_lock_hash(struct fnic *fnic, | ||
105 | struct scsi_cmnd *sc) | ||
106 | { | ||
107 | u32 hash = sc->request->tag & (FNIC_IO_LOCKS - 1); | ||
108 | |||
109 | return &fnic->io_req_lock[hash]; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Unmap the data buffer and sense buffer for an io_req, | ||
114 | * also unmap and free the device-private scatter/gather list. | ||
115 | */ | ||
116 | static void fnic_release_ioreq_buf(struct fnic *fnic, | ||
117 | struct fnic_io_req *io_req, | ||
118 | struct scsi_cmnd *sc) | ||
119 | { | ||
120 | if (io_req->sgl_list_pa) | ||
121 | pci_unmap_single(fnic->pdev, io_req->sgl_list_pa, | ||
122 | sizeof(io_req->sgl_list[0]) * io_req->sgl_cnt, | ||
123 | PCI_DMA_TODEVICE); | ||
124 | scsi_dma_unmap(sc); | ||
125 | |||
126 | if (io_req->sgl_cnt) | ||
127 | mempool_free(io_req->sgl_list_alloc, | ||
128 | fnic->io_sgl_pool[io_req->sgl_type]); | ||
129 | if (io_req->sense_buf_pa) | ||
130 | pci_unmap_single(fnic->pdev, io_req->sense_buf_pa, | ||
131 | SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE); | ||
132 | } | ||
133 | |||
134 | /* Free up Copy Wq descriptors. Called with copy_wq lock held */ | ||
135 | static int free_wq_copy_descs(struct fnic *fnic, struct vnic_wq_copy *wq) | ||
136 | { | ||
137 | /* if no Ack received from firmware, then nothing to clean */ | ||
138 | if (!fnic->fw_ack_recd[0]) | ||
139 | return 1; | ||
140 | |||
141 | /* | ||
142 | * Update desc_available count based on number of freed descriptors | ||
143 | * Account for wraparound | ||
144 | */ | ||
145 | if (wq->to_clean_index <= fnic->fw_ack_index[0]) | ||
146 | wq->ring.desc_avail += (fnic->fw_ack_index[0] | ||
147 | - wq->to_clean_index + 1); | ||
148 | else | ||
149 | wq->ring.desc_avail += (wq->ring.desc_count | ||
150 | - wq->to_clean_index | ||
151 | + fnic->fw_ack_index[0] + 1); | ||
152 | |||
153 | /* | ||
154 | * just bump clean index to ack_index+1 accounting for wraparound | ||
155 | * this will essentially free up all descriptors between | ||
156 | * to_clean_index and fw_ack_index, both inclusive | ||
157 | */ | ||
158 | wq->to_clean_index = | ||
159 | (fnic->fw_ack_index[0] + 1) % wq->ring.desc_count; | ||
160 | |||
161 | /* we have processed the acks received so far */ | ||
162 | fnic->fw_ack_recd[0] = 0; | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | |||
167 | /* | ||
168 | * fnic_fw_reset_handler | ||
169 | * Routine to send reset msg to fw | ||
170 | */ | ||
171 | int fnic_fw_reset_handler(struct fnic *fnic) | ||
172 | { | ||
173 | struct vnic_wq_copy *wq = &fnic->wq_copy[0]; | ||
174 | int ret = 0; | ||
175 | unsigned long flags; | ||
176 | |||
177 | spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); | ||
178 | |||
179 | if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) | ||
180 | free_wq_copy_descs(fnic, wq); | ||
181 | |||
182 | if (!vnic_wq_copy_desc_avail(wq)) | ||
183 | ret = -EAGAIN; | ||
184 | else | ||
185 | fnic_queue_wq_copy_desc_fw_reset(wq, SCSI_NO_TAG); | ||
186 | |||
187 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); | ||
188 | |||
189 | if (!ret) | ||
190 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
191 | "Issued fw reset\n"); | ||
192 | else | ||
193 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
194 | "Failed to issue fw reset\n"); | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | |||
199 | /* | ||
200 | * fnic_flogi_reg_handler | ||
201 | * Routine to send flogi register msg to fw | ||
202 | */ | ||
203 | int fnic_flogi_reg_handler(struct fnic *fnic) | ||
204 | { | ||
205 | struct vnic_wq_copy *wq = &fnic->wq_copy[0]; | ||
206 | u8 gw_mac[ETH_ALEN]; | ||
207 | int ret = 0; | ||
208 | unsigned long flags; | ||
209 | |||
210 | spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); | ||
211 | |||
212 | if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) | ||
213 | free_wq_copy_descs(fnic, wq); | ||
214 | |||
215 | if (!vnic_wq_copy_desc_avail(wq)) { | ||
216 | ret = -EAGAIN; | ||
217 | goto flogi_reg_ioreq_end; | ||
218 | } | ||
219 | |||
220 | if (fnic->fcoui_mode) | ||
221 | memset(gw_mac, 0xff, ETH_ALEN); | ||
222 | else | ||
223 | memcpy(gw_mac, fnic->dest_addr, ETH_ALEN); | ||
224 | |||
225 | fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG, | ||
226 | FCPIO_FLOGI_REG_GW_DEST, | ||
227 | fnic->s_id, | ||
228 | gw_mac); | ||
229 | |||
230 | flogi_reg_ioreq_end: | ||
231 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); | ||
232 | |||
233 | if (!ret) | ||
234 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
235 | "flog reg issued\n"); | ||
236 | |||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * fnic_queue_wq_copy_desc | ||
242 | * Routine to enqueue a wq copy desc | ||
243 | */ | ||
244 | static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, | ||
245 | struct vnic_wq_copy *wq, | ||
246 | struct fnic_io_req *io_req, | ||
247 | struct scsi_cmnd *sc, | ||
248 | u32 sg_count) | ||
249 | { | ||
250 | struct scatterlist *sg; | ||
251 | struct fc_rport *rport = starget_to_rport(scsi_target(sc->device)); | ||
252 | struct fc_rport_libfc_priv *rp = rport->dd_data; | ||
253 | struct host_sg_desc *desc; | ||
254 | u8 pri_tag = 0; | ||
255 | unsigned int i; | ||
256 | unsigned long intr_flags; | ||
257 | int flags; | ||
258 | u8 exch_flags; | ||
259 | struct scsi_lun fc_lun; | ||
260 | char msg[2]; | ||
261 | |||
262 | if (sg_count) { | ||
263 | BUG_ON(sg_count < 0); | ||
264 | BUG_ON(sg_count > FNIC_MAX_SG_DESC_CNT); | ||
265 | |||
266 | /* For each SGE, create a device desc entry */ | ||
267 | desc = io_req->sgl_list; | ||
268 | for_each_sg(scsi_sglist(sc), sg, sg_count, i) { | ||
269 | desc->addr = cpu_to_le64(sg_dma_address(sg)); | ||
270 | desc->len = cpu_to_le32(sg_dma_len(sg)); | ||
271 | desc->_resvd = 0; | ||
272 | desc++; | ||
273 | } | ||
274 | |||
275 | io_req->sgl_list_pa = pci_map_single | ||
276 | (fnic->pdev, | ||
277 | io_req->sgl_list, | ||
278 | sizeof(io_req->sgl_list[0]) * sg_count, | ||
279 | PCI_DMA_TODEVICE); | ||
280 | } | ||
281 | |||
282 | io_req->sense_buf_pa = pci_map_single(fnic->pdev, | ||
283 | sc->sense_buffer, | ||
284 | SCSI_SENSE_BUFFERSIZE, | ||
285 | PCI_DMA_FROMDEVICE); | ||
286 | |||
287 | int_to_scsilun(sc->device->lun, &fc_lun); | ||
288 | |||
289 | pri_tag = FCPIO_ICMND_PTA_SIMPLE; | ||
290 | msg[0] = MSG_SIMPLE_TAG; | ||
291 | scsi_populate_tag_msg(sc, msg); | ||
292 | if (msg[0] == MSG_ORDERED_TAG) | ||
293 | pri_tag = FCPIO_ICMND_PTA_ORDERED; | ||
294 | |||
295 | /* Enqueue the descriptor in the Copy WQ */ | ||
296 | spin_lock_irqsave(&fnic->wq_copy_lock[0], intr_flags); | ||
297 | |||
298 | if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) | ||
299 | free_wq_copy_descs(fnic, wq); | ||
300 | |||
301 | if (unlikely(!vnic_wq_copy_desc_avail(wq))) { | ||
302 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags); | ||
303 | return SCSI_MLQUEUE_HOST_BUSY; | ||
304 | } | ||
305 | |||
306 | flags = 0; | ||
307 | if (sc->sc_data_direction == DMA_FROM_DEVICE) | ||
308 | flags = FCPIO_ICMND_RDDATA; | ||
309 | else if (sc->sc_data_direction == DMA_TO_DEVICE) | ||
310 | flags = FCPIO_ICMND_WRDATA; | ||
311 | |||
312 | exch_flags = 0; | ||
313 | if ((fnic->config.flags & VFCF_FCP_SEQ_LVL_ERR) && | ||
314 | (rp->flags & FC_RP_FLAGS_RETRY)) | ||
315 | exch_flags |= FCPIO_ICMND_SRFLAG_RETRY; | ||
316 | |||
317 | fnic_queue_wq_copy_desc_icmnd_16(wq, sc->request->tag, | ||
318 | 0, exch_flags, io_req->sgl_cnt, | ||
319 | SCSI_SENSE_BUFFERSIZE, | ||
320 | io_req->sgl_list_pa, | ||
321 | io_req->sense_buf_pa, | ||
322 | 0, /* scsi cmd ref, always 0 */ | ||
323 | pri_tag, /* scsi pri and tag */ | ||
324 | flags, /* command flags */ | ||
325 | sc->cmnd, scsi_bufflen(sc), | ||
326 | fc_lun.scsi_lun, io_req->port_id, | ||
327 | rport->maxframe_size, rp->r_a_tov, | ||
328 | rp->e_d_tov); | ||
329 | |||
330 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags); | ||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * fnic_queuecommand | ||
336 | * Routine to send a scsi cdb | ||
337 | * Called with host_lock held and interrupts disabled. | ||
338 | */ | ||
339 | int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | ||
340 | { | ||
341 | struct fc_lport *lp; | ||
342 | struct fc_rport *rport; | ||
343 | struct fnic_io_req *io_req; | ||
344 | struct fnic *fnic; | ||
345 | struct vnic_wq_copy *wq; | ||
346 | int ret; | ||
347 | u32 sg_count; | ||
348 | unsigned long flags; | ||
349 | unsigned long ptr; | ||
350 | |||
351 | rport = starget_to_rport(scsi_target(sc->device)); | ||
352 | ret = fc_remote_port_chkready(rport); | ||
353 | if (ret) { | ||
354 | sc->result = ret; | ||
355 | done(sc); | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | lp = shost_priv(sc->device->host); | ||
360 | if (lp->state != LPORT_ST_READY || !(lp->link_up)) | ||
361 | return SCSI_MLQUEUE_HOST_BUSY; | ||
362 | |||
363 | /* | ||
364 | * Release host lock, use driver resource specific locks from here. | ||
365 | * Don't re-enable interrupts in case they were disabled prior to the | ||
366 | * caller disabling them. | ||
367 | */ | ||
368 | spin_unlock(lp->host->host_lock); | ||
369 | |||
370 | /* Get a new io_req for this SCSI IO */ | ||
371 | fnic = lport_priv(lp); | ||
372 | |||
373 | io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC); | ||
374 | if (!io_req) { | ||
375 | ret = SCSI_MLQUEUE_HOST_BUSY; | ||
376 | goto out; | ||
377 | } | ||
378 | memset(io_req, 0, sizeof(*io_req)); | ||
379 | |||
380 | /* Map the data buffer */ | ||
381 | sg_count = scsi_dma_map(sc); | ||
382 | if (sg_count < 0) { | ||
383 | mempool_free(io_req, fnic->io_req_pool); | ||
384 | goto out; | ||
385 | } | ||
386 | |||
387 | /* Determine the type of scatter/gather list we need */ | ||
388 | io_req->sgl_cnt = sg_count; | ||
389 | io_req->sgl_type = FNIC_SGL_CACHE_DFLT; | ||
390 | if (sg_count > FNIC_DFLT_SG_DESC_CNT) | ||
391 | io_req->sgl_type = FNIC_SGL_CACHE_MAX; | ||
392 | |||
393 | if (sg_count) { | ||
394 | io_req->sgl_list = | ||
395 | mempool_alloc(fnic->io_sgl_pool[io_req->sgl_type], | ||
396 | GFP_ATOMIC | GFP_DMA); | ||
397 | if (!io_req->sgl_list) { | ||
398 | ret = SCSI_MLQUEUE_HOST_BUSY; | ||
399 | scsi_dma_unmap(sc); | ||
400 | mempool_free(io_req, fnic->io_req_pool); | ||
401 | goto out; | ||
402 | } | ||
403 | |||
404 | /* Cache sgl list allocated address before alignment */ | ||
405 | io_req->sgl_list_alloc = io_req->sgl_list; | ||
406 | ptr = (unsigned long) io_req->sgl_list; | ||
407 | if (ptr % FNIC_SG_DESC_ALIGN) { | ||
408 | io_req->sgl_list = (struct host_sg_desc *) | ||
409 | (((unsigned long) ptr | ||
410 | + FNIC_SG_DESC_ALIGN - 1) | ||
411 | & ~(FNIC_SG_DESC_ALIGN - 1)); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | /* initialize rest of io_req */ | ||
416 | io_req->port_id = rport->port_id; | ||
417 | CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; | ||
418 | CMD_SP(sc) = (char *)io_req; | ||
419 | sc->scsi_done = done; | ||
420 | |||
421 | /* create copy wq desc and enqueue it */ | ||
422 | wq = &fnic->wq_copy[0]; | ||
423 | ret = fnic_queue_wq_copy_desc(fnic, wq, io_req, sc, sg_count); | ||
424 | if (ret) { | ||
425 | /* | ||
426 | * In case another thread cancelled the request, | ||
427 | * refetch the pointer under the lock. | ||
428 | */ | ||
429 | spinlock_t *io_lock = fnic_io_lock_hash(fnic, sc); | ||
430 | |||
431 | spin_lock_irqsave(io_lock, flags); | ||
432 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
433 | CMD_SP(sc) = NULL; | ||
434 | CMD_STATE(sc) = FNIC_IOREQ_CMD_COMPLETE; | ||
435 | spin_unlock_irqrestore(io_lock, flags); | ||
436 | if (io_req) { | ||
437 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
438 | mempool_free(io_req, fnic->io_req_pool); | ||
439 | } | ||
440 | } | ||
441 | out: | ||
442 | /* acquire host lock before returning to SCSI */ | ||
443 | spin_lock(lp->host->host_lock); | ||
444 | return ret; | ||
445 | } | ||
446 | |||
447 | /* | ||
448 | * fnic_fcpio_fw_reset_cmpl_handler | ||
449 | * Routine to handle fw reset completion | ||
450 | */ | ||
451 | static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic, | ||
452 | struct fcpio_fw_req *desc) | ||
453 | { | ||
454 | u8 type; | ||
455 | u8 hdr_status; | ||
456 | struct fcpio_tag tag; | ||
457 | int ret = 0; | ||
458 | struct fc_frame *flogi; | ||
459 | unsigned long flags; | ||
460 | |||
461 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); | ||
462 | |||
463 | /* Clean up all outstanding io requests */ | ||
464 | fnic_cleanup_io(fnic, SCSI_NO_TAG); | ||
465 | |||
466 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
467 | |||
468 | flogi = fnic->flogi; | ||
469 | fnic->flogi = NULL; | ||
470 | |||
471 | /* fnic should be in FC_TRANS_ETH_MODE */ | ||
472 | if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) { | ||
473 | /* Check status of reset completion */ | ||
474 | if (!hdr_status) { | ||
475 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
476 | "reset cmpl success\n"); | ||
477 | /* Ready to send flogi out */ | ||
478 | fnic->state = FNIC_IN_ETH_MODE; | ||
479 | } else { | ||
480 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
481 | fnic->lport->host, | ||
482 | "fnic fw_reset : failed %s\n", | ||
483 | fnic_fcpio_status_to_str(hdr_status)); | ||
484 | |||
485 | /* | ||
486 | * Unable to change to eth mode, cannot send out flogi | ||
487 | * Change state to fc mode, so that subsequent Flogi | ||
488 | * requests from libFC will cause more attempts to | ||
489 | * reset the firmware. Free the cached flogi | ||
490 | */ | ||
491 | fnic->state = FNIC_IN_FC_MODE; | ||
492 | ret = -1; | ||
493 | } | ||
494 | } else { | ||
495 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
496 | fnic->lport->host, | ||
497 | "Unexpected state %s while processing" | ||
498 | " reset cmpl\n", fnic_state_to_str(fnic->state)); | ||
499 | ret = -1; | ||
500 | } | ||
501 | |||
502 | /* Thread removing device blocks till firmware reset is complete */ | ||
503 | if (fnic->remove_wait) | ||
504 | complete(fnic->remove_wait); | ||
505 | |||
506 | /* | ||
507 | * If fnic is being removed, or fw reset failed | ||
508 | * free the flogi frame. Else, send it out | ||
509 | */ | ||
510 | if (fnic->remove_wait || ret) { | ||
511 | fnic->flogi_oxid = FC_XID_UNKNOWN; | ||
512 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
513 | if (flogi) | ||
514 | dev_kfree_skb_irq(fp_skb(flogi)); | ||
515 | goto reset_cmpl_handler_end; | ||
516 | } | ||
517 | |||
518 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
519 | |||
520 | if (flogi) | ||
521 | ret = fnic_send_frame(fnic, flogi); | ||
522 | |||
523 | reset_cmpl_handler_end: | ||
524 | return ret; | ||
525 | } | ||
526 | |||
527 | /* | ||
528 | * fnic_fcpio_flogi_reg_cmpl_handler | ||
529 | * Routine to handle flogi register completion | ||
530 | */ | ||
531 | static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic, | ||
532 | struct fcpio_fw_req *desc) | ||
533 | { | ||
534 | u8 type; | ||
535 | u8 hdr_status; | ||
536 | struct fcpio_tag tag; | ||
537 | int ret = 0; | ||
538 | struct fc_frame *flogi_resp = NULL; | ||
539 | unsigned long flags; | ||
540 | struct sk_buff *skb; | ||
541 | |||
542 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); | ||
543 | |||
544 | /* Update fnic state based on status of flogi reg completion */ | ||
545 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
546 | |||
547 | flogi_resp = fnic->flogi_resp; | ||
548 | fnic->flogi_resp = NULL; | ||
549 | |||
550 | if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) { | ||
551 | |||
552 | /* Check flogi registration completion status */ | ||
553 | if (!hdr_status) { | ||
554 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
555 | "flog reg succeeded\n"); | ||
556 | fnic->state = FNIC_IN_FC_MODE; | ||
557 | } else { | ||
558 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
559 | fnic->lport->host, | ||
560 | "fnic flogi reg :failed %s\n", | ||
561 | fnic_fcpio_status_to_str(hdr_status)); | ||
562 | fnic->state = FNIC_IN_ETH_MODE; | ||
563 | ret = -1; | ||
564 | } | ||
565 | } else { | ||
566 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
567 | "Unexpected fnic state %s while" | ||
568 | " processing flogi reg completion\n", | ||
569 | fnic_state_to_str(fnic->state)); | ||
570 | ret = -1; | ||
571 | } | ||
572 | |||
573 | /* Successful flogi reg cmpl, pass frame to LibFC */ | ||
574 | if (!ret && flogi_resp) { | ||
575 | if (fnic->stop_rx_link_events) { | ||
576 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
577 | goto reg_cmpl_handler_end; | ||
578 | } | ||
579 | skb = (struct sk_buff *)flogi_resp; | ||
580 | /* Use fr_flags to indicate whether flogi resp or not */ | ||
581 | fr_flags(flogi_resp) = 1; | ||
582 | fr_dev(flogi_resp) = fnic->lport; | ||
583 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
584 | |||
585 | skb_queue_tail(&fnic->frame_queue, skb); | ||
586 | queue_work(fnic_event_queue, &fnic->frame_work); | ||
587 | |||
588 | } else { | ||
589 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
590 | if (flogi_resp) | ||
591 | dev_kfree_skb_irq(fp_skb(flogi_resp)); | ||
592 | } | ||
593 | |||
594 | reg_cmpl_handler_end: | ||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | static inline int is_ack_index_in_range(struct vnic_wq_copy *wq, | ||
599 | u16 request_out) | ||
600 | { | ||
601 | if (wq->to_clean_index <= wq->to_use_index) { | ||
602 | /* out of range, stale request_out index */ | ||
603 | if (request_out < wq->to_clean_index || | ||
604 | request_out >= wq->to_use_index) | ||
605 | return 0; | ||
606 | } else { | ||
607 | /* out of range, stale request_out index */ | ||
608 | if (request_out < wq->to_clean_index && | ||
609 | request_out >= wq->to_use_index) | ||
610 | return 0; | ||
611 | } | ||
612 | /* request_out index is in range */ | ||
613 | return 1; | ||
614 | } | ||
615 | |||
616 | |||
617 | /* | ||
618 | * Mark that ack received and store the Ack index. If there are multiple | ||
619 | * acks received before Tx thread cleans it up, the latest value will be | ||
620 | * used which is correct behavior. This state should be in the copy Wq | ||
621 | * instead of in the fnic | ||
622 | */ | ||
623 | static inline void fnic_fcpio_ack_handler(struct fnic *fnic, | ||
624 | unsigned int cq_index, | ||
625 | struct fcpio_fw_req *desc) | ||
626 | { | ||
627 | struct vnic_wq_copy *wq; | ||
628 | u16 request_out = desc->u.ack.request_out; | ||
629 | unsigned long flags; | ||
630 | |||
631 | /* mark the ack state */ | ||
632 | wq = &fnic->wq_copy[cq_index - fnic->raw_wq_count - fnic->rq_count]; | ||
633 | spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); | ||
634 | |||
635 | if (is_ack_index_in_range(wq, request_out)) { | ||
636 | fnic->fw_ack_index[0] = request_out; | ||
637 | fnic->fw_ack_recd[0] = 1; | ||
638 | } | ||
639 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); | ||
640 | } | ||
641 | |||
642 | /* | ||
643 | * fnic_fcpio_icmnd_cmpl_handler | ||
644 | * Routine to handle icmnd completions | ||
645 | */ | ||
646 | static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, | ||
647 | struct fcpio_fw_req *desc) | ||
648 | { | ||
649 | u8 type; | ||
650 | u8 hdr_status; | ||
651 | struct fcpio_tag tag; | ||
652 | u32 id; | ||
653 | u64 xfer_len = 0; | ||
654 | struct fcpio_icmnd_cmpl *icmnd_cmpl; | ||
655 | struct fnic_io_req *io_req; | ||
656 | struct scsi_cmnd *sc; | ||
657 | unsigned long flags; | ||
658 | spinlock_t *io_lock; | ||
659 | |||
660 | /* Decode the cmpl description to get the io_req id */ | ||
661 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); | ||
662 | fcpio_tag_id_dec(&tag, &id); | ||
663 | |||
664 | if (id >= FNIC_MAX_IO_REQ) | ||
665 | return; | ||
666 | |||
667 | sc = scsi_host_find_tag(fnic->lport->host, id); | ||
668 | WARN_ON_ONCE(!sc); | ||
669 | if (!sc) | ||
670 | return; | ||
671 | |||
672 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
673 | spin_lock_irqsave(io_lock, flags); | ||
674 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
675 | WARN_ON_ONCE(!io_req); | ||
676 | if (!io_req) { | ||
677 | spin_unlock_irqrestore(io_lock, flags); | ||
678 | return; | ||
679 | } | ||
680 | |||
681 | /* firmware completed the io */ | ||
682 | io_req->io_completed = 1; | ||
683 | |||
684 | /* | ||
685 | * if SCSI-ML has already issued abort on this command, | ||
686 | * ignore completion of the IO. The abts path will clean it up | ||
687 | */ | ||
688 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { | ||
689 | spin_unlock_irqrestore(io_lock, flags); | ||
690 | return; | ||
691 | } | ||
692 | |||
693 | /* Mark the IO as complete */ | ||
694 | CMD_STATE(sc) = FNIC_IOREQ_CMD_COMPLETE; | ||
695 | |||
696 | icmnd_cmpl = &desc->u.icmnd_cmpl; | ||
697 | |||
698 | switch (hdr_status) { | ||
699 | case FCPIO_SUCCESS: | ||
700 | sc->result = (DID_OK << 16) | icmnd_cmpl->scsi_status; | ||
701 | xfer_len = scsi_bufflen(sc); | ||
702 | scsi_set_resid(sc, icmnd_cmpl->residual); | ||
703 | |||
704 | if (icmnd_cmpl->flags & FCPIO_ICMND_CMPL_RESID_UNDER) | ||
705 | xfer_len -= icmnd_cmpl->residual; | ||
706 | |||
707 | /* | ||
708 | * If queue_full, then try to reduce queue depth for all | ||
709 | * LUNS on the target. Todo: this should be accompanied | ||
710 | * by a periodic queue_depth rampup based on successful | ||
711 | * IO completion. | ||
712 | */ | ||
713 | if (icmnd_cmpl->scsi_status == QUEUE_FULL) { | ||
714 | struct scsi_device *t_sdev; | ||
715 | int qd = 0; | ||
716 | |||
717 | shost_for_each_device(t_sdev, sc->device->host) { | ||
718 | if (t_sdev->id != sc->device->id) | ||
719 | continue; | ||
720 | |||
721 | if (t_sdev->queue_depth > 1) { | ||
722 | qd = scsi_track_queue_full | ||
723 | (t_sdev, | ||
724 | t_sdev->queue_depth - 1); | ||
725 | if (qd == -1) | ||
726 | qd = t_sdev->host->cmd_per_lun; | ||
727 | shost_printk(KERN_INFO, | ||
728 | fnic->lport->host, | ||
729 | "scsi[%d:%d:%d:%d" | ||
730 | "] queue full detected," | ||
731 | "new depth = %d\n", | ||
732 | t_sdev->host->host_no, | ||
733 | t_sdev->channel, | ||
734 | t_sdev->id, t_sdev->lun, | ||
735 | t_sdev->queue_depth); | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | break; | ||
740 | |||
741 | case FCPIO_TIMEOUT: /* request was timed out */ | ||
742 | sc->result = (DID_TIME_OUT << 16) | icmnd_cmpl->scsi_status; | ||
743 | break; | ||
744 | |||
745 | case FCPIO_ABORTED: /* request was aborted */ | ||
746 | sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status; | ||
747 | break; | ||
748 | |||
749 | case FCPIO_DATA_CNT_MISMATCH: /* recv/sent more/less data than exp. */ | ||
750 | scsi_set_resid(sc, icmnd_cmpl->residual); | ||
751 | sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status; | ||
752 | break; | ||
753 | |||
754 | case FCPIO_OUT_OF_RESOURCE: /* out of resources to complete request */ | ||
755 | sc->result = (DID_REQUEUE << 16) | icmnd_cmpl->scsi_status; | ||
756 | break; | ||
757 | case FCPIO_INVALID_HEADER: /* header contains invalid data */ | ||
758 | case FCPIO_INVALID_PARAM: /* some parameter in request invalid */ | ||
759 | case FCPIO_REQ_NOT_SUPPORTED:/* request type is not supported */ | ||
760 | case FCPIO_IO_NOT_FOUND: /* requested I/O was not found */ | ||
761 | case FCPIO_SGL_INVALID: /* request was aborted due to sgl error */ | ||
762 | case FCPIO_MSS_INVALID: /* request was aborted due to mss error */ | ||
763 | case FCPIO_FW_ERR: /* request was terminated due fw error */ | ||
764 | default: | ||
765 | shost_printk(KERN_ERR, fnic->lport->host, "hdr status = %s\n", | ||
766 | fnic_fcpio_status_to_str(hdr_status)); | ||
767 | sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status; | ||
768 | break; | ||
769 | } | ||
770 | |||
771 | /* Break link with the SCSI command */ | ||
772 | CMD_SP(sc) = NULL; | ||
773 | |||
774 | spin_unlock_irqrestore(io_lock, flags); | ||
775 | |||
776 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
777 | |||
778 | mempool_free(io_req, fnic->io_req_pool); | ||
779 | |||
780 | if (sc->sc_data_direction == DMA_FROM_DEVICE) { | ||
781 | fnic->lport->host_stats.fcp_input_requests++; | ||
782 | fnic->fcp_input_bytes += xfer_len; | ||
783 | } else if (sc->sc_data_direction == DMA_TO_DEVICE) { | ||
784 | fnic->lport->host_stats.fcp_output_requests++; | ||
785 | fnic->fcp_output_bytes += xfer_len; | ||
786 | } else | ||
787 | fnic->lport->host_stats.fcp_control_requests++; | ||
788 | |||
789 | /* Call SCSI completion function to complete the IO */ | ||
790 | if (sc->scsi_done) | ||
791 | sc->scsi_done(sc); | ||
792 | |||
793 | } | ||
794 | |||
795 | /* fnic_fcpio_itmf_cmpl_handler | ||
796 | * Routine to handle itmf completions | ||
797 | */ | ||
798 | static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, | ||
799 | struct fcpio_fw_req *desc) | ||
800 | { | ||
801 | u8 type; | ||
802 | u8 hdr_status; | ||
803 | struct fcpio_tag tag; | ||
804 | u32 id; | ||
805 | struct scsi_cmnd *sc; | ||
806 | struct fnic_io_req *io_req; | ||
807 | unsigned long flags; | ||
808 | spinlock_t *io_lock; | ||
809 | |||
810 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); | ||
811 | fcpio_tag_id_dec(&tag, &id); | ||
812 | |||
813 | if ((id & FNIC_TAG_MASK) >= FNIC_MAX_IO_REQ) | ||
814 | return; | ||
815 | |||
816 | sc = scsi_host_find_tag(fnic->lport->host, id & FNIC_TAG_MASK); | ||
817 | WARN_ON_ONCE(!sc); | ||
818 | if (!sc) | ||
819 | return; | ||
820 | |||
821 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
822 | spin_lock_irqsave(io_lock, flags); | ||
823 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
824 | WARN_ON_ONCE(!io_req); | ||
825 | if (!io_req) { | ||
826 | spin_unlock_irqrestore(io_lock, flags); | ||
827 | return; | ||
828 | } | ||
829 | |||
830 | if (id & FNIC_TAG_ABORT) { | ||
831 | /* Completion of abort cmd */ | ||
832 | if (CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING) { | ||
833 | /* This is a late completion. Ignore it */ | ||
834 | spin_unlock_irqrestore(io_lock, flags); | ||
835 | return; | ||
836 | } | ||
837 | CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; | ||
838 | CMD_ABTS_STATUS(sc) = hdr_status; | ||
839 | |||
840 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
841 | "abts cmpl recd. id %d status %s\n", | ||
842 | (int)(id & FNIC_TAG_MASK), | ||
843 | fnic_fcpio_status_to_str(hdr_status)); | ||
844 | |||
845 | /* | ||
846 | * If scsi_eh thread is blocked waiting for abts to complete, | ||
847 | * signal completion to it. IO will be cleaned in the thread | ||
848 | * else clean it in this context | ||
849 | */ | ||
850 | if (io_req->abts_done) { | ||
851 | complete(io_req->abts_done); | ||
852 | spin_unlock_irqrestore(io_lock, flags); | ||
853 | } else { | ||
854 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
855 | "abts cmpl, completing IO\n"); | ||
856 | CMD_SP(sc) = NULL; | ||
857 | sc->result = (DID_ERROR << 16); | ||
858 | |||
859 | spin_unlock_irqrestore(io_lock, flags); | ||
860 | |||
861 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
862 | mempool_free(io_req, fnic->io_req_pool); | ||
863 | if (sc->scsi_done) | ||
864 | sc->scsi_done(sc); | ||
865 | } | ||
866 | |||
867 | } else if (id & FNIC_TAG_DEV_RST) { | ||
868 | /* Completion of device reset */ | ||
869 | CMD_LR_STATUS(sc) = hdr_status; | ||
870 | CMD_STATE(sc) = FNIC_IOREQ_CMD_COMPLETE; | ||
871 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
872 | "dev reset cmpl recd. id %d status %s\n", | ||
873 | (int)(id & FNIC_TAG_MASK), | ||
874 | fnic_fcpio_status_to_str(hdr_status)); | ||
875 | if (io_req->dr_done) | ||
876 | complete(io_req->dr_done); | ||
877 | spin_unlock_irqrestore(io_lock, flags); | ||
878 | |||
879 | } else { | ||
880 | shost_printk(KERN_ERR, fnic->lport->host, | ||
881 | "Unexpected itmf io state %s tag %x\n", | ||
882 | fnic_ioreq_state_to_str(CMD_STATE(sc)), id); | ||
883 | spin_unlock_irqrestore(io_lock, flags); | ||
884 | } | ||
885 | |||
886 | } | ||
887 | |||
888 | /* | ||
889 | * fnic_fcpio_cmpl_handler | ||
890 | * Routine to service the cq for wq_copy | ||
891 | */ | ||
892 | static int fnic_fcpio_cmpl_handler(struct vnic_dev *vdev, | ||
893 | unsigned int cq_index, | ||
894 | struct fcpio_fw_req *desc) | ||
895 | { | ||
896 | struct fnic *fnic = vnic_dev_priv(vdev); | ||
897 | int ret = 0; | ||
898 | |||
899 | switch (desc->hdr.type) { | ||
900 | case FCPIO_ACK: /* fw copied copy wq desc to its queue */ | ||
901 | fnic_fcpio_ack_handler(fnic, cq_index, desc); | ||
902 | break; | ||
903 | |||
904 | case FCPIO_ICMND_CMPL: /* fw completed a command */ | ||
905 | fnic_fcpio_icmnd_cmpl_handler(fnic, desc); | ||
906 | break; | ||
907 | |||
908 | case FCPIO_ITMF_CMPL: /* fw completed itmf (abort cmd, lun reset)*/ | ||
909 | fnic_fcpio_itmf_cmpl_handler(fnic, desc); | ||
910 | break; | ||
911 | |||
912 | case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */ | ||
913 | ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc); | ||
914 | break; | ||
915 | |||
916 | case FCPIO_RESET_CMPL: /* fw completed reset */ | ||
917 | ret = fnic_fcpio_fw_reset_cmpl_handler(fnic, desc); | ||
918 | break; | ||
919 | |||
920 | default: | ||
921 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
922 | "firmware completion type %d\n", | ||
923 | desc->hdr.type); | ||
924 | break; | ||
925 | } | ||
926 | |||
927 | return ret; | ||
928 | } | ||
929 | |||
930 | /* | ||
931 | * fnic_wq_copy_cmpl_handler | ||
932 | * Routine to process wq copy | ||
933 | */ | ||
934 | int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int copy_work_to_do) | ||
935 | { | ||
936 | unsigned int wq_work_done = 0; | ||
937 | unsigned int i, cq_index; | ||
938 | unsigned int cur_work_done; | ||
939 | |||
940 | for (i = 0; i < fnic->wq_copy_count; i++) { | ||
941 | cq_index = i + fnic->raw_wq_count + fnic->rq_count; | ||
942 | cur_work_done = vnic_cq_copy_service(&fnic->cq[cq_index], | ||
943 | fnic_fcpio_cmpl_handler, | ||
944 | copy_work_to_do); | ||
945 | wq_work_done += cur_work_done; | ||
946 | } | ||
947 | return wq_work_done; | ||
948 | } | ||
949 | |||
950 | static void fnic_cleanup_io(struct fnic *fnic, int exclude_id) | ||
951 | { | ||
952 | unsigned int i; | ||
953 | struct fnic_io_req *io_req; | ||
954 | unsigned long flags = 0; | ||
955 | struct scsi_cmnd *sc; | ||
956 | spinlock_t *io_lock; | ||
957 | |||
958 | for (i = 0; i < FNIC_MAX_IO_REQ; i++) { | ||
959 | if (i == exclude_id) | ||
960 | continue; | ||
961 | |||
962 | sc = scsi_host_find_tag(fnic->lport->host, i); | ||
963 | if (!sc) | ||
964 | continue; | ||
965 | |||
966 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
967 | spin_lock_irqsave(io_lock, flags); | ||
968 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
969 | if (!io_req) { | ||
970 | spin_unlock_irqrestore(io_lock, flags); | ||
971 | goto cleanup_scsi_cmd; | ||
972 | } | ||
973 | |||
974 | CMD_SP(sc) = NULL; | ||
975 | |||
976 | spin_unlock_irqrestore(io_lock, flags); | ||
977 | |||
978 | /* | ||
979 | * If there is a scsi_cmnd associated with this io_req, then | ||
980 | * free the corresponding state | ||
981 | */ | ||
982 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
983 | mempool_free(io_req, fnic->io_req_pool); | ||
984 | |||
985 | cleanup_scsi_cmd: | ||
986 | sc->result = DID_TRANSPORT_DISRUPTED << 16; | ||
987 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "fnic_cleanup_io:" | ||
988 | " DID_TRANSPORT_DISRUPTED\n"); | ||
989 | |||
990 | /* Complete the command to SCSI */ | ||
991 | if (sc->scsi_done) | ||
992 | sc->scsi_done(sc); | ||
993 | } | ||
994 | } | ||
995 | |||
996 | void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq, | ||
997 | struct fcpio_host_req *desc) | ||
998 | { | ||
999 | u32 id; | ||
1000 | struct fnic *fnic = vnic_dev_priv(wq->vdev); | ||
1001 | struct fnic_io_req *io_req; | ||
1002 | struct scsi_cmnd *sc; | ||
1003 | unsigned long flags; | ||
1004 | spinlock_t *io_lock; | ||
1005 | |||
1006 | /* get the tag reference */ | ||
1007 | fcpio_tag_id_dec(&desc->hdr.tag, &id); | ||
1008 | id &= FNIC_TAG_MASK; | ||
1009 | |||
1010 | if (id >= FNIC_MAX_IO_REQ) | ||
1011 | return; | ||
1012 | |||
1013 | sc = scsi_host_find_tag(fnic->lport->host, id); | ||
1014 | if (!sc) | ||
1015 | return; | ||
1016 | |||
1017 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1018 | spin_lock_irqsave(io_lock, flags); | ||
1019 | |||
1020 | /* Get the IO context which this desc refers to */ | ||
1021 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1022 | |||
1023 | /* fnic interrupts are turned off by now */ | ||
1024 | |||
1025 | if (!io_req) { | ||
1026 | spin_unlock_irqrestore(io_lock, flags); | ||
1027 | goto wq_copy_cleanup_scsi_cmd; | ||
1028 | } | ||
1029 | |||
1030 | CMD_SP(sc) = NULL; | ||
1031 | |||
1032 | spin_unlock_irqrestore(io_lock, flags); | ||
1033 | |||
1034 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
1035 | mempool_free(io_req, fnic->io_req_pool); | ||
1036 | |||
1037 | wq_copy_cleanup_scsi_cmd: | ||
1038 | sc->result = DID_NO_CONNECT << 16; | ||
1039 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "wq_copy_cleanup_handler:" | ||
1040 | " DID_NO_CONNECT\n"); | ||
1041 | |||
1042 | if (sc->scsi_done) | ||
1043 | sc->scsi_done(sc); | ||
1044 | } | ||
1045 | |||
1046 | static inline int fnic_queue_abort_io_req(struct fnic *fnic, int tag, | ||
1047 | u32 task_req, u8 *fc_lun, | ||
1048 | struct fnic_io_req *io_req) | ||
1049 | { | ||
1050 | struct vnic_wq_copy *wq = &fnic->wq_copy[0]; | ||
1051 | unsigned long flags; | ||
1052 | |||
1053 | spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); | ||
1054 | |||
1055 | if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) | ||
1056 | free_wq_copy_descs(fnic, wq); | ||
1057 | |||
1058 | if (!vnic_wq_copy_desc_avail(wq)) { | ||
1059 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); | ||
1060 | return 1; | ||
1061 | } | ||
1062 | fnic_queue_wq_copy_desc_itmf(wq, tag | FNIC_TAG_ABORT, | ||
1063 | 0, task_req, tag, fc_lun, io_req->port_id, | ||
1064 | fnic->config.ra_tov, fnic->config.ed_tov); | ||
1065 | |||
1066 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); | ||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) | ||
1071 | { | ||
1072 | int tag; | ||
1073 | struct fnic_io_req *io_req; | ||
1074 | spinlock_t *io_lock; | ||
1075 | unsigned long flags; | ||
1076 | struct scsi_cmnd *sc; | ||
1077 | struct scsi_lun fc_lun; | ||
1078 | enum fnic_ioreq_state old_ioreq_state; | ||
1079 | |||
1080 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
1081 | fnic->lport->host, | ||
1082 | "fnic_rport_reset_exch called portid 0x%06x\n", | ||
1083 | port_id); | ||
1084 | |||
1085 | if (fnic->in_remove) | ||
1086 | return; | ||
1087 | |||
1088 | for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) { | ||
1089 | sc = scsi_host_find_tag(fnic->lport->host, tag); | ||
1090 | if (!sc) | ||
1091 | continue; | ||
1092 | |||
1093 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1094 | spin_lock_irqsave(io_lock, flags); | ||
1095 | |||
1096 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1097 | |||
1098 | if (!io_req || io_req->port_id != port_id) { | ||
1099 | spin_unlock_irqrestore(io_lock, flags); | ||
1100 | continue; | ||
1101 | } | ||
1102 | |||
1103 | /* | ||
1104 | * Found IO that is still pending with firmware and | ||
1105 | * belongs to rport that went away | ||
1106 | */ | ||
1107 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { | ||
1108 | spin_unlock_irqrestore(io_lock, flags); | ||
1109 | continue; | ||
1110 | } | ||
1111 | old_ioreq_state = CMD_STATE(sc); | ||
1112 | CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; | ||
1113 | CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; | ||
1114 | |||
1115 | BUG_ON(io_req->abts_done); | ||
1116 | |||
1117 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1118 | "fnic_rport_reset_exch: Issuing abts\n"); | ||
1119 | |||
1120 | spin_unlock_irqrestore(io_lock, flags); | ||
1121 | |||
1122 | /* Now queue the abort command to firmware */ | ||
1123 | int_to_scsilun(sc->device->lun, &fc_lun); | ||
1124 | |||
1125 | if (fnic_queue_abort_io_req(fnic, tag, | ||
1126 | FCPIO_ITMF_ABT_TASK_TERM, | ||
1127 | fc_lun.scsi_lun, io_req)) { | ||
1128 | /* | ||
1129 | * Revert the cmd state back to old state, if | ||
1130 | * it hasnt changed in between. This cmd will get | ||
1131 | * aborted later by scsi_eh, or cleaned up during | ||
1132 | * lun reset | ||
1133 | */ | ||
1134 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1135 | |||
1136 | spin_lock_irqsave(io_lock, flags); | ||
1137 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) | ||
1138 | CMD_STATE(sc) = old_ioreq_state; | ||
1139 | spin_unlock_irqrestore(io_lock, flags); | ||
1140 | } | ||
1141 | } | ||
1142 | |||
1143 | } | ||
1144 | |||
1145 | void fnic_terminate_rport_io(struct fc_rport *rport) | ||
1146 | { | ||
1147 | int tag; | ||
1148 | struct fnic_io_req *io_req; | ||
1149 | spinlock_t *io_lock; | ||
1150 | unsigned long flags; | ||
1151 | struct scsi_cmnd *sc; | ||
1152 | struct scsi_lun fc_lun; | ||
1153 | struct fc_rport_libfc_priv *rdata = rport->dd_data; | ||
1154 | struct fc_lport *lport = rdata->local_port; | ||
1155 | struct fnic *fnic = lport_priv(lport); | ||
1156 | struct fc_rport *cmd_rport; | ||
1157 | enum fnic_ioreq_state old_ioreq_state; | ||
1158 | |||
1159 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
1160 | fnic->lport->host, "fnic_terminate_rport_io called" | ||
1161 | " wwpn 0x%llx, wwnn0x%llx, portid 0x%06x\n", | ||
1162 | rport->port_name, rport->node_name, | ||
1163 | rport->port_id); | ||
1164 | |||
1165 | if (fnic->in_remove) | ||
1166 | return; | ||
1167 | |||
1168 | for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) { | ||
1169 | sc = scsi_host_find_tag(fnic->lport->host, tag); | ||
1170 | if (!sc) | ||
1171 | continue; | ||
1172 | |||
1173 | cmd_rport = starget_to_rport(scsi_target(sc->device)); | ||
1174 | if (rport != cmd_rport) | ||
1175 | continue; | ||
1176 | |||
1177 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1178 | spin_lock_irqsave(io_lock, flags); | ||
1179 | |||
1180 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1181 | |||
1182 | if (!io_req || rport != cmd_rport) { | ||
1183 | spin_unlock_irqrestore(io_lock, flags); | ||
1184 | continue; | ||
1185 | } | ||
1186 | |||
1187 | /* | ||
1188 | * Found IO that is still pending with firmware and | ||
1189 | * belongs to rport that went away | ||
1190 | */ | ||
1191 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { | ||
1192 | spin_unlock_irqrestore(io_lock, flags); | ||
1193 | continue; | ||
1194 | } | ||
1195 | old_ioreq_state = CMD_STATE(sc); | ||
1196 | CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; | ||
1197 | CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; | ||
1198 | |||
1199 | BUG_ON(io_req->abts_done); | ||
1200 | |||
1201 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
1202 | fnic->lport->host, | ||
1203 | "fnic_terminate_rport_io: Issuing abts\n"); | ||
1204 | |||
1205 | spin_unlock_irqrestore(io_lock, flags); | ||
1206 | |||
1207 | /* Now queue the abort command to firmware */ | ||
1208 | int_to_scsilun(sc->device->lun, &fc_lun); | ||
1209 | |||
1210 | if (fnic_queue_abort_io_req(fnic, tag, | ||
1211 | FCPIO_ITMF_ABT_TASK_TERM, | ||
1212 | fc_lun.scsi_lun, io_req)) { | ||
1213 | /* | ||
1214 | * Revert the cmd state back to old state, if | ||
1215 | * it hasnt changed in between. This cmd will get | ||
1216 | * aborted later by scsi_eh, or cleaned up during | ||
1217 | * lun reset | ||
1218 | */ | ||
1219 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1220 | |||
1221 | spin_lock_irqsave(io_lock, flags); | ||
1222 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) | ||
1223 | CMD_STATE(sc) = old_ioreq_state; | ||
1224 | spin_unlock_irqrestore(io_lock, flags); | ||
1225 | } | ||
1226 | } | ||
1227 | |||
1228 | } | ||
1229 | |||
1230 | static void fnic_block_error_handler(struct scsi_cmnd *sc) | ||
1231 | { | ||
1232 | struct Scsi_Host *shost = sc->device->host; | ||
1233 | struct fc_rport *rport = starget_to_rport(scsi_target(sc->device)); | ||
1234 | unsigned long flags; | ||
1235 | |||
1236 | spin_lock_irqsave(shost->host_lock, flags); | ||
1237 | while (rport->port_state == FC_PORTSTATE_BLOCKED) { | ||
1238 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1239 | msleep(1000); | ||
1240 | spin_lock_irqsave(shost->host_lock, flags); | ||
1241 | } | ||
1242 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1243 | |||
1244 | } | ||
1245 | |||
1246 | /* | ||
1247 | * This function is exported to SCSI for sending abort cmnds. | ||
1248 | * A SCSI IO is represented by a io_req in the driver. | ||
1249 | * The ioreq is linked to the SCSI Cmd, thus a link with the ULP's IO. | ||
1250 | */ | ||
1251 | int fnic_abort_cmd(struct scsi_cmnd *sc) | ||
1252 | { | ||
1253 | struct fc_lport *lp; | ||
1254 | struct fnic *fnic; | ||
1255 | struct fnic_io_req *io_req; | ||
1256 | struct fc_rport *rport; | ||
1257 | spinlock_t *io_lock; | ||
1258 | unsigned long flags; | ||
1259 | int ret = SUCCESS; | ||
1260 | u32 task_req; | ||
1261 | struct scsi_lun fc_lun; | ||
1262 | DECLARE_COMPLETION_ONSTACK(tm_done); | ||
1263 | |||
1264 | /* Wait for rport to unblock */ | ||
1265 | fnic_block_error_handler(sc); | ||
1266 | |||
1267 | /* Get local-port, check ready and link up */ | ||
1268 | lp = shost_priv(sc->device->host); | ||
1269 | |||
1270 | fnic = lport_priv(lp); | ||
1271 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
1272 | fnic->lport->host, | ||
1273 | "Abort Cmd called FCID 0x%x, LUN 0x%x TAG %d\n", | ||
1274 | (starget_to_rport(scsi_target(sc->device)))->port_id, | ||
1275 | sc->device->lun, sc->request->tag); | ||
1276 | |||
1277 | if (lp->state != LPORT_ST_READY || !(lp->link_up)) { | ||
1278 | ret = FAILED; | ||
1279 | goto fnic_abort_cmd_end; | ||
1280 | } | ||
1281 | |||
1282 | /* | ||
1283 | * Avoid a race between SCSI issuing the abort and the device | ||
1284 | * completing the command. | ||
1285 | * | ||
1286 | * If the command is already completed by the fw cmpl code, | ||
1287 | * we just return SUCCESS from here. This means that the abort | ||
1288 | * succeeded. In the SCSI ML, since the timeout for command has | ||
1289 | * happened, the completion wont actually complete the command | ||
1290 | * and it will be considered as an aborted command | ||
1291 | * | ||
1292 | * The CMD_SP will not be cleared except while holding io_req_lock. | ||
1293 | */ | ||
1294 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1295 | spin_lock_irqsave(io_lock, flags); | ||
1296 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1297 | if (!io_req) { | ||
1298 | spin_unlock_irqrestore(io_lock, flags); | ||
1299 | goto fnic_abort_cmd_end; | ||
1300 | } | ||
1301 | |||
1302 | io_req->abts_done = &tm_done; | ||
1303 | |||
1304 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { | ||
1305 | spin_unlock_irqrestore(io_lock, flags); | ||
1306 | goto wait_pending; | ||
1307 | } | ||
1308 | /* | ||
1309 | * Command is still pending, need to abort it | ||
1310 | * If the firmware completes the command after this point, | ||
1311 | * the completion wont be done till mid-layer, since abort | ||
1312 | * has already started. | ||
1313 | */ | ||
1314 | CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; | ||
1315 | CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; | ||
1316 | |||
1317 | spin_unlock_irqrestore(io_lock, flags); | ||
1318 | |||
1319 | /* | ||
1320 | * Check readiness of the remote port. If the path to remote | ||
1321 | * port is up, then send abts to the remote port to terminate | ||
1322 | * the IO. Else, just locally terminate the IO in the firmware | ||
1323 | */ | ||
1324 | rport = starget_to_rport(scsi_target(sc->device)); | ||
1325 | if (fc_remote_port_chkready(rport) == 0) | ||
1326 | task_req = FCPIO_ITMF_ABT_TASK; | ||
1327 | else | ||
1328 | task_req = FCPIO_ITMF_ABT_TASK_TERM; | ||
1329 | |||
1330 | /* Now queue the abort command to firmware */ | ||
1331 | int_to_scsilun(sc->device->lun, &fc_lun); | ||
1332 | |||
1333 | if (fnic_queue_abort_io_req(fnic, sc->request->tag, task_req, | ||
1334 | fc_lun.scsi_lun, io_req)) { | ||
1335 | spin_lock_irqsave(io_lock, flags); | ||
1336 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1337 | if (io_req) | ||
1338 | io_req->abts_done = NULL; | ||
1339 | spin_unlock_irqrestore(io_lock, flags); | ||
1340 | ret = FAILED; | ||
1341 | goto fnic_abort_cmd_end; | ||
1342 | } | ||
1343 | |||
1344 | /* | ||
1345 | * We queued an abort IO, wait for its completion. | ||
1346 | * Once the firmware completes the abort command, it will | ||
1347 | * wake up this thread. | ||
1348 | */ | ||
1349 | wait_pending: | ||
1350 | wait_for_completion_timeout(&tm_done, | ||
1351 | msecs_to_jiffies | ||
1352 | (2 * fnic->config.ra_tov + | ||
1353 | fnic->config.ed_tov)); | ||
1354 | |||
1355 | /* Check the abort status */ | ||
1356 | spin_lock_irqsave(io_lock, flags); | ||
1357 | |||
1358 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1359 | if (!io_req) { | ||
1360 | spin_unlock_irqrestore(io_lock, flags); | ||
1361 | ret = FAILED; | ||
1362 | goto fnic_abort_cmd_end; | ||
1363 | } | ||
1364 | io_req->abts_done = NULL; | ||
1365 | |||
1366 | /* fw did not complete abort, timed out */ | ||
1367 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { | ||
1368 | spin_unlock_irqrestore(io_lock, flags); | ||
1369 | ret = FAILED; | ||
1370 | goto fnic_abort_cmd_end; | ||
1371 | } | ||
1372 | |||
1373 | /* | ||
1374 | * firmware completed the abort, check the status, | ||
1375 | * free the io_req irrespective of failure or success | ||
1376 | */ | ||
1377 | if (CMD_ABTS_STATUS(sc) != FCPIO_SUCCESS) | ||
1378 | ret = FAILED; | ||
1379 | |||
1380 | CMD_SP(sc) = NULL; | ||
1381 | |||
1382 | spin_unlock_irqrestore(io_lock, flags); | ||
1383 | |||
1384 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
1385 | mempool_free(io_req, fnic->io_req_pool); | ||
1386 | |||
1387 | fnic_abort_cmd_end: | ||
1388 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1389 | "Returning from abort cmd %s\n", | ||
1390 | (ret == SUCCESS) ? | ||
1391 | "SUCCESS" : "FAILED"); | ||
1392 | return ret; | ||
1393 | } | ||
1394 | |||
1395 | static inline int fnic_queue_dr_io_req(struct fnic *fnic, | ||
1396 | struct scsi_cmnd *sc, | ||
1397 | struct fnic_io_req *io_req) | ||
1398 | { | ||
1399 | struct vnic_wq_copy *wq = &fnic->wq_copy[0]; | ||
1400 | struct scsi_lun fc_lun; | ||
1401 | int ret = 0; | ||
1402 | unsigned long intr_flags; | ||
1403 | |||
1404 | spin_lock_irqsave(&fnic->wq_copy_lock[0], intr_flags); | ||
1405 | |||
1406 | if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) | ||
1407 | free_wq_copy_descs(fnic, wq); | ||
1408 | |||
1409 | if (!vnic_wq_copy_desc_avail(wq)) { | ||
1410 | ret = -EAGAIN; | ||
1411 | goto lr_io_req_end; | ||
1412 | } | ||
1413 | |||
1414 | /* fill in the lun info */ | ||
1415 | int_to_scsilun(sc->device->lun, &fc_lun); | ||
1416 | |||
1417 | fnic_queue_wq_copy_desc_itmf(wq, sc->request->tag | FNIC_TAG_DEV_RST, | ||
1418 | 0, FCPIO_ITMF_LUN_RESET, SCSI_NO_TAG, | ||
1419 | fc_lun.scsi_lun, io_req->port_id, | ||
1420 | fnic->config.ra_tov, fnic->config.ed_tov); | ||
1421 | |||
1422 | lr_io_req_end: | ||
1423 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags); | ||
1424 | |||
1425 | return ret; | ||
1426 | } | ||
1427 | |||
1428 | /* | ||
1429 | * Clean up any pending aborts on the lun | ||
1430 | * For each outstanding IO on this lun, whose abort is not completed by fw, | ||
1431 | * issue a local abort. Wait for abort to complete. Return 0 if all commands | ||
1432 | * successfully aborted, 1 otherwise | ||
1433 | */ | ||
1434 | static int fnic_clean_pending_aborts(struct fnic *fnic, | ||
1435 | struct scsi_cmnd *lr_sc) | ||
1436 | { | ||
1437 | int tag; | ||
1438 | struct fnic_io_req *io_req; | ||
1439 | spinlock_t *io_lock; | ||
1440 | unsigned long flags; | ||
1441 | int ret = 0; | ||
1442 | struct scsi_cmnd *sc; | ||
1443 | struct fc_rport *rport; | ||
1444 | struct scsi_lun fc_lun; | ||
1445 | struct scsi_device *lun_dev = lr_sc->device; | ||
1446 | DECLARE_COMPLETION_ONSTACK(tm_done); | ||
1447 | |||
1448 | for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) { | ||
1449 | sc = scsi_host_find_tag(fnic->lport->host, tag); | ||
1450 | /* | ||
1451 | * ignore this lun reset cmd or cmds that do not belong to | ||
1452 | * this lun | ||
1453 | */ | ||
1454 | if (!sc || sc == lr_sc || sc->device != lun_dev) | ||
1455 | continue; | ||
1456 | |||
1457 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1458 | spin_lock_irqsave(io_lock, flags); | ||
1459 | |||
1460 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1461 | |||
1462 | if (!io_req || sc->device != lun_dev) { | ||
1463 | spin_unlock_irqrestore(io_lock, flags); | ||
1464 | continue; | ||
1465 | } | ||
1466 | |||
1467 | /* | ||
1468 | * Found IO that is still pending with firmware and | ||
1469 | * belongs to the LUN that we are resetting | ||
1470 | */ | ||
1471 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1472 | "Found IO in %s on lun\n", | ||
1473 | fnic_ioreq_state_to_str(CMD_STATE(sc))); | ||
1474 | |||
1475 | BUG_ON(CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING); | ||
1476 | |||
1477 | CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; | ||
1478 | io_req->abts_done = &tm_done; | ||
1479 | spin_unlock_irqrestore(io_lock, flags); | ||
1480 | |||
1481 | /* Now queue the abort command to firmware */ | ||
1482 | int_to_scsilun(sc->device->lun, &fc_lun); | ||
1483 | rport = starget_to_rport(scsi_target(sc->device)); | ||
1484 | |||
1485 | if (fnic_queue_abort_io_req(fnic, tag, | ||
1486 | FCPIO_ITMF_ABT_TASK_TERM, | ||
1487 | fc_lun.scsi_lun, io_req)) { | ||
1488 | spin_lock_irqsave(io_lock, flags); | ||
1489 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1490 | if (io_req) | ||
1491 | io_req->abts_done = NULL; | ||
1492 | spin_unlock_irqrestore(io_lock, flags); | ||
1493 | ret = 1; | ||
1494 | goto clean_pending_aborts_end; | ||
1495 | } | ||
1496 | |||
1497 | wait_for_completion_timeout(&tm_done, | ||
1498 | msecs_to_jiffies | ||
1499 | (fnic->config.ed_tov)); | ||
1500 | |||
1501 | /* Recheck cmd state to check if it is now aborted */ | ||
1502 | spin_lock_irqsave(io_lock, flags); | ||
1503 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1504 | if (!io_req) { | ||
1505 | spin_unlock_irqrestore(io_lock, flags); | ||
1506 | ret = 1; | ||
1507 | goto clean_pending_aborts_end; | ||
1508 | } | ||
1509 | |||
1510 | io_req->abts_done = NULL; | ||
1511 | |||
1512 | /* if abort is still pending with fw, fail */ | ||
1513 | if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { | ||
1514 | spin_unlock_irqrestore(io_lock, flags); | ||
1515 | ret = 1; | ||
1516 | goto clean_pending_aborts_end; | ||
1517 | } | ||
1518 | CMD_SP(sc) = NULL; | ||
1519 | spin_unlock_irqrestore(io_lock, flags); | ||
1520 | |||
1521 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
1522 | mempool_free(io_req, fnic->io_req_pool); | ||
1523 | } | ||
1524 | |||
1525 | clean_pending_aborts_end: | ||
1526 | return ret; | ||
1527 | } | ||
1528 | |||
1529 | /* | ||
1530 | * SCSI Eh thread issues a Lun Reset when one or more commands on a LUN | ||
1531 | * fail to get aborted. It calls driver's eh_device_reset with a SCSI command | ||
1532 | * on the LUN. | ||
1533 | */ | ||
1534 | int fnic_device_reset(struct scsi_cmnd *sc) | ||
1535 | { | ||
1536 | struct fc_lport *lp; | ||
1537 | struct fnic *fnic; | ||
1538 | struct fnic_io_req *io_req; | ||
1539 | struct fc_rport *rport; | ||
1540 | int status; | ||
1541 | int ret = FAILED; | ||
1542 | spinlock_t *io_lock; | ||
1543 | unsigned long flags; | ||
1544 | DECLARE_COMPLETION_ONSTACK(tm_done); | ||
1545 | |||
1546 | /* Wait for rport to unblock */ | ||
1547 | fnic_block_error_handler(sc); | ||
1548 | |||
1549 | /* Get local-port, check ready and link up */ | ||
1550 | lp = shost_priv(sc->device->host); | ||
1551 | |||
1552 | fnic = lport_priv(lp); | ||
1553 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
1554 | fnic->lport->host, | ||
1555 | "Device reset called FCID 0x%x, LUN 0x%x\n", | ||
1556 | (starget_to_rport(scsi_target(sc->device)))->port_id, | ||
1557 | sc->device->lun); | ||
1558 | |||
1559 | |||
1560 | if (lp->state != LPORT_ST_READY || !(lp->link_up)) | ||
1561 | goto fnic_device_reset_end; | ||
1562 | |||
1563 | /* Check if remote port up */ | ||
1564 | rport = starget_to_rport(scsi_target(sc->device)); | ||
1565 | if (fc_remote_port_chkready(rport)) | ||
1566 | goto fnic_device_reset_end; | ||
1567 | |||
1568 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
1569 | spin_lock_irqsave(io_lock, flags); | ||
1570 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1571 | |||
1572 | /* | ||
1573 | * If there is a io_req attached to this command, then use it, | ||
1574 | * else allocate a new one. | ||
1575 | */ | ||
1576 | if (!io_req) { | ||
1577 | io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC); | ||
1578 | if (!io_req) { | ||
1579 | spin_unlock_irqrestore(io_lock, flags); | ||
1580 | goto fnic_device_reset_end; | ||
1581 | } | ||
1582 | memset(io_req, 0, sizeof(*io_req)); | ||
1583 | io_req->port_id = rport->port_id; | ||
1584 | CMD_SP(sc) = (char *)io_req; | ||
1585 | } | ||
1586 | io_req->dr_done = &tm_done; | ||
1587 | CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; | ||
1588 | CMD_LR_STATUS(sc) = FCPIO_INVALID_CODE; | ||
1589 | spin_unlock_irqrestore(io_lock, flags); | ||
1590 | |||
1591 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "TAG %d\n", | ||
1592 | sc->request->tag); | ||
1593 | |||
1594 | /* | ||
1595 | * issue the device reset, if enqueue failed, clean up the ioreq | ||
1596 | * and break assoc with scsi cmd | ||
1597 | */ | ||
1598 | if (fnic_queue_dr_io_req(fnic, sc, io_req)) { | ||
1599 | spin_lock_irqsave(io_lock, flags); | ||
1600 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1601 | if (io_req) | ||
1602 | io_req->dr_done = NULL; | ||
1603 | goto fnic_device_reset_clean; | ||
1604 | } | ||
1605 | |||
1606 | /* | ||
1607 | * Wait on the local completion for LUN reset. The io_req may be | ||
1608 | * freed while we wait since we hold no lock. | ||
1609 | */ | ||
1610 | wait_for_completion_timeout(&tm_done, | ||
1611 | msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT)); | ||
1612 | |||
1613 | spin_lock_irqsave(io_lock, flags); | ||
1614 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1615 | if (!io_req) { | ||
1616 | spin_unlock_irqrestore(io_lock, flags); | ||
1617 | goto fnic_device_reset_end; | ||
1618 | } | ||
1619 | io_req->dr_done = NULL; | ||
1620 | |||
1621 | status = CMD_LR_STATUS(sc); | ||
1622 | spin_unlock_irqrestore(io_lock, flags); | ||
1623 | |||
1624 | /* | ||
1625 | * If lun reset not completed, bail out with failed. io_req | ||
1626 | * gets cleaned up during higher levels of EH | ||
1627 | */ | ||
1628 | if (status == FCPIO_INVALID_CODE) { | ||
1629 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1630 | "Device reset timed out\n"); | ||
1631 | goto fnic_device_reset_end; | ||
1632 | } | ||
1633 | |||
1634 | /* Completed, but not successful, clean up the io_req, return fail */ | ||
1635 | if (status != FCPIO_SUCCESS) { | ||
1636 | spin_lock_irqsave(io_lock, flags); | ||
1637 | FNIC_SCSI_DBG(KERN_DEBUG, | ||
1638 | fnic->lport->host, | ||
1639 | "Device reset completed - failed\n"); | ||
1640 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1641 | goto fnic_device_reset_clean; | ||
1642 | } | ||
1643 | |||
1644 | /* | ||
1645 | * Clean up any aborts on this lun that have still not | ||
1646 | * completed. If any of these fail, then LUN reset fails. | ||
1647 | * clean_pending_aborts cleans all cmds on this lun except | ||
1648 | * the lun reset cmd. If all cmds get cleaned, the lun reset | ||
1649 | * succeeds | ||
1650 | */ | ||
1651 | if (fnic_clean_pending_aborts(fnic, sc)) { | ||
1652 | spin_lock_irqsave(io_lock, flags); | ||
1653 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1654 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1655 | "Device reset failed" | ||
1656 | " since could not abort all IOs\n"); | ||
1657 | goto fnic_device_reset_clean; | ||
1658 | } | ||
1659 | |||
1660 | /* Clean lun reset command */ | ||
1661 | spin_lock_irqsave(io_lock, flags); | ||
1662 | io_req = (struct fnic_io_req *)CMD_SP(sc); | ||
1663 | if (io_req) | ||
1664 | /* Completed, and successful */ | ||
1665 | ret = SUCCESS; | ||
1666 | |||
1667 | fnic_device_reset_clean: | ||
1668 | if (io_req) | ||
1669 | CMD_SP(sc) = NULL; | ||
1670 | |||
1671 | spin_unlock_irqrestore(io_lock, flags); | ||
1672 | |||
1673 | if (io_req) { | ||
1674 | fnic_release_ioreq_buf(fnic, io_req, sc); | ||
1675 | mempool_free(io_req, fnic->io_req_pool); | ||
1676 | } | ||
1677 | |||
1678 | fnic_device_reset_end: | ||
1679 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1680 | "Returning from device reset %s\n", | ||
1681 | (ret == SUCCESS) ? | ||
1682 | "SUCCESS" : "FAILED"); | ||
1683 | return ret; | ||
1684 | } | ||
1685 | |||
1686 | /* Clean up all IOs, clean up libFC local port */ | ||
1687 | int fnic_reset(struct Scsi_Host *shost) | ||
1688 | { | ||
1689 | struct fc_lport *lp; | ||
1690 | struct fnic *fnic; | ||
1691 | int ret = SUCCESS; | ||
1692 | |||
1693 | lp = shost_priv(shost); | ||
1694 | fnic = lport_priv(lp); | ||
1695 | |||
1696 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1697 | "fnic_reset called\n"); | ||
1698 | |||
1699 | /* | ||
1700 | * Reset local port, this will clean up libFC exchanges, | ||
1701 | * reset remote port sessions, and if link is up, begin flogi | ||
1702 | */ | ||
1703 | if (lp->tt.lport_reset(lp)) | ||
1704 | ret = FAILED; | ||
1705 | |||
1706 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1707 | "Returning from fnic reset %s\n", | ||
1708 | (ret == SUCCESS) ? | ||
1709 | "SUCCESS" : "FAILED"); | ||
1710 | |||
1711 | return ret; | ||
1712 | } | ||
1713 | |||
1714 | /* | ||
1715 | * SCSI Error handling calls driver's eh_host_reset if all prior | ||
1716 | * error handling levels return FAILED. If host reset completes | ||
1717 | * successfully, and if link is up, then Fabric login begins. | ||
1718 | * | ||
1719 | * Host Reset is the highest level of error recovery. If this fails, then | ||
1720 | * host is offlined by SCSI. | ||
1721 | * | ||
1722 | */ | ||
1723 | int fnic_host_reset(struct scsi_cmnd *sc) | ||
1724 | { | ||
1725 | int ret; | ||
1726 | unsigned long wait_host_tmo; | ||
1727 | struct Scsi_Host *shost = sc->device->host; | ||
1728 | struct fc_lport *lp = shost_priv(shost); | ||
1729 | |||
1730 | /* | ||
1731 | * If fnic_reset is successful, wait for fabric login to complete | ||
1732 | * scsi-ml tries to send a TUR to every device if host reset is | ||
1733 | * successful, so before returning to scsi, fabric should be up | ||
1734 | */ | ||
1735 | ret = fnic_reset(shost); | ||
1736 | if (ret == SUCCESS) { | ||
1737 | wait_host_tmo = jiffies + FNIC_HOST_RESET_SETTLE_TIME * HZ; | ||
1738 | ret = FAILED; | ||
1739 | while (time_before(jiffies, wait_host_tmo)) { | ||
1740 | if ((lp->state == LPORT_ST_READY) && | ||
1741 | (lp->link_up)) { | ||
1742 | ret = SUCCESS; | ||
1743 | break; | ||
1744 | } | ||
1745 | ssleep(1); | ||
1746 | } | ||
1747 | } | ||
1748 | |||
1749 | return ret; | ||
1750 | } | ||
1751 | |||
1752 | /* | ||
1753 | * This fxn is called from libFC when host is removed | ||
1754 | */ | ||
1755 | void fnic_scsi_abort_io(struct fc_lport *lp) | ||
1756 | { | ||
1757 | int err = 0; | ||
1758 | unsigned long flags; | ||
1759 | enum fnic_state old_state; | ||
1760 | struct fnic *fnic = lport_priv(lp); | ||
1761 | DECLARE_COMPLETION_ONSTACK(remove_wait); | ||
1762 | |||
1763 | /* Issue firmware reset for fnic, wait for reset to complete */ | ||
1764 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
1765 | fnic->remove_wait = &remove_wait; | ||
1766 | old_state = fnic->state; | ||
1767 | fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; | ||
1768 | vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); | ||
1769 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
1770 | |||
1771 | err = fnic_fw_reset_handler(fnic); | ||
1772 | if (err) { | ||
1773 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
1774 | if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) | ||
1775 | fnic->state = old_state; | ||
1776 | fnic->remove_wait = NULL; | ||
1777 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
1778 | return; | ||
1779 | } | ||
1780 | |||
1781 | /* Wait for firmware reset to complete */ | ||
1782 | wait_for_completion_timeout(&remove_wait, | ||
1783 | msecs_to_jiffies(FNIC_RMDEVICE_TIMEOUT)); | ||
1784 | |||
1785 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
1786 | fnic->remove_wait = NULL; | ||
1787 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1788 | "fnic_scsi_abort_io %s\n", | ||
1789 | (fnic->state == FNIC_IN_ETH_MODE) ? | ||
1790 | "SUCCESS" : "FAILED"); | ||
1791 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
1792 | |||
1793 | } | ||
1794 | |||
1795 | /* | ||
1796 | * This fxn called from libFC to clean up driver IO state on link down | ||
1797 | */ | ||
1798 | void fnic_scsi_cleanup(struct fc_lport *lp) | ||
1799 | { | ||
1800 | unsigned long flags; | ||
1801 | enum fnic_state old_state; | ||
1802 | struct fnic *fnic = lport_priv(lp); | ||
1803 | |||
1804 | /* issue fw reset */ | ||
1805 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
1806 | old_state = fnic->state; | ||
1807 | fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; | ||
1808 | vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); | ||
1809 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
1810 | |||
1811 | if (fnic_fw_reset_handler(fnic)) { | ||
1812 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
1813 | if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) | ||
1814 | fnic->state = old_state; | ||
1815 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
1816 | } | ||
1817 | |||
1818 | } | ||
1819 | |||
1820 | void fnic_empty_scsi_cleanup(struct fc_lport *lp) | ||
1821 | { | ||
1822 | } | ||
1823 | |||
1824 | void fnic_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did) | ||
1825 | { | ||
1826 | struct fnic *fnic = lport_priv(lp); | ||
1827 | |||
1828 | /* Non-zero sid, nothing to do */ | ||
1829 | if (sid) | ||
1830 | goto call_fc_exch_mgr_reset; | ||
1831 | |||
1832 | if (did) { | ||
1833 | fnic_rport_exch_reset(fnic, did); | ||
1834 | goto call_fc_exch_mgr_reset; | ||
1835 | } | ||
1836 | |||
1837 | /* | ||
1838 | * sid = 0, did = 0 | ||
1839 | * link down or device being removed | ||
1840 | */ | ||
1841 | if (!fnic->in_remove) | ||
1842 | fnic_scsi_cleanup(lp); | ||
1843 | else | ||
1844 | fnic_scsi_abort_io(lp); | ||
1845 | |||
1846 | /* call libFC exch mgr reset to reset its exchanges */ | ||
1847 | call_fc_exch_mgr_reset: | ||
1848 | fc_exch_mgr_reset(lp, sid, did); | ||
1849 | |||
1850 | } | ||
diff --git a/drivers/scsi/fnic/rq_enet_desc.h b/drivers/scsi/fnic/rq_enet_desc.h new file mode 100644 index 000000000000..92e80ae6b725 --- /dev/null +++ b/drivers/scsi/fnic/rq_enet_desc.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _RQ_ENET_DESC_H_ | ||
19 | #define _RQ_ENET_DESC_H_ | ||
20 | |||
21 | /* Ethernet receive queue descriptor: 16B */ | ||
22 | struct rq_enet_desc { | ||
23 | __le64 address; | ||
24 | __le16 length_type; | ||
25 | u8 reserved[6]; | ||
26 | }; | ||
27 | |||
28 | enum rq_enet_type_types { | ||
29 | RQ_ENET_TYPE_ONLY_SOP = 0, | ||
30 | RQ_ENET_TYPE_NOT_SOP = 1, | ||
31 | RQ_ENET_TYPE_RESV2 = 2, | ||
32 | RQ_ENET_TYPE_RESV3 = 3, | ||
33 | }; | ||
34 | |||
35 | #define RQ_ENET_ADDR_BITS 64 | ||
36 | #define RQ_ENET_LEN_BITS 14 | ||
37 | #define RQ_ENET_LEN_MASK ((1 << RQ_ENET_LEN_BITS) - 1) | ||
38 | #define RQ_ENET_TYPE_BITS 2 | ||
39 | #define RQ_ENET_TYPE_MASK ((1 << RQ_ENET_TYPE_BITS) - 1) | ||
40 | |||
41 | static inline void rq_enet_desc_enc(struct rq_enet_desc *desc, | ||
42 | u64 address, u8 type, u16 length) | ||
43 | { | ||
44 | desc->address = cpu_to_le64(address); | ||
45 | desc->length_type = cpu_to_le16((length & RQ_ENET_LEN_MASK) | | ||
46 | ((type & RQ_ENET_TYPE_MASK) << RQ_ENET_LEN_BITS)); | ||
47 | } | ||
48 | |||
49 | static inline void rq_enet_desc_dec(struct rq_enet_desc *desc, | ||
50 | u64 *address, u8 *type, u16 *length) | ||
51 | { | ||
52 | *address = le64_to_cpu(desc->address); | ||
53 | *length = le16_to_cpu(desc->length_type) & RQ_ENET_LEN_MASK; | ||
54 | *type = (u8)((le16_to_cpu(desc->length_type) >> RQ_ENET_LEN_BITS) & | ||
55 | RQ_ENET_TYPE_MASK); | ||
56 | } | ||
57 | |||
58 | #endif /* _RQ_ENET_DESC_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_cq.c b/drivers/scsi/fnic/vnic_cq.c new file mode 100644 index 000000000000..c5db32eda5ef --- /dev/null +++ b/drivers/scsi/fnic/vnic_cq.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include "vnic_dev.h" | ||
22 | #include "vnic_cq.h" | ||
23 | |||
24 | void vnic_cq_free(struct vnic_cq *cq) | ||
25 | { | ||
26 | vnic_dev_free_desc_ring(cq->vdev, &cq->ring); | ||
27 | |||
28 | cq->ctrl = NULL; | ||
29 | } | ||
30 | |||
31 | int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index, | ||
32 | unsigned int desc_count, unsigned int desc_size) | ||
33 | { | ||
34 | int err; | ||
35 | |||
36 | cq->index = index; | ||
37 | cq->vdev = vdev; | ||
38 | |||
39 | cq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_CQ, index); | ||
40 | if (!cq->ctrl) { | ||
41 | printk(KERN_ERR "Failed to hook CQ[%d] resource\n", index); | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | |||
45 | err = vnic_dev_alloc_desc_ring(vdev, &cq->ring, desc_count, desc_size); | ||
46 | if (err) | ||
47 | return err; | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable, | ||
53 | unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail, | ||
54 | unsigned int cq_tail_color, unsigned int interrupt_enable, | ||
55 | unsigned int cq_entry_enable, unsigned int cq_message_enable, | ||
56 | unsigned int interrupt_offset, u64 cq_message_addr) | ||
57 | { | ||
58 | u64 paddr; | ||
59 | |||
60 | paddr = (u64)cq->ring.base_addr | VNIC_PADDR_TARGET; | ||
61 | writeq(paddr, &cq->ctrl->ring_base); | ||
62 | iowrite32(cq->ring.desc_count, &cq->ctrl->ring_size); | ||
63 | iowrite32(flow_control_enable, &cq->ctrl->flow_control_enable); | ||
64 | iowrite32(color_enable, &cq->ctrl->color_enable); | ||
65 | iowrite32(cq_head, &cq->ctrl->cq_head); | ||
66 | iowrite32(cq_tail, &cq->ctrl->cq_tail); | ||
67 | iowrite32(cq_tail_color, &cq->ctrl->cq_tail_color); | ||
68 | iowrite32(interrupt_enable, &cq->ctrl->interrupt_enable); | ||
69 | iowrite32(cq_entry_enable, &cq->ctrl->cq_entry_enable); | ||
70 | iowrite32(cq_message_enable, &cq->ctrl->cq_message_enable); | ||
71 | iowrite32(interrupt_offset, &cq->ctrl->interrupt_offset); | ||
72 | writeq(cq_message_addr, &cq->ctrl->cq_message_addr); | ||
73 | } | ||
74 | |||
75 | void vnic_cq_clean(struct vnic_cq *cq) | ||
76 | { | ||
77 | cq->to_clean = 0; | ||
78 | cq->last_color = 0; | ||
79 | |||
80 | iowrite32(0, &cq->ctrl->cq_head); | ||
81 | iowrite32(0, &cq->ctrl->cq_tail); | ||
82 | iowrite32(1, &cq->ctrl->cq_tail_color); | ||
83 | |||
84 | vnic_dev_clear_desc_ring(&cq->ring); | ||
85 | } | ||
diff --git a/drivers/scsi/fnic/vnic_cq.h b/drivers/scsi/fnic/vnic_cq.h new file mode 100644 index 000000000000..4ede6809fb1e --- /dev/null +++ b/drivers/scsi/fnic/vnic_cq.h | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_CQ_H_ | ||
19 | #define _VNIC_CQ_H_ | ||
20 | |||
21 | #include "cq_desc.h" | ||
22 | #include "vnic_dev.h" | ||
23 | |||
24 | /* | ||
25 | * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth | ||
26 | * Driver) when both are built with CONFIG options =y | ||
27 | */ | ||
28 | #define vnic_cq_service fnic_cq_service | ||
29 | #define vnic_cq_free fnic_cq_free | ||
30 | #define vnic_cq_alloc fnic_cq_alloc | ||
31 | #define vnic_cq_init fnic_cq_init | ||
32 | #define vnic_cq_clean fnic_cq_clean | ||
33 | |||
34 | /* Completion queue control */ | ||
35 | struct vnic_cq_ctrl { | ||
36 | u64 ring_base; /* 0x00 */ | ||
37 | u32 ring_size; /* 0x08 */ | ||
38 | u32 pad0; | ||
39 | u32 flow_control_enable; /* 0x10 */ | ||
40 | u32 pad1; | ||
41 | u32 color_enable; /* 0x18 */ | ||
42 | u32 pad2; | ||
43 | u32 cq_head; /* 0x20 */ | ||
44 | u32 pad3; | ||
45 | u32 cq_tail; /* 0x28 */ | ||
46 | u32 pad4; | ||
47 | u32 cq_tail_color; /* 0x30 */ | ||
48 | u32 pad5; | ||
49 | u32 interrupt_enable; /* 0x38 */ | ||
50 | u32 pad6; | ||
51 | u32 cq_entry_enable; /* 0x40 */ | ||
52 | u32 pad7; | ||
53 | u32 cq_message_enable; /* 0x48 */ | ||
54 | u32 pad8; | ||
55 | u32 interrupt_offset; /* 0x50 */ | ||
56 | u32 pad9; | ||
57 | u64 cq_message_addr; /* 0x58 */ | ||
58 | u32 pad10; | ||
59 | }; | ||
60 | |||
61 | struct vnic_cq { | ||
62 | unsigned int index; | ||
63 | struct vnic_dev *vdev; | ||
64 | struct vnic_cq_ctrl __iomem *ctrl; /* memory-mapped */ | ||
65 | struct vnic_dev_ring ring; | ||
66 | unsigned int to_clean; | ||
67 | unsigned int last_color; | ||
68 | }; | ||
69 | |||
70 | static inline unsigned int vnic_cq_service(struct vnic_cq *cq, | ||
71 | unsigned int work_to_do, | ||
72 | int (*q_service)(struct vnic_dev *vdev, struct cq_desc *cq_desc, | ||
73 | u8 type, u16 q_number, u16 completed_index, void *opaque), | ||
74 | void *opaque) | ||
75 | { | ||
76 | struct cq_desc *cq_desc; | ||
77 | unsigned int work_done = 0; | ||
78 | u16 q_number, completed_index; | ||
79 | u8 type, color; | ||
80 | |||
81 | cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs + | ||
82 | cq->ring.desc_size * cq->to_clean); | ||
83 | cq_desc_dec(cq_desc, &type, &color, | ||
84 | &q_number, &completed_index); | ||
85 | |||
86 | while (color != cq->last_color) { | ||
87 | |||
88 | if ((*q_service)(cq->vdev, cq_desc, type, | ||
89 | q_number, completed_index, opaque)) | ||
90 | break; | ||
91 | |||
92 | cq->to_clean++; | ||
93 | if (cq->to_clean == cq->ring.desc_count) { | ||
94 | cq->to_clean = 0; | ||
95 | cq->last_color = cq->last_color ? 0 : 1; | ||
96 | } | ||
97 | |||
98 | cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs + | ||
99 | cq->ring.desc_size * cq->to_clean); | ||
100 | cq_desc_dec(cq_desc, &type, &color, | ||
101 | &q_number, &completed_index); | ||
102 | |||
103 | work_done++; | ||
104 | if (work_done >= work_to_do) | ||
105 | break; | ||
106 | } | ||
107 | |||
108 | return work_done; | ||
109 | } | ||
110 | |||
111 | void vnic_cq_free(struct vnic_cq *cq); | ||
112 | int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index, | ||
113 | unsigned int desc_count, unsigned int desc_size); | ||
114 | void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable, | ||
115 | unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail, | ||
116 | unsigned int cq_tail_color, unsigned int interrupt_enable, | ||
117 | unsigned int cq_entry_enable, unsigned int message_enable, | ||
118 | unsigned int interrupt_offset, u64 message_addr); | ||
119 | void vnic_cq_clean(struct vnic_cq *cq); | ||
120 | |||
121 | #endif /* _VNIC_CQ_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_cq_copy.h b/drivers/scsi/fnic/vnic_cq_copy.h new file mode 100644 index 000000000000..7901ce255a81 --- /dev/null +++ b/drivers/scsi/fnic/vnic_cq_copy.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_CQ_COPY_H_ | ||
19 | #define _VNIC_CQ_COPY_H_ | ||
20 | |||
21 | #include "fcpio.h" | ||
22 | |||
23 | static inline unsigned int vnic_cq_copy_service( | ||
24 | struct vnic_cq *cq, | ||
25 | int (*q_service)(struct vnic_dev *vdev, | ||
26 | unsigned int index, | ||
27 | struct fcpio_fw_req *desc), | ||
28 | unsigned int work_to_do) | ||
29 | |||
30 | { | ||
31 | struct fcpio_fw_req *desc; | ||
32 | unsigned int work_done = 0; | ||
33 | u8 color; | ||
34 | |||
35 | desc = (struct fcpio_fw_req *)((u8 *)cq->ring.descs + | ||
36 | cq->ring.desc_size * cq->to_clean); | ||
37 | fcpio_color_dec(desc, &color); | ||
38 | |||
39 | while (color != cq->last_color) { | ||
40 | |||
41 | if ((*q_service)(cq->vdev, cq->index, desc)) | ||
42 | break; | ||
43 | |||
44 | cq->to_clean++; | ||
45 | if (cq->to_clean == cq->ring.desc_count) { | ||
46 | cq->to_clean = 0; | ||
47 | cq->last_color = cq->last_color ? 0 : 1; | ||
48 | } | ||
49 | |||
50 | desc = (struct fcpio_fw_req *)((u8 *)cq->ring.descs + | ||
51 | cq->ring.desc_size * cq->to_clean); | ||
52 | fcpio_color_dec(desc, &color); | ||
53 | |||
54 | work_done++; | ||
55 | if (work_done >= work_to_do) | ||
56 | break; | ||
57 | } | ||
58 | |||
59 | return work_done; | ||
60 | } | ||
61 | |||
62 | #endif /* _VNIC_CQ_COPY_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c new file mode 100644 index 000000000000..566770645086 --- /dev/null +++ b/drivers/scsi/fnic/vnic_dev.c | |||
@@ -0,0 +1,690 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/if_ether.h> | ||
25 | #include "vnic_resource.h" | ||
26 | #include "vnic_devcmd.h" | ||
27 | #include "vnic_dev.h" | ||
28 | #include "vnic_stats.h" | ||
29 | |||
30 | struct vnic_res { | ||
31 | void __iomem *vaddr; | ||
32 | unsigned int count; | ||
33 | }; | ||
34 | |||
35 | struct vnic_dev { | ||
36 | void *priv; | ||
37 | struct pci_dev *pdev; | ||
38 | struct vnic_res res[RES_TYPE_MAX]; | ||
39 | enum vnic_dev_intr_mode intr_mode; | ||
40 | struct vnic_devcmd __iomem *devcmd; | ||
41 | struct vnic_devcmd_notify *notify; | ||
42 | struct vnic_devcmd_notify notify_copy; | ||
43 | dma_addr_t notify_pa; | ||
44 | u32 *linkstatus; | ||
45 | dma_addr_t linkstatus_pa; | ||
46 | struct vnic_stats *stats; | ||
47 | dma_addr_t stats_pa; | ||
48 | struct vnic_devcmd_fw_info *fw_info; | ||
49 | dma_addr_t fw_info_pa; | ||
50 | }; | ||
51 | |||
52 | #define VNIC_MAX_RES_HDR_SIZE \ | ||
53 | (sizeof(struct vnic_resource_header) + \ | ||
54 | sizeof(struct vnic_resource) * RES_TYPE_MAX) | ||
55 | #define VNIC_RES_STRIDE 128 | ||
56 | |||
57 | void *vnic_dev_priv(struct vnic_dev *vdev) | ||
58 | { | ||
59 | return vdev->priv; | ||
60 | } | ||
61 | |||
62 | static int vnic_dev_discover_res(struct vnic_dev *vdev, | ||
63 | struct vnic_dev_bar *bar) | ||
64 | { | ||
65 | struct vnic_resource_header __iomem *rh; | ||
66 | struct vnic_resource __iomem *r; | ||
67 | u8 type; | ||
68 | |||
69 | if (bar->len < VNIC_MAX_RES_HDR_SIZE) { | ||
70 | printk(KERN_ERR "vNIC BAR0 res hdr length error\n"); | ||
71 | return -EINVAL; | ||
72 | } | ||
73 | |||
74 | rh = bar->vaddr; | ||
75 | if (!rh) { | ||
76 | printk(KERN_ERR "vNIC BAR0 res hdr not mem-mapped\n"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | if (ioread32(&rh->magic) != VNIC_RES_MAGIC || | ||
81 | ioread32(&rh->version) != VNIC_RES_VERSION) { | ||
82 | printk(KERN_ERR "vNIC BAR0 res magic/version error " | ||
83 | "exp (%lx/%lx) curr (%x/%x)\n", | ||
84 | VNIC_RES_MAGIC, VNIC_RES_VERSION, | ||
85 | ioread32(&rh->magic), ioread32(&rh->version)); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | r = (struct vnic_resource __iomem *)(rh + 1); | ||
90 | |||
91 | while ((type = ioread8(&r->type)) != RES_TYPE_EOL) { | ||
92 | |||
93 | u8 bar_num = ioread8(&r->bar); | ||
94 | u32 bar_offset = ioread32(&r->bar_offset); | ||
95 | u32 count = ioread32(&r->count); | ||
96 | u32 len; | ||
97 | |||
98 | r++; | ||
99 | |||
100 | if (bar_num != 0) /* only mapping in BAR0 resources */ | ||
101 | continue; | ||
102 | |||
103 | switch (type) { | ||
104 | case RES_TYPE_WQ: | ||
105 | case RES_TYPE_RQ: | ||
106 | case RES_TYPE_CQ: | ||
107 | case RES_TYPE_INTR_CTRL: | ||
108 | /* each count is stride bytes long */ | ||
109 | len = count * VNIC_RES_STRIDE; | ||
110 | if (len + bar_offset > bar->len) { | ||
111 | printk(KERN_ERR "vNIC BAR0 resource %d " | ||
112 | "out-of-bounds, offset 0x%x + " | ||
113 | "size 0x%x > bar len 0x%lx\n", | ||
114 | type, bar_offset, | ||
115 | len, | ||
116 | bar->len); | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | break; | ||
120 | case RES_TYPE_INTR_PBA_LEGACY: | ||
121 | case RES_TYPE_DEVCMD: | ||
122 | len = count; | ||
123 | break; | ||
124 | default: | ||
125 | continue; | ||
126 | } | ||
127 | |||
128 | vdev->res[type].count = count; | ||
129 | vdev->res[type].vaddr = (char __iomem *)bar->vaddr + bar_offset; | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev, | ||
136 | enum vnic_res_type type) | ||
137 | { | ||
138 | return vdev->res[type].count; | ||
139 | } | ||
140 | |||
141 | void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, | ||
142 | unsigned int index) | ||
143 | { | ||
144 | if (!vdev->res[type].vaddr) | ||
145 | return NULL; | ||
146 | |||
147 | switch (type) { | ||
148 | case RES_TYPE_WQ: | ||
149 | case RES_TYPE_RQ: | ||
150 | case RES_TYPE_CQ: | ||
151 | case RES_TYPE_INTR_CTRL: | ||
152 | return (char __iomem *)vdev->res[type].vaddr + | ||
153 | index * VNIC_RES_STRIDE; | ||
154 | default: | ||
155 | return (char __iomem *)vdev->res[type].vaddr; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, | ||
160 | unsigned int desc_count, | ||
161 | unsigned int desc_size) | ||
162 | { | ||
163 | /* The base address of the desc rings must be 512 byte aligned. | ||
164 | * Descriptor count is aligned to groups of 32 descriptors. A | ||
165 | * count of 0 means the maximum 4096 descriptors. Descriptor | ||
166 | * size is aligned to 16 bytes. | ||
167 | */ | ||
168 | |||
169 | unsigned int count_align = 32; | ||
170 | unsigned int desc_align = 16; | ||
171 | |||
172 | ring->base_align = 512; | ||
173 | |||
174 | if (desc_count == 0) | ||
175 | desc_count = 4096; | ||
176 | |||
177 | ring->desc_count = ALIGN(desc_count, count_align); | ||
178 | |||
179 | ring->desc_size = ALIGN(desc_size, desc_align); | ||
180 | |||
181 | ring->size = ring->desc_count * ring->desc_size; | ||
182 | ring->size_unaligned = ring->size + ring->base_align; | ||
183 | |||
184 | return ring->size_unaligned; | ||
185 | } | ||
186 | |||
187 | void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring) | ||
188 | { | ||
189 | memset(ring->descs, 0, ring->size); | ||
190 | } | ||
191 | |||
192 | int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring, | ||
193 | unsigned int desc_count, unsigned int desc_size) | ||
194 | { | ||
195 | vnic_dev_desc_ring_size(ring, desc_count, desc_size); | ||
196 | |||
197 | ring->descs_unaligned = pci_alloc_consistent(vdev->pdev, | ||
198 | ring->size_unaligned, | ||
199 | &ring->base_addr_unaligned); | ||
200 | |||
201 | if (!ring->descs_unaligned) { | ||
202 | printk(KERN_ERR | ||
203 | "Failed to allocate ring (size=%d), aborting\n", | ||
204 | (int)ring->size); | ||
205 | return -ENOMEM; | ||
206 | } | ||
207 | |||
208 | ring->base_addr = ALIGN(ring->base_addr_unaligned, | ||
209 | ring->base_align); | ||
210 | ring->descs = (u8 *)ring->descs_unaligned + | ||
211 | (ring->base_addr - ring->base_addr_unaligned); | ||
212 | |||
213 | vnic_dev_clear_desc_ring(ring); | ||
214 | |||
215 | ring->desc_avail = ring->desc_count - 1; | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring) | ||
221 | { | ||
222 | if (ring->descs) { | ||
223 | pci_free_consistent(vdev->pdev, | ||
224 | ring->size_unaligned, | ||
225 | ring->descs_unaligned, | ||
226 | ring->base_addr_unaligned); | ||
227 | ring->descs = NULL; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | ||
232 | u64 *a0, u64 *a1, int wait) | ||
233 | { | ||
234 | struct vnic_devcmd __iomem *devcmd = vdev->devcmd; | ||
235 | int delay; | ||
236 | u32 status; | ||
237 | int dev_cmd_err[] = { | ||
238 | /* convert from fw's version of error.h to host's version */ | ||
239 | 0, /* ERR_SUCCESS */ | ||
240 | EINVAL, /* ERR_EINVAL */ | ||
241 | EFAULT, /* ERR_EFAULT */ | ||
242 | EPERM, /* ERR_EPERM */ | ||
243 | EBUSY, /* ERR_EBUSY */ | ||
244 | }; | ||
245 | int err; | ||
246 | |||
247 | status = ioread32(&devcmd->status); | ||
248 | if (status & STAT_BUSY) { | ||
249 | printk(KERN_ERR "Busy devcmd %d\n", _CMD_N(cmd)); | ||
250 | return -EBUSY; | ||
251 | } | ||
252 | |||
253 | if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) { | ||
254 | writeq(*a0, &devcmd->args[0]); | ||
255 | writeq(*a1, &devcmd->args[1]); | ||
256 | wmb(); | ||
257 | } | ||
258 | |||
259 | iowrite32(cmd, &devcmd->cmd); | ||
260 | |||
261 | if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT)) | ||
262 | return 0; | ||
263 | |||
264 | for (delay = 0; delay < wait; delay++) { | ||
265 | |||
266 | udelay(100); | ||
267 | |||
268 | status = ioread32(&devcmd->status); | ||
269 | if (!(status & STAT_BUSY)) { | ||
270 | |||
271 | if (status & STAT_ERROR) { | ||
272 | err = dev_cmd_err[(int)readq(&devcmd->args[0])]; | ||
273 | printk(KERN_ERR "Error %d devcmd %d\n", | ||
274 | err, _CMD_N(cmd)); | ||
275 | return -err; | ||
276 | } | ||
277 | |||
278 | if (_CMD_DIR(cmd) & _CMD_DIR_READ) { | ||
279 | rmb(); | ||
280 | *a0 = readq(&devcmd->args[0]); | ||
281 | *a1 = readq(&devcmd->args[1]); | ||
282 | } | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | printk(KERN_ERR "Timedout devcmd %d\n", _CMD_N(cmd)); | ||
289 | return -ETIMEDOUT; | ||
290 | } | ||
291 | |||
292 | int vnic_dev_fw_info(struct vnic_dev *vdev, | ||
293 | struct vnic_devcmd_fw_info **fw_info) | ||
294 | { | ||
295 | u64 a0, a1 = 0; | ||
296 | int wait = 1000; | ||
297 | int err = 0; | ||
298 | |||
299 | if (!vdev->fw_info) { | ||
300 | vdev->fw_info = pci_alloc_consistent(vdev->pdev, | ||
301 | sizeof(struct vnic_devcmd_fw_info), | ||
302 | &vdev->fw_info_pa); | ||
303 | if (!vdev->fw_info) | ||
304 | return -ENOMEM; | ||
305 | |||
306 | a0 = vdev->fw_info_pa; | ||
307 | |||
308 | /* only get fw_info once and cache it */ | ||
309 | err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait); | ||
310 | } | ||
311 | |||
312 | *fw_info = vdev->fw_info; | ||
313 | |||
314 | return err; | ||
315 | } | ||
316 | |||
317 | int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, | ||
318 | void *value) | ||
319 | { | ||
320 | u64 a0, a1; | ||
321 | int wait = 1000; | ||
322 | int err; | ||
323 | |||
324 | a0 = offset; | ||
325 | a1 = size; | ||
326 | |||
327 | err = vnic_dev_cmd(vdev, CMD_DEV_SPEC, &a0, &a1, wait); | ||
328 | |||
329 | switch (size) { | ||
330 | case 1: | ||
331 | *(u8 *)value = (u8)a0; | ||
332 | break; | ||
333 | case 2: | ||
334 | *(u16 *)value = (u16)a0; | ||
335 | break; | ||
336 | case 4: | ||
337 | *(u32 *)value = (u32)a0; | ||
338 | break; | ||
339 | case 8: | ||
340 | *(u64 *)value = a0; | ||
341 | break; | ||
342 | default: | ||
343 | BUG(); | ||
344 | break; | ||
345 | } | ||
346 | |||
347 | return err; | ||
348 | } | ||
349 | |||
350 | int vnic_dev_stats_clear(struct vnic_dev *vdev) | ||
351 | { | ||
352 | u64 a0 = 0, a1 = 0; | ||
353 | int wait = 1000; | ||
354 | return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait); | ||
355 | } | ||
356 | |||
357 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) | ||
358 | { | ||
359 | u64 a0, a1; | ||
360 | int wait = 1000; | ||
361 | |||
362 | if (!vdev->stats) { | ||
363 | vdev->stats = pci_alloc_consistent(vdev->pdev, | ||
364 | sizeof(struct vnic_stats), &vdev->stats_pa); | ||
365 | if (!vdev->stats) | ||
366 | return -ENOMEM; | ||
367 | } | ||
368 | |||
369 | *stats = vdev->stats; | ||
370 | a0 = vdev->stats_pa; | ||
371 | a1 = sizeof(struct vnic_stats); | ||
372 | |||
373 | return vnic_dev_cmd(vdev, CMD_STATS_DUMP, &a0, &a1, wait); | ||
374 | } | ||
375 | |||
376 | int vnic_dev_close(struct vnic_dev *vdev) | ||
377 | { | ||
378 | u64 a0 = 0, a1 = 0; | ||
379 | int wait = 1000; | ||
380 | return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait); | ||
381 | } | ||
382 | |||
383 | int vnic_dev_enable(struct vnic_dev *vdev) | ||
384 | { | ||
385 | u64 a0 = 0, a1 = 0; | ||
386 | int wait = 1000; | ||
387 | return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); | ||
388 | } | ||
389 | |||
390 | int vnic_dev_disable(struct vnic_dev *vdev) | ||
391 | { | ||
392 | u64 a0 = 0, a1 = 0; | ||
393 | int wait = 1000; | ||
394 | return vnic_dev_cmd(vdev, CMD_DISABLE, &a0, &a1, wait); | ||
395 | } | ||
396 | |||
397 | int vnic_dev_open(struct vnic_dev *vdev, int arg) | ||
398 | { | ||
399 | u64 a0 = (u32)arg, a1 = 0; | ||
400 | int wait = 1000; | ||
401 | return vnic_dev_cmd(vdev, CMD_OPEN, &a0, &a1, wait); | ||
402 | } | ||
403 | |||
404 | int vnic_dev_open_done(struct vnic_dev *vdev, int *done) | ||
405 | { | ||
406 | u64 a0 = 0, a1 = 0; | ||
407 | int wait = 1000; | ||
408 | int err; | ||
409 | |||
410 | *done = 0; | ||
411 | |||
412 | err = vnic_dev_cmd(vdev, CMD_OPEN_STATUS, &a0, &a1, wait); | ||
413 | if (err) | ||
414 | return err; | ||
415 | |||
416 | *done = (a0 == 0); | ||
417 | |||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg) | ||
422 | { | ||
423 | u64 a0 = (u32)arg, a1 = 0; | ||
424 | int wait = 1000; | ||
425 | return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait); | ||
426 | } | ||
427 | |||
428 | int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) | ||
429 | { | ||
430 | u64 a0 = 0, a1 = 0; | ||
431 | int wait = 1000; | ||
432 | int err; | ||
433 | |||
434 | *done = 0; | ||
435 | |||
436 | err = vnic_dev_cmd(vdev, CMD_SOFT_RESET_STATUS, &a0, &a1, wait); | ||
437 | if (err) | ||
438 | return err; | ||
439 | |||
440 | *done = (a0 == 0); | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | int vnic_dev_hang_notify(struct vnic_dev *vdev) | ||
446 | { | ||
447 | u64 a0, a1; | ||
448 | int wait = 1000; | ||
449 | return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait); | ||
450 | } | ||
451 | |||
452 | int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) | ||
453 | { | ||
454 | u64 a0, a1; | ||
455 | int wait = 1000; | ||
456 | int err, i; | ||
457 | |||
458 | for (i = 0; i < ETH_ALEN; i++) | ||
459 | mac_addr[i] = 0; | ||
460 | |||
461 | err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait); | ||
462 | if (err) | ||
463 | return err; | ||
464 | |||
465 | for (i = 0; i < ETH_ALEN; i++) | ||
466 | mac_addr[i] = ((u8 *)&a0)[i]; | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | ||
472 | int broadcast, int promisc, int allmulti) | ||
473 | { | ||
474 | u64 a0, a1 = 0; | ||
475 | int wait = 1000; | ||
476 | int err; | ||
477 | |||
478 | a0 = (directed ? CMD_PFILTER_DIRECTED : 0) | | ||
479 | (multicast ? CMD_PFILTER_MULTICAST : 0) | | ||
480 | (broadcast ? CMD_PFILTER_BROADCAST : 0) | | ||
481 | (promisc ? CMD_PFILTER_PROMISCUOUS : 0) | | ||
482 | (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0); | ||
483 | |||
484 | err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait); | ||
485 | if (err) | ||
486 | printk(KERN_ERR "Can't set packet filter\n"); | ||
487 | } | ||
488 | |||
489 | void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) | ||
490 | { | ||
491 | u64 a0 = 0, a1 = 0; | ||
492 | int wait = 1000; | ||
493 | int err; | ||
494 | int i; | ||
495 | |||
496 | for (i = 0; i < ETH_ALEN; i++) | ||
497 | ((u8 *)&a0)[i] = addr[i]; | ||
498 | |||
499 | err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); | ||
500 | if (err) | ||
501 | printk(KERN_ERR | ||
502 | "Can't add addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n", | ||
503 | addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], | ||
504 | err); | ||
505 | } | ||
506 | |||
507 | void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) | ||
508 | { | ||
509 | u64 a0 = 0, a1 = 0; | ||
510 | int wait = 1000; | ||
511 | int err; | ||
512 | int i; | ||
513 | |||
514 | for (i = 0; i < ETH_ALEN; i++) | ||
515 | ((u8 *)&a0)[i] = addr[i]; | ||
516 | |||
517 | err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); | ||
518 | if (err) | ||
519 | printk(KERN_ERR | ||
520 | "Can't del addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n", | ||
521 | addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], | ||
522 | err); | ||
523 | } | ||
524 | |||
525 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | ||
526 | { | ||
527 | u64 a0, a1; | ||
528 | int wait = 1000; | ||
529 | |||
530 | if (!vdev->notify) { | ||
531 | vdev->notify = pci_alloc_consistent(vdev->pdev, | ||
532 | sizeof(struct vnic_devcmd_notify), | ||
533 | &vdev->notify_pa); | ||
534 | if (!vdev->notify) | ||
535 | return -ENOMEM; | ||
536 | } | ||
537 | |||
538 | a0 = vdev->notify_pa; | ||
539 | a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; | ||
540 | a1 += sizeof(struct vnic_devcmd_notify); | ||
541 | |||
542 | return vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); | ||
543 | } | ||
544 | |||
545 | void vnic_dev_notify_unset(struct vnic_dev *vdev) | ||
546 | { | ||
547 | u64 a0, a1; | ||
548 | int wait = 1000; | ||
549 | |||
550 | a0 = 0; /* paddr = 0 to unset notify buffer */ | ||
551 | a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */ | ||
552 | a1 += sizeof(struct vnic_devcmd_notify); | ||
553 | |||
554 | vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); | ||
555 | } | ||
556 | |||
557 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) | ||
558 | { | ||
559 | u32 *words; | ||
560 | unsigned int nwords = sizeof(struct vnic_devcmd_notify) / 4; | ||
561 | unsigned int i; | ||
562 | u32 csum; | ||
563 | |||
564 | if (!vdev->notify) | ||
565 | return 0; | ||
566 | |||
567 | do { | ||
568 | csum = 0; | ||
569 | memcpy(&vdev->notify_copy, vdev->notify, | ||
570 | sizeof(struct vnic_devcmd_notify)); | ||
571 | words = (u32 *)&vdev->notify_copy; | ||
572 | for (i = 1; i < nwords; i++) | ||
573 | csum += words[i]; | ||
574 | } while (csum != words[0]); | ||
575 | |||
576 | return 1; | ||
577 | } | ||
578 | |||
579 | int vnic_dev_init(struct vnic_dev *vdev, int arg) | ||
580 | { | ||
581 | u64 a0 = (u32)arg, a1 = 0; | ||
582 | int wait = 1000; | ||
583 | return vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait); | ||
584 | } | ||
585 | |||
586 | int vnic_dev_link_status(struct vnic_dev *vdev) | ||
587 | { | ||
588 | if (vdev->linkstatus) | ||
589 | return *vdev->linkstatus; | ||
590 | |||
591 | if (!vnic_dev_notify_ready(vdev)) | ||
592 | return 0; | ||
593 | |||
594 | return vdev->notify_copy.link_state; | ||
595 | } | ||
596 | |||
597 | u32 vnic_dev_port_speed(struct vnic_dev *vdev) | ||
598 | { | ||
599 | if (!vnic_dev_notify_ready(vdev)) | ||
600 | return 0; | ||
601 | |||
602 | return vdev->notify_copy.port_speed; | ||
603 | } | ||
604 | |||
605 | u32 vnic_dev_msg_lvl(struct vnic_dev *vdev) | ||
606 | { | ||
607 | if (!vnic_dev_notify_ready(vdev)) | ||
608 | return 0; | ||
609 | |||
610 | return vdev->notify_copy.msglvl; | ||
611 | } | ||
612 | |||
613 | u32 vnic_dev_mtu(struct vnic_dev *vdev) | ||
614 | { | ||
615 | if (!vnic_dev_notify_ready(vdev)) | ||
616 | return 0; | ||
617 | |||
618 | return vdev->notify_copy.mtu; | ||
619 | } | ||
620 | |||
621 | u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev) | ||
622 | { | ||
623 | if (!vnic_dev_notify_ready(vdev)) | ||
624 | return 0; | ||
625 | |||
626 | return vdev->notify_copy.link_down_cnt; | ||
627 | } | ||
628 | |||
629 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, | ||
630 | enum vnic_dev_intr_mode intr_mode) | ||
631 | { | ||
632 | vdev->intr_mode = intr_mode; | ||
633 | } | ||
634 | |||
635 | enum vnic_dev_intr_mode vnic_dev_get_intr_mode( | ||
636 | struct vnic_dev *vdev) | ||
637 | { | ||
638 | return vdev->intr_mode; | ||
639 | } | ||
640 | |||
641 | void vnic_dev_unregister(struct vnic_dev *vdev) | ||
642 | { | ||
643 | if (vdev) { | ||
644 | if (vdev->notify) | ||
645 | pci_free_consistent(vdev->pdev, | ||
646 | sizeof(struct vnic_devcmd_notify), | ||
647 | vdev->notify, | ||
648 | vdev->notify_pa); | ||
649 | if (vdev->linkstatus) | ||
650 | pci_free_consistent(vdev->pdev, | ||
651 | sizeof(u32), | ||
652 | vdev->linkstatus, | ||
653 | vdev->linkstatus_pa); | ||
654 | if (vdev->stats) | ||
655 | pci_free_consistent(vdev->pdev, | ||
656 | sizeof(struct vnic_dev), | ||
657 | vdev->stats, vdev->stats_pa); | ||
658 | if (vdev->fw_info) | ||
659 | pci_free_consistent(vdev->pdev, | ||
660 | sizeof(struct vnic_devcmd_fw_info), | ||
661 | vdev->fw_info, vdev->fw_info_pa); | ||
662 | kfree(vdev); | ||
663 | } | ||
664 | } | ||
665 | |||
666 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | ||
667 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar) | ||
668 | { | ||
669 | if (!vdev) { | ||
670 | vdev = kzalloc(sizeof(struct vnic_dev), GFP_KERNEL); | ||
671 | if (!vdev) | ||
672 | return NULL; | ||
673 | } | ||
674 | |||
675 | vdev->priv = priv; | ||
676 | vdev->pdev = pdev; | ||
677 | |||
678 | if (vnic_dev_discover_res(vdev, bar)) | ||
679 | goto err_out; | ||
680 | |||
681 | vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0); | ||
682 | if (!vdev->devcmd) | ||
683 | goto err_out; | ||
684 | |||
685 | return vdev; | ||
686 | |||
687 | err_out: | ||
688 | vnic_dev_unregister(vdev); | ||
689 | return NULL; | ||
690 | } | ||
diff --git a/drivers/scsi/fnic/vnic_dev.h b/drivers/scsi/fnic/vnic_dev.h new file mode 100644 index 000000000000..f9935a8a5a09 --- /dev/null +++ b/drivers/scsi/fnic/vnic_dev.h | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_DEV_H_ | ||
19 | #define _VNIC_DEV_H_ | ||
20 | |||
21 | #include "vnic_resource.h" | ||
22 | #include "vnic_devcmd.h" | ||
23 | |||
24 | /* | ||
25 | * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth | ||
26 | * Driver) when both are built with CONFIG options =y | ||
27 | */ | ||
28 | #define vnic_dev_priv fnic_dev_priv | ||
29 | #define vnic_dev_get_res_count fnic_dev_get_res_count | ||
30 | #define vnic_dev_get_res fnic_dev_get_res | ||
31 | #define vnic_dev_desc_ring_size fnic_dev_desc_ring_siz | ||
32 | #define vnic_dev_clear_desc_ring fnic_dev_clear_desc_ring | ||
33 | #define vnic_dev_alloc_desc_ring fnic_dev_alloc_desc_ring | ||
34 | #define vnic_dev_free_desc_ring fnic_dev_free_desc_ring | ||
35 | #define vnic_dev_cmd fnic_dev_cmd | ||
36 | #define vnic_dev_fw_info fnic_dev_fw_info | ||
37 | #define vnic_dev_spec fnic_dev_spec | ||
38 | #define vnic_dev_stats_clear fnic_dev_stats_clear | ||
39 | #define vnic_dev_stats_dump fnic_dev_stats_dump | ||
40 | #define vnic_dev_hang_notify fnic_dev_hang_notify | ||
41 | #define vnic_dev_packet_filter fnic_dev_packet_filter | ||
42 | #define vnic_dev_add_addr fnic_dev_add_addr | ||
43 | #define vnic_dev_del_addr fnic_dev_del_addr | ||
44 | #define vnic_dev_mac_addr fnic_dev_mac_addr | ||
45 | #define vnic_dev_notify_set fnic_dev_notify_set | ||
46 | #define vnic_dev_notify_unset fnic_dev_notify_unset | ||
47 | #define vnic_dev_link_status fnic_dev_link_status | ||
48 | #define vnic_dev_port_speed fnic_dev_port_speed | ||
49 | #define vnic_dev_msg_lvl fnic_dev_msg_lvl | ||
50 | #define vnic_dev_mtu fnic_dev_mtu | ||
51 | #define vnic_dev_link_down_cnt fnic_dev_link_down_cnt | ||
52 | #define vnic_dev_close fnic_dev_close | ||
53 | #define vnic_dev_enable fnic_dev_enable | ||
54 | #define vnic_dev_disable fnic_dev_disable | ||
55 | #define vnic_dev_open fnic_dev_open | ||
56 | #define vnic_dev_open_done fnic_dev_open_done | ||
57 | #define vnic_dev_init fnic_dev_init | ||
58 | #define vnic_dev_soft_reset fnic_dev_soft_reset | ||
59 | #define vnic_dev_soft_reset_done fnic_dev_soft_reset_done | ||
60 | #define vnic_dev_set_intr_mode fnic_dev_set_intr_mode | ||
61 | #define vnic_dev_get_intr_mode fnic_dev_get_intr_mode | ||
62 | #define vnic_dev_unregister fnic_dev_unregister | ||
63 | #define vnic_dev_register fnic_dev_register | ||
64 | |||
65 | #ifndef VNIC_PADDR_TARGET | ||
66 | #define VNIC_PADDR_TARGET 0x0000000000000000ULL | ||
67 | #endif | ||
68 | |||
69 | #ifndef readq | ||
70 | static inline u64 readq(void __iomem *reg) | ||
71 | { | ||
72 | return ((u64)readl(reg + 0x4UL) << 32) | (u64)readl(reg); | ||
73 | } | ||
74 | |||
75 | static inline void writeq(u64 val, void __iomem *reg) | ||
76 | { | ||
77 | writel(val & 0xffffffff, reg); | ||
78 | writel(val >> 32, reg + 0x4UL); | ||
79 | } | ||
80 | #endif | ||
81 | |||
82 | enum vnic_dev_intr_mode { | ||
83 | VNIC_DEV_INTR_MODE_UNKNOWN, | ||
84 | VNIC_DEV_INTR_MODE_INTX, | ||
85 | VNIC_DEV_INTR_MODE_MSI, | ||
86 | VNIC_DEV_INTR_MODE_MSIX, | ||
87 | }; | ||
88 | |||
89 | struct vnic_dev_bar { | ||
90 | void __iomem *vaddr; | ||
91 | dma_addr_t bus_addr; | ||
92 | unsigned long len; | ||
93 | }; | ||
94 | |||
95 | struct vnic_dev_ring { | ||
96 | void *descs; | ||
97 | size_t size; | ||
98 | dma_addr_t base_addr; | ||
99 | size_t base_align; | ||
100 | void *descs_unaligned; | ||
101 | size_t size_unaligned; | ||
102 | dma_addr_t base_addr_unaligned; | ||
103 | unsigned int desc_size; | ||
104 | unsigned int desc_count; | ||
105 | unsigned int desc_avail; | ||
106 | }; | ||
107 | |||
108 | struct vnic_dev; | ||
109 | struct vnic_stats; | ||
110 | |||
111 | void *vnic_dev_priv(struct vnic_dev *vdev); | ||
112 | unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev, | ||
113 | enum vnic_res_type type); | ||
114 | void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, | ||
115 | unsigned int index); | ||
116 | unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, | ||
117 | unsigned int desc_count, | ||
118 | unsigned int desc_size); | ||
119 | void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring); | ||
120 | int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring, | ||
121 | unsigned int desc_count, unsigned int desc_size); | ||
122 | void vnic_dev_free_desc_ring(struct vnic_dev *vdev, | ||
123 | struct vnic_dev_ring *ring); | ||
124 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | ||
125 | u64 *a0, u64 *a1, int wait); | ||
126 | int vnic_dev_fw_info(struct vnic_dev *vdev, | ||
127 | struct vnic_devcmd_fw_info **fw_info); | ||
128 | int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, | ||
129 | unsigned int size, void *value); | ||
130 | int vnic_dev_stats_clear(struct vnic_dev *vdev); | ||
131 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); | ||
132 | int vnic_dev_hang_notify(struct vnic_dev *vdev); | ||
133 | void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | ||
134 | int broadcast, int promisc, int allmulti); | ||
135 | void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); | ||
136 | void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); | ||
137 | int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); | ||
138 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); | ||
139 | void vnic_dev_notify_unset(struct vnic_dev *vdev); | ||
140 | int vnic_dev_link_status(struct vnic_dev *vdev); | ||
141 | u32 vnic_dev_port_speed(struct vnic_dev *vdev); | ||
142 | u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); | ||
143 | u32 vnic_dev_mtu(struct vnic_dev *vdev); | ||
144 | u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev); | ||
145 | int vnic_dev_close(struct vnic_dev *vdev); | ||
146 | int vnic_dev_enable(struct vnic_dev *vdev); | ||
147 | int vnic_dev_disable(struct vnic_dev *vdev); | ||
148 | int vnic_dev_open(struct vnic_dev *vdev, int arg); | ||
149 | int vnic_dev_open_done(struct vnic_dev *vdev, int *done); | ||
150 | int vnic_dev_init(struct vnic_dev *vdev, int arg); | ||
151 | int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg); | ||
152 | int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done); | ||
153 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, | ||
154 | enum vnic_dev_intr_mode intr_mode); | ||
155 | enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev); | ||
156 | void vnic_dev_unregister(struct vnic_dev *vdev); | ||
157 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | ||
158 | void *priv, struct pci_dev *pdev, | ||
159 | struct vnic_dev_bar *bar); | ||
160 | |||
161 | #endif /* _VNIC_DEV_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_devcmd.h b/drivers/scsi/fnic/vnic_devcmd.h new file mode 100644 index 000000000000..d62b9061bf12 --- /dev/null +++ b/drivers/scsi/fnic/vnic_devcmd.h | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_DEVCMD_H_ | ||
19 | #define _VNIC_DEVCMD_H_ | ||
20 | |||
21 | #define _CMD_NBITS 14 | ||
22 | #define _CMD_VTYPEBITS 10 | ||
23 | #define _CMD_FLAGSBITS 6 | ||
24 | #define _CMD_DIRBITS 2 | ||
25 | |||
26 | #define _CMD_NMASK ((1 << _CMD_NBITS)-1) | ||
27 | #define _CMD_VTYPEMASK ((1 << _CMD_VTYPEBITS)-1) | ||
28 | #define _CMD_FLAGSMASK ((1 << _CMD_FLAGSBITS)-1) | ||
29 | #define _CMD_DIRMASK ((1 << _CMD_DIRBITS)-1) | ||
30 | |||
31 | #define _CMD_NSHIFT 0 | ||
32 | #define _CMD_VTYPESHIFT (_CMD_NSHIFT+_CMD_NBITS) | ||
33 | #define _CMD_FLAGSSHIFT (_CMD_VTYPESHIFT+_CMD_VTYPEBITS) | ||
34 | #define _CMD_DIRSHIFT (_CMD_FLAGSSHIFT+_CMD_FLAGSBITS) | ||
35 | |||
36 | /* | ||
37 | * Direction bits (from host perspective). | ||
38 | */ | ||
39 | #define _CMD_DIR_NONE 0U | ||
40 | #define _CMD_DIR_WRITE 1U | ||
41 | #define _CMD_DIR_READ 2U | ||
42 | #define _CMD_DIR_RW (_CMD_DIR_WRITE | _CMD_DIR_READ) | ||
43 | |||
44 | /* | ||
45 | * Flag bits. | ||
46 | */ | ||
47 | #define _CMD_FLAGS_NONE 0U | ||
48 | #define _CMD_FLAGS_NOWAIT 1U | ||
49 | |||
50 | /* | ||
51 | * vNIC type bits. | ||
52 | */ | ||
53 | #define _CMD_VTYPE_NONE 0U | ||
54 | #define _CMD_VTYPE_ENET 1U | ||
55 | #define _CMD_VTYPE_FC 2U | ||
56 | #define _CMD_VTYPE_SCSI 4U | ||
57 | #define _CMD_VTYPE_ALL (_CMD_VTYPE_ENET | _CMD_VTYPE_FC | _CMD_VTYPE_SCSI) | ||
58 | |||
59 | /* | ||
60 | * Used to create cmds.. | ||
61 | */ | ||
62 | #define _CMDCF(dir, flags, vtype, nr) \ | ||
63 | (((dir) << _CMD_DIRSHIFT) | \ | ||
64 | ((flags) << _CMD_FLAGSSHIFT) | \ | ||
65 | ((vtype) << _CMD_VTYPESHIFT) | \ | ||
66 | ((nr) << _CMD_NSHIFT)) | ||
67 | #define _CMDC(dir, vtype, nr) _CMDCF(dir, 0, vtype, nr) | ||
68 | #define _CMDCNW(dir, vtype, nr) _CMDCF(dir, _CMD_FLAGS_NOWAIT, vtype, nr) | ||
69 | |||
70 | /* | ||
71 | * Used to decode cmds.. | ||
72 | */ | ||
73 | #define _CMD_DIR(cmd) (((cmd) >> _CMD_DIRSHIFT) & _CMD_DIRMASK) | ||
74 | #define _CMD_FLAGS(cmd) (((cmd) >> _CMD_FLAGSSHIFT) & _CMD_FLAGSMASK) | ||
75 | #define _CMD_VTYPE(cmd) (((cmd) >> _CMD_VTYPESHIFT) & _CMD_VTYPEMASK) | ||
76 | #define _CMD_N(cmd) (((cmd) >> _CMD_NSHIFT) & _CMD_NMASK) | ||
77 | |||
78 | enum vnic_devcmd_cmd { | ||
79 | CMD_NONE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_NONE, 0), | ||
80 | |||
81 | /* mcpu fw info in mem: (u64)a0=paddr to struct vnic_devcmd_fw_info */ | ||
82 | CMD_MCPU_FW_INFO = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 1), | ||
83 | |||
84 | /* dev-specific block member: | ||
85 | * in: (u16)a0=offset,(u8)a1=size | ||
86 | * out: a0=value */ | ||
87 | CMD_DEV_SPEC = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 2), | ||
88 | |||
89 | /* stats clear */ | ||
90 | CMD_STATS_CLEAR = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 3), | ||
91 | |||
92 | /* stats dump in mem: (u64)a0=paddr to stats area, | ||
93 | * (u16)a1=sizeof stats area */ | ||
94 | CMD_STATS_DUMP = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 4), | ||
95 | |||
96 | /* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */ | ||
97 | CMD_PACKET_FILTER = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 7), | ||
98 | |||
99 | /* hang detection notification */ | ||
100 | CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8), | ||
101 | |||
102 | /* MAC address in (u48)a0 */ | ||
103 | CMD_MAC_ADDR = _CMDC(_CMD_DIR_READ, | ||
104 | _CMD_VTYPE_ENET | _CMD_VTYPE_FC, 9), | ||
105 | |||
106 | /* disable/enable promisc mode: (u8)a0=0/1 */ | ||
107 | /***** XXX DEPRECATED *****/ | ||
108 | CMD_PROMISC_MODE = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 10), | ||
109 | |||
110 | /* disable/enable all-multi mode: (u8)a0=0/1 */ | ||
111 | /***** XXX DEPRECATED *****/ | ||
112 | CMD_ALLMULTI_MODE = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 11), | ||
113 | |||
114 | /* add addr from (u48)a0 */ | ||
115 | CMD_ADDR_ADD = _CMDCNW(_CMD_DIR_WRITE, | ||
116 | _CMD_VTYPE_ENET | _CMD_VTYPE_FC, 12), | ||
117 | |||
118 | /* del addr from (u48)a0 */ | ||
119 | CMD_ADDR_DEL = _CMDCNW(_CMD_DIR_WRITE, | ||
120 | _CMD_VTYPE_ENET | _CMD_VTYPE_FC, 13), | ||
121 | |||
122 | /* add VLAN id in (u16)a0 */ | ||
123 | CMD_VLAN_ADD = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 14), | ||
124 | |||
125 | /* del VLAN id in (u16)a0 */ | ||
126 | CMD_VLAN_DEL = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 15), | ||
127 | |||
128 | /* nic_cfg in (u32)a0 */ | ||
129 | CMD_NIC_CFG = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 16), | ||
130 | |||
131 | /* union vnic_rss_key in mem: (u64)a0=paddr, (u16)a1=len */ | ||
132 | CMD_RSS_KEY = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 17), | ||
133 | |||
134 | /* union vnic_rss_cpu in mem: (u64)a0=paddr, (u16)a1=len */ | ||
135 | CMD_RSS_CPU = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 18), | ||
136 | |||
137 | /* initiate softreset */ | ||
138 | CMD_SOFT_RESET = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 19), | ||
139 | |||
140 | /* softreset status: | ||
141 | * out: a0=0 reset complete, a0=1 reset in progress */ | ||
142 | CMD_SOFT_RESET_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 20), | ||
143 | |||
144 | /* set struct vnic_devcmd_notify buffer in mem: | ||
145 | * in: | ||
146 | * (u64)a0=paddr to notify (set paddr=0 to unset) | ||
147 | * (u32)a1 & 0x00000000ffffffff=sizeof(struct vnic_devcmd_notify) | ||
148 | * (u16)a1 & 0x0000ffff00000000=intr num (-1 for no intr) | ||
149 | * out: | ||
150 | * (u32)a1 = effective size | ||
151 | */ | ||
152 | CMD_NOTIFY = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 21), | ||
153 | |||
154 | /* UNDI API: (u64)a0=paddr to s_PXENV_UNDI_ struct, | ||
155 | * (u8)a1=PXENV_UNDI_xxx */ | ||
156 | CMD_UNDI = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 22), | ||
157 | |||
158 | /* initiate open sequence (u32)a0=flags (see CMD_OPENF_*) */ | ||
159 | CMD_OPEN = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 23), | ||
160 | |||
161 | /* open status: | ||
162 | * out: a0=0 open complete, a0=1 open in progress */ | ||
163 | CMD_OPEN_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 24), | ||
164 | |||
165 | /* close vnic */ | ||
166 | CMD_CLOSE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 25), | ||
167 | |||
168 | /* initialize virtual link: (u32)a0=flags (see CMD_INITF_*) */ | ||
169 | CMD_INIT = _CMDCNW(_CMD_DIR_READ, _CMD_VTYPE_ALL, 26), | ||
170 | |||
171 | /* variant of CMD_INIT, with provisioning info | ||
172 | * (u64)a0=paddr of vnic_devcmd_provinfo | ||
173 | * (u32)a1=sizeof provision info */ | ||
174 | CMD_INIT_PROV_INFO = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 27), | ||
175 | |||
176 | /* enable virtual link */ | ||
177 | CMD_ENABLE = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28), | ||
178 | |||
179 | /* disable virtual link */ | ||
180 | CMD_DISABLE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 29), | ||
181 | |||
182 | /* stats dump all vnics on uplink in mem: (u64)a0=paddr (u32)a1=uif */ | ||
183 | CMD_STATS_DUMP_ALL = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 30), | ||
184 | |||
185 | /* init status: | ||
186 | * out: a0=0 init complete, a0=1 init in progress | ||
187 | * if a0=0, a1=errno */ | ||
188 | CMD_INIT_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 31), | ||
189 | |||
190 | /* INT13 API: (u64)a0=paddr to vnic_int13_params struct | ||
191 | * (u8)a1=INT13_CMD_xxx */ | ||
192 | CMD_INT13 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_FC, 32), | ||
193 | |||
194 | /* logical uplink enable/disable: (u64)a0: 0/1=disable/enable */ | ||
195 | CMD_LOGICAL_UPLINK = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 33), | ||
196 | |||
197 | /* undo initialize of virtual link */ | ||
198 | CMD_DEINIT = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 34), | ||
199 | }; | ||
200 | |||
201 | /* flags for CMD_OPEN */ | ||
202 | #define CMD_OPENF_OPROM 0x1 /* open coming from option rom */ | ||
203 | |||
204 | /* flags for CMD_INIT */ | ||
205 | #define CMD_INITF_DEFAULT_MAC 0x1 /* init with default mac addr */ | ||
206 | |||
207 | /* flags for CMD_PACKET_FILTER */ | ||
208 | #define CMD_PFILTER_DIRECTED 0x01 | ||
209 | #define CMD_PFILTER_MULTICAST 0x02 | ||
210 | #define CMD_PFILTER_BROADCAST 0x04 | ||
211 | #define CMD_PFILTER_PROMISCUOUS 0x08 | ||
212 | #define CMD_PFILTER_ALL_MULTICAST 0x10 | ||
213 | |||
214 | enum vnic_devcmd_status { | ||
215 | STAT_NONE = 0, | ||
216 | STAT_BUSY = 1 << 0, /* cmd in progress */ | ||
217 | STAT_ERROR = 1 << 1, /* last cmd caused error (code in a0) */ | ||
218 | }; | ||
219 | |||
220 | enum vnic_devcmd_error { | ||
221 | ERR_SUCCESS = 0, | ||
222 | ERR_EINVAL = 1, | ||
223 | ERR_EFAULT = 2, | ||
224 | ERR_EPERM = 3, | ||
225 | ERR_EBUSY = 4, | ||
226 | ERR_ECMDUNKNOWN = 5, | ||
227 | ERR_EBADSTATE = 6, | ||
228 | ERR_ENOMEM = 7, | ||
229 | ERR_ETIMEDOUT = 8, | ||
230 | ERR_ELINKDOWN = 9, | ||
231 | }; | ||
232 | |||
233 | struct vnic_devcmd_fw_info { | ||
234 | char fw_version[32]; | ||
235 | char fw_build[32]; | ||
236 | char hw_version[32]; | ||
237 | char hw_serial_number[32]; | ||
238 | }; | ||
239 | |||
240 | struct vnic_devcmd_notify { | ||
241 | u32 csum; /* checksum over following words */ | ||
242 | |||
243 | u32 link_state; /* link up == 1 */ | ||
244 | u32 port_speed; /* effective port speed (rate limit) */ | ||
245 | u32 mtu; /* MTU */ | ||
246 | u32 msglvl; /* requested driver msg lvl */ | ||
247 | u32 uif; /* uplink interface */ | ||
248 | u32 status; /* status bits (see VNIC_STF_*) */ | ||
249 | u32 error; /* error code (see ERR_*) for first ERR */ | ||
250 | u32 link_down_cnt; /* running count of link down transitions */ | ||
251 | }; | ||
252 | #define VNIC_STF_FATAL_ERR 0x0001 /* fatal fw error */ | ||
253 | |||
254 | struct vnic_devcmd_provinfo { | ||
255 | u8 oui[3]; | ||
256 | u8 type; | ||
257 | u8 data[0]; | ||
258 | }; | ||
259 | |||
260 | /* | ||
261 | * Writing cmd register causes STAT_BUSY to get set in status register. | ||
262 | * When cmd completes, STAT_BUSY will be cleared. | ||
263 | * | ||
264 | * If cmd completed successfully STAT_ERROR will be clear | ||
265 | * and args registers contain cmd-specific results. | ||
266 | * | ||
267 | * If cmd error, STAT_ERROR will be set and args[0] contains error code. | ||
268 | * | ||
269 | * status register is read-only. While STAT_BUSY is set, | ||
270 | * all other register contents are read-only. | ||
271 | */ | ||
272 | |||
273 | /* Make sizeof(vnic_devcmd) a power-of-2 for I/O BAR. */ | ||
274 | #define VNIC_DEVCMD_NARGS 15 | ||
275 | struct vnic_devcmd { | ||
276 | u32 status; /* RO */ | ||
277 | u32 cmd; /* RW */ | ||
278 | u64 args[VNIC_DEVCMD_NARGS]; /* RW cmd args (little-endian) */ | ||
279 | }; | ||
280 | |||
281 | #endif /* _VNIC_DEVCMD_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_intr.c b/drivers/scsi/fnic/vnic_intr.c new file mode 100644 index 000000000000..4f4dc8793d23 --- /dev/null +++ b/drivers/scsi/fnic/vnic_intr.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include "vnic_dev.h" | ||
25 | #include "vnic_intr.h" | ||
26 | |||
27 | void vnic_intr_free(struct vnic_intr *intr) | ||
28 | { | ||
29 | intr->ctrl = NULL; | ||
30 | } | ||
31 | |||
32 | int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr, | ||
33 | unsigned int index) | ||
34 | { | ||
35 | intr->index = index; | ||
36 | intr->vdev = vdev; | ||
37 | |||
38 | intr->ctrl = vnic_dev_get_res(vdev, RES_TYPE_INTR_CTRL, index); | ||
39 | if (!intr->ctrl) { | ||
40 | printk(KERN_ERR "Failed to hook INTR[%d].ctrl resource\n", | ||
41 | index); | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer, | ||
49 | unsigned int coalescing_type, unsigned int mask_on_assertion) | ||
50 | { | ||
51 | iowrite32(coalescing_timer, &intr->ctrl->coalescing_timer); | ||
52 | iowrite32(coalescing_type, &intr->ctrl->coalescing_type); | ||
53 | iowrite32(mask_on_assertion, &intr->ctrl->mask_on_assertion); | ||
54 | iowrite32(0, &intr->ctrl->int_credits); | ||
55 | } | ||
56 | |||
57 | void vnic_intr_clean(struct vnic_intr *intr) | ||
58 | { | ||
59 | iowrite32(0, &intr->ctrl->int_credits); | ||
60 | } | ||
diff --git a/drivers/scsi/fnic/vnic_intr.h b/drivers/scsi/fnic/vnic_intr.h new file mode 100644 index 000000000000..d5fb40e7c98e --- /dev/null +++ b/drivers/scsi/fnic/vnic_intr.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_INTR_H_ | ||
19 | #define _VNIC_INTR_H_ | ||
20 | |||
21 | #include <linux/pci.h> | ||
22 | #include "vnic_dev.h" | ||
23 | |||
24 | /* | ||
25 | * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth | ||
26 | * Driver) when both are built with CONFIG options =y | ||
27 | */ | ||
28 | #define vnic_intr_unmask fnic_intr_unmask | ||
29 | #define vnic_intr_mask fnic_intr_mask | ||
30 | #define vnic_intr_return_credits fnic_intr_return_credits | ||
31 | #define vnic_intr_credits fnic_intr_credits | ||
32 | #define vnic_intr_return_all_credits fnic_intr_return_all_credits | ||
33 | #define vnic_intr_legacy_pba fnic_intr_legacy_pba | ||
34 | #define vnic_intr_free fnic_intr_free | ||
35 | #define vnic_intr_alloc fnic_intr_alloc | ||
36 | #define vnic_intr_init fnic_intr_init | ||
37 | #define vnic_intr_clean fnic_intr_clean | ||
38 | |||
39 | #define VNIC_INTR_TIMER_MAX 0xffff | ||
40 | |||
41 | #define VNIC_INTR_TIMER_TYPE_ABS 0 | ||
42 | #define VNIC_INTR_TIMER_TYPE_QUIET 1 | ||
43 | |||
44 | /* Interrupt control */ | ||
45 | struct vnic_intr_ctrl { | ||
46 | u32 coalescing_timer; /* 0x00 */ | ||
47 | u32 pad0; | ||
48 | u32 coalescing_value; /* 0x08 */ | ||
49 | u32 pad1; | ||
50 | u32 coalescing_type; /* 0x10 */ | ||
51 | u32 pad2; | ||
52 | u32 mask_on_assertion; /* 0x18 */ | ||
53 | u32 pad3; | ||
54 | u32 mask; /* 0x20 */ | ||
55 | u32 pad4; | ||
56 | u32 int_credits; /* 0x28 */ | ||
57 | u32 pad5; | ||
58 | u32 int_credit_return; /* 0x30 */ | ||
59 | u32 pad6; | ||
60 | }; | ||
61 | |||
62 | struct vnic_intr { | ||
63 | unsigned int index; | ||
64 | struct vnic_dev *vdev; | ||
65 | struct vnic_intr_ctrl __iomem *ctrl; /* memory-mapped */ | ||
66 | }; | ||
67 | |||
68 | static inline void vnic_intr_unmask(struct vnic_intr *intr) | ||
69 | { | ||
70 | iowrite32(0, &intr->ctrl->mask); | ||
71 | } | ||
72 | |||
73 | static inline void vnic_intr_mask(struct vnic_intr *intr) | ||
74 | { | ||
75 | iowrite32(1, &intr->ctrl->mask); | ||
76 | } | ||
77 | |||
78 | static inline void vnic_intr_return_credits(struct vnic_intr *intr, | ||
79 | unsigned int credits, int unmask, int reset_timer) | ||
80 | { | ||
81 | #define VNIC_INTR_UNMASK_SHIFT 16 | ||
82 | #define VNIC_INTR_RESET_TIMER_SHIFT 17 | ||
83 | |||
84 | u32 int_credit_return = (credits & 0xffff) | | ||
85 | (unmask ? (1 << VNIC_INTR_UNMASK_SHIFT) : 0) | | ||
86 | (reset_timer ? (1 << VNIC_INTR_RESET_TIMER_SHIFT) : 0); | ||
87 | |||
88 | iowrite32(int_credit_return, &intr->ctrl->int_credit_return); | ||
89 | } | ||
90 | |||
91 | static inline unsigned int vnic_intr_credits(struct vnic_intr *intr) | ||
92 | { | ||
93 | return ioread32(&intr->ctrl->int_credits); | ||
94 | } | ||
95 | |||
96 | static inline void vnic_intr_return_all_credits(struct vnic_intr *intr) | ||
97 | { | ||
98 | unsigned int credits = vnic_intr_credits(intr); | ||
99 | int unmask = 1; | ||
100 | int reset_timer = 1; | ||
101 | |||
102 | vnic_intr_return_credits(intr, credits, unmask, reset_timer); | ||
103 | } | ||
104 | |||
105 | static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba) | ||
106 | { | ||
107 | /* read PBA without clearing */ | ||
108 | return ioread32(legacy_pba); | ||
109 | } | ||
110 | |||
111 | void vnic_intr_free(struct vnic_intr *intr); | ||
112 | int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr, | ||
113 | unsigned int index); | ||
114 | void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer, | ||
115 | unsigned int coalescing_type, unsigned int mask_on_assertion); | ||
116 | void vnic_intr_clean(struct vnic_intr *intr); | ||
117 | |||
118 | #endif /* _VNIC_INTR_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_nic.h b/drivers/scsi/fnic/vnic_nic.h new file mode 100644 index 000000000000..f15b83eeaced --- /dev/null +++ b/drivers/scsi/fnic/vnic_nic.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_NIC_H_ | ||
19 | #define _VNIC_NIC_H_ | ||
20 | |||
21 | /* | ||
22 | * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth | ||
23 | * Driver) when both are built with CONFIG options =y | ||
24 | */ | ||
25 | #define vnic_set_nic_cfg fnic_set_nic_cfg | ||
26 | |||
27 | #define NIC_CFG_RSS_DEFAULT_CPU_MASK_FIELD 0xffUL | ||
28 | #define NIC_CFG_RSS_DEFAULT_CPU_SHIFT 0 | ||
29 | #define NIC_CFG_RSS_HASH_TYPE (0xffUL << 8) | ||
30 | #define NIC_CFG_RSS_HASH_TYPE_MASK_FIELD 0xffUL | ||
31 | #define NIC_CFG_RSS_HASH_TYPE_SHIFT 8 | ||
32 | #define NIC_CFG_RSS_HASH_BITS (7UL << 16) | ||
33 | #define NIC_CFG_RSS_HASH_BITS_MASK_FIELD 7UL | ||
34 | #define NIC_CFG_RSS_HASH_BITS_SHIFT 16 | ||
35 | #define NIC_CFG_RSS_BASE_CPU (7UL << 19) | ||
36 | #define NIC_CFG_RSS_BASE_CPU_MASK_FIELD 7UL | ||
37 | #define NIC_CFG_RSS_BASE_CPU_SHIFT 19 | ||
38 | #define NIC_CFG_RSS_ENABLE (1UL << 22) | ||
39 | #define NIC_CFG_RSS_ENABLE_MASK_FIELD 1UL | ||
40 | #define NIC_CFG_RSS_ENABLE_SHIFT 22 | ||
41 | #define NIC_CFG_TSO_IPID_SPLIT_EN (1UL << 23) | ||
42 | #define NIC_CFG_TSO_IPID_SPLIT_EN_MASK_FIELD 1UL | ||
43 | #define NIC_CFG_TSO_IPID_SPLIT_EN_SHIFT 23 | ||
44 | #define NIC_CFG_IG_VLAN_STRIP_EN (1UL << 24) | ||
45 | #define NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD 1UL | ||
46 | #define NIC_CFG_IG_VLAN_STRIP_EN_SHIFT 24 | ||
47 | |||
48 | static inline void vnic_set_nic_cfg(u32 *nic_cfg, | ||
49 | u8 rss_default_cpu, u8 rss_hash_type, | ||
50 | u8 rss_hash_bits, u8 rss_base_cpu, | ||
51 | u8 rss_enable, u8 tso_ipid_split_en, | ||
52 | u8 ig_vlan_strip_en) | ||
53 | { | ||
54 | *nic_cfg = (rss_default_cpu & NIC_CFG_RSS_DEFAULT_CPU_MASK_FIELD) | | ||
55 | ((rss_hash_type & NIC_CFG_RSS_HASH_TYPE_MASK_FIELD) | ||
56 | << NIC_CFG_RSS_HASH_TYPE_SHIFT) | | ||
57 | ((rss_hash_bits & NIC_CFG_RSS_HASH_BITS_MASK_FIELD) | ||
58 | << NIC_CFG_RSS_HASH_BITS_SHIFT) | | ||
59 | ((rss_base_cpu & NIC_CFG_RSS_BASE_CPU_MASK_FIELD) | ||
60 | << NIC_CFG_RSS_BASE_CPU_SHIFT) | | ||
61 | ((rss_enable & NIC_CFG_RSS_ENABLE_MASK_FIELD) | ||
62 | << NIC_CFG_RSS_ENABLE_SHIFT) | | ||
63 | ((tso_ipid_split_en & NIC_CFG_TSO_IPID_SPLIT_EN_MASK_FIELD) | ||
64 | << NIC_CFG_TSO_IPID_SPLIT_EN_SHIFT) | | ||
65 | ((ig_vlan_strip_en & NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD) | ||
66 | << NIC_CFG_IG_VLAN_STRIP_EN_SHIFT); | ||
67 | } | ||
68 | |||
69 | #endif /* _VNIC_NIC_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_resource.h b/drivers/scsi/fnic/vnic_resource.h new file mode 100644 index 000000000000..2d842f79d41a --- /dev/null +++ b/drivers/scsi/fnic/vnic_resource.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_RESOURCE_H_ | ||
19 | #define _VNIC_RESOURCE_H_ | ||
20 | |||
21 | #define VNIC_RES_MAGIC 0x766E6963L /* 'vnic' */ | ||
22 | #define VNIC_RES_VERSION 0x00000000L | ||
23 | |||
24 | /* vNIC resource types */ | ||
25 | enum vnic_res_type { | ||
26 | RES_TYPE_EOL, /* End-of-list */ | ||
27 | RES_TYPE_WQ, /* Work queues */ | ||
28 | RES_TYPE_RQ, /* Receive queues */ | ||
29 | RES_TYPE_CQ, /* Completion queues */ | ||
30 | RES_TYPE_RSVD1, | ||
31 | RES_TYPE_NIC_CFG, /* Enet NIC config registers */ | ||
32 | RES_TYPE_RSVD2, | ||
33 | RES_TYPE_RSVD3, | ||
34 | RES_TYPE_RSVD4, | ||
35 | RES_TYPE_RSVD5, | ||
36 | RES_TYPE_INTR_CTRL, /* Interrupt ctrl table */ | ||
37 | RES_TYPE_INTR_TABLE, /* MSI/MSI-X Interrupt table */ | ||
38 | RES_TYPE_INTR_PBA, /* MSI/MSI-X PBA table */ | ||
39 | RES_TYPE_INTR_PBA_LEGACY, /* Legacy intr status */ | ||
40 | RES_TYPE_RSVD6, | ||
41 | RES_TYPE_RSVD7, | ||
42 | RES_TYPE_DEVCMD, /* Device command region */ | ||
43 | RES_TYPE_PASS_THRU_PAGE, /* Pass-thru page */ | ||
44 | |||
45 | RES_TYPE_MAX, /* Count of resource types */ | ||
46 | }; | ||
47 | |||
48 | struct vnic_resource_header { | ||
49 | u32 magic; | ||
50 | u32 version; | ||
51 | }; | ||
52 | |||
53 | struct vnic_resource { | ||
54 | u8 type; | ||
55 | u8 bar; | ||
56 | u8 pad[2]; | ||
57 | u32 bar_offset; | ||
58 | u32 count; | ||
59 | }; | ||
60 | |||
61 | #endif /* _VNIC_RESOURCE_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_rq.c b/drivers/scsi/fnic/vnic_rq.c new file mode 100644 index 000000000000..bedd0d285630 --- /dev/null +++ b/drivers/scsi/fnic/vnic_rq.c | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/errno.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include "vnic_dev.h" | ||
24 | #include "vnic_rq.h" | ||
25 | |||
26 | static int vnic_rq_alloc_bufs(struct vnic_rq *rq) | ||
27 | { | ||
28 | struct vnic_rq_buf *buf; | ||
29 | struct vnic_dev *vdev; | ||
30 | unsigned int i, j, count = rq->ring.desc_count; | ||
31 | unsigned int blks = VNIC_RQ_BUF_BLKS_NEEDED(count); | ||
32 | |||
33 | vdev = rq->vdev; | ||
34 | |||
35 | for (i = 0; i < blks; i++) { | ||
36 | rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ, GFP_ATOMIC); | ||
37 | if (!rq->bufs[i]) { | ||
38 | printk(KERN_ERR "Failed to alloc rq_bufs\n"); | ||
39 | return -ENOMEM; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | for (i = 0; i < blks; i++) { | ||
44 | buf = rq->bufs[i]; | ||
45 | for (j = 0; j < VNIC_RQ_BUF_BLK_ENTRIES; j++) { | ||
46 | buf->index = i * VNIC_RQ_BUF_BLK_ENTRIES + j; | ||
47 | buf->desc = (u8 *)rq->ring.descs + | ||
48 | rq->ring.desc_size * buf->index; | ||
49 | if (buf->index + 1 == count) { | ||
50 | buf->next = rq->bufs[0]; | ||
51 | break; | ||
52 | } else if (j + 1 == VNIC_RQ_BUF_BLK_ENTRIES) { | ||
53 | buf->next = rq->bufs[i + 1]; | ||
54 | } else { | ||
55 | buf->next = buf + 1; | ||
56 | buf++; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | rq->to_use = rq->to_clean = rq->bufs[0]; | ||
62 | rq->buf_index = 0; | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | void vnic_rq_free(struct vnic_rq *rq) | ||
68 | { | ||
69 | struct vnic_dev *vdev; | ||
70 | unsigned int i; | ||
71 | |||
72 | vdev = rq->vdev; | ||
73 | |||
74 | vnic_dev_free_desc_ring(vdev, &rq->ring); | ||
75 | |||
76 | for (i = 0; i < VNIC_RQ_BUF_BLKS_MAX; i++) { | ||
77 | kfree(rq->bufs[i]); | ||
78 | rq->bufs[i] = NULL; | ||
79 | } | ||
80 | |||
81 | rq->ctrl = NULL; | ||
82 | } | ||
83 | |||
84 | int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, | ||
85 | unsigned int desc_count, unsigned int desc_size) | ||
86 | { | ||
87 | int err; | ||
88 | |||
89 | rq->index = index; | ||
90 | rq->vdev = vdev; | ||
91 | |||
92 | rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index); | ||
93 | if (!rq->ctrl) { | ||
94 | printk(KERN_ERR "Failed to hook RQ[%d] resource\n", index); | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | |||
98 | vnic_rq_disable(rq); | ||
99 | |||
100 | err = vnic_dev_alloc_desc_ring(vdev, &rq->ring, desc_count, desc_size); | ||
101 | if (err) | ||
102 | return err; | ||
103 | |||
104 | err = vnic_rq_alloc_bufs(rq); | ||
105 | if (err) { | ||
106 | vnic_rq_free(rq); | ||
107 | return err; | ||
108 | } | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, | ||
114 | unsigned int error_interrupt_enable, | ||
115 | unsigned int error_interrupt_offset) | ||
116 | { | ||
117 | u64 paddr; | ||
118 | u32 fetch_index; | ||
119 | |||
120 | paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET; | ||
121 | writeq(paddr, &rq->ctrl->ring_base); | ||
122 | iowrite32(rq->ring.desc_count, &rq->ctrl->ring_size); | ||
123 | iowrite32(cq_index, &rq->ctrl->cq_index); | ||
124 | iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable); | ||
125 | iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset); | ||
126 | iowrite32(0, &rq->ctrl->dropped_packet_count); | ||
127 | iowrite32(0, &rq->ctrl->error_status); | ||
128 | |||
129 | /* Use current fetch_index as the ring starting point */ | ||
130 | fetch_index = ioread32(&rq->ctrl->fetch_index); | ||
131 | rq->to_use = rq->to_clean = | ||
132 | &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES] | ||
133 | [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES]; | ||
134 | iowrite32(fetch_index, &rq->ctrl->posted_index); | ||
135 | |||
136 | rq->buf_index = 0; | ||
137 | } | ||
138 | |||
139 | unsigned int vnic_rq_error_status(struct vnic_rq *rq) | ||
140 | { | ||
141 | return ioread32(&rq->ctrl->error_status); | ||
142 | } | ||
143 | |||
144 | void vnic_rq_enable(struct vnic_rq *rq) | ||
145 | { | ||
146 | iowrite32(1, &rq->ctrl->enable); | ||
147 | } | ||
148 | |||
149 | int vnic_rq_disable(struct vnic_rq *rq) | ||
150 | { | ||
151 | unsigned int wait; | ||
152 | |||
153 | iowrite32(0, &rq->ctrl->enable); | ||
154 | |||
155 | /* Wait for HW to ACK disable request */ | ||
156 | for (wait = 0; wait < 100; wait++) { | ||
157 | if (!(ioread32(&rq->ctrl->running))) | ||
158 | return 0; | ||
159 | udelay(1); | ||
160 | } | ||
161 | |||
162 | printk(KERN_ERR "Failed to disable RQ[%d]\n", rq->index); | ||
163 | |||
164 | return -ETIMEDOUT; | ||
165 | } | ||
166 | |||
167 | void vnic_rq_clean(struct vnic_rq *rq, | ||
168 | void (*buf_clean)(struct vnic_rq *rq, struct vnic_rq_buf *buf)) | ||
169 | { | ||
170 | struct vnic_rq_buf *buf; | ||
171 | u32 fetch_index; | ||
172 | |||
173 | BUG_ON(ioread32(&rq->ctrl->enable)); | ||
174 | |||
175 | buf = rq->to_clean; | ||
176 | |||
177 | while (vnic_rq_desc_used(rq) > 0) { | ||
178 | |||
179 | (*buf_clean)(rq, buf); | ||
180 | |||
181 | buf = rq->to_clean = buf->next; | ||
182 | rq->ring.desc_avail++; | ||
183 | } | ||
184 | |||
185 | /* Use current fetch_index as the ring starting point */ | ||
186 | fetch_index = ioread32(&rq->ctrl->fetch_index); | ||
187 | rq->to_use = rq->to_clean = | ||
188 | &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES] | ||
189 | [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES]; | ||
190 | iowrite32(fetch_index, &rq->ctrl->posted_index); | ||
191 | |||
192 | rq->buf_index = 0; | ||
193 | |||
194 | vnic_dev_clear_desc_ring(&rq->ring); | ||
195 | } | ||
196 | |||
diff --git a/drivers/scsi/fnic/vnic_rq.h b/drivers/scsi/fnic/vnic_rq.h new file mode 100644 index 000000000000..aebdfbd6ad3c --- /dev/null +++ b/drivers/scsi/fnic/vnic_rq.h | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_RQ_H_ | ||
19 | #define _VNIC_RQ_H_ | ||
20 | |||
21 | #include <linux/pci.h> | ||
22 | #include "vnic_dev.h" | ||
23 | #include "vnic_cq.h" | ||
24 | |||
25 | /* | ||
26 | * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth | ||
27 | * Driver) when both are built with CONFIG options =y | ||
28 | */ | ||
29 | #define vnic_rq_desc_avail fnic_rq_desc_avail | ||
30 | #define vnic_rq_desc_used fnic_rq_desc_used | ||
31 | #define vnic_rq_next_desc fnic_rq_next_desc | ||
32 | #define vnic_rq_next_index fnic_rq_next_index | ||
33 | #define vnic_rq_next_buf_index fnic_rq_next_buf_index | ||
34 | #define vnic_rq_post fnic_rq_post | ||
35 | #define vnic_rq_posting_soon fnic_rq_posting_soon | ||
36 | #define vnic_rq_return_descs fnic_rq_return_descs | ||
37 | #define vnic_rq_service fnic_rq_service | ||
38 | #define vnic_rq_fill fnic_rq_fill | ||
39 | #define vnic_rq_free fnic_rq_free | ||
40 | #define vnic_rq_alloc fnic_rq_alloc | ||
41 | #define vnic_rq_init fnic_rq_init | ||
42 | #define vnic_rq_error_status fnic_rq_error_status | ||
43 | #define vnic_rq_enable fnic_rq_enable | ||
44 | #define vnic_rq_disable fnic_rq_disable | ||
45 | #define vnic_rq_clean fnic_rq_clean | ||
46 | |||
47 | /* Receive queue control */ | ||
48 | struct vnic_rq_ctrl { | ||
49 | u64 ring_base; /* 0x00 */ | ||
50 | u32 ring_size; /* 0x08 */ | ||
51 | u32 pad0; | ||
52 | u32 posted_index; /* 0x10 */ | ||
53 | u32 pad1; | ||
54 | u32 cq_index; /* 0x18 */ | ||
55 | u32 pad2; | ||
56 | u32 enable; /* 0x20 */ | ||
57 | u32 pad3; | ||
58 | u32 running; /* 0x28 */ | ||
59 | u32 pad4; | ||
60 | u32 fetch_index; /* 0x30 */ | ||
61 | u32 pad5; | ||
62 | u32 error_interrupt_enable; /* 0x38 */ | ||
63 | u32 pad6; | ||
64 | u32 error_interrupt_offset; /* 0x40 */ | ||
65 | u32 pad7; | ||
66 | u32 error_status; /* 0x48 */ | ||
67 | u32 pad8; | ||
68 | u32 dropped_packet_count; /* 0x50 */ | ||
69 | u32 pad9; | ||
70 | u32 dropped_packet_count_rc; /* 0x58 */ | ||
71 | u32 pad10; | ||
72 | }; | ||
73 | |||
74 | /* Break the vnic_rq_buf allocations into blocks of 64 entries */ | ||
75 | #define VNIC_RQ_BUF_BLK_ENTRIES 64 | ||
76 | #define VNIC_RQ_BUF_BLK_SZ \ | ||
77 | (VNIC_RQ_BUF_BLK_ENTRIES * sizeof(struct vnic_rq_buf)) | ||
78 | #define VNIC_RQ_BUF_BLKS_NEEDED(entries) \ | ||
79 | DIV_ROUND_UP(entries, VNIC_RQ_BUF_BLK_ENTRIES) | ||
80 | #define VNIC_RQ_BUF_BLKS_MAX VNIC_RQ_BUF_BLKS_NEEDED(4096) | ||
81 | |||
82 | struct vnic_rq_buf { | ||
83 | struct vnic_rq_buf *next; | ||
84 | dma_addr_t dma_addr; | ||
85 | void *os_buf; | ||
86 | unsigned int os_buf_index; | ||
87 | unsigned int len; | ||
88 | unsigned int index; | ||
89 | void *desc; | ||
90 | }; | ||
91 | |||
92 | struct vnic_rq { | ||
93 | unsigned int index; | ||
94 | struct vnic_dev *vdev; | ||
95 | struct vnic_rq_ctrl __iomem *ctrl; /* memory-mapped */ | ||
96 | struct vnic_dev_ring ring; | ||
97 | struct vnic_rq_buf *bufs[VNIC_RQ_BUF_BLKS_MAX]; | ||
98 | struct vnic_rq_buf *to_use; | ||
99 | struct vnic_rq_buf *to_clean; | ||
100 | void *os_buf_head; | ||
101 | unsigned int buf_index; | ||
102 | unsigned int pkts_outstanding; | ||
103 | }; | ||
104 | |||
105 | static inline unsigned int vnic_rq_desc_avail(struct vnic_rq *rq) | ||
106 | { | ||
107 | /* how many does SW own? */ | ||
108 | return rq->ring.desc_avail; | ||
109 | } | ||
110 | |||
111 | static inline unsigned int vnic_rq_desc_used(struct vnic_rq *rq) | ||
112 | { | ||
113 | /* how many does HW own? */ | ||
114 | return rq->ring.desc_count - rq->ring.desc_avail - 1; | ||
115 | } | ||
116 | |||
117 | static inline void *vnic_rq_next_desc(struct vnic_rq *rq) | ||
118 | { | ||
119 | return rq->to_use->desc; | ||
120 | } | ||
121 | |||
122 | static inline unsigned int vnic_rq_next_index(struct vnic_rq *rq) | ||
123 | { | ||
124 | return rq->to_use->index; | ||
125 | } | ||
126 | |||
127 | static inline unsigned int vnic_rq_next_buf_index(struct vnic_rq *rq) | ||
128 | { | ||
129 | return rq->buf_index++; | ||
130 | } | ||
131 | |||
132 | static inline void vnic_rq_post(struct vnic_rq *rq, | ||
133 | void *os_buf, unsigned int os_buf_index, | ||
134 | dma_addr_t dma_addr, unsigned int len) | ||
135 | { | ||
136 | struct vnic_rq_buf *buf = rq->to_use; | ||
137 | |||
138 | buf->os_buf = os_buf; | ||
139 | buf->os_buf_index = os_buf_index; | ||
140 | buf->dma_addr = dma_addr; | ||
141 | buf->len = len; | ||
142 | |||
143 | buf = buf->next; | ||
144 | rq->to_use = buf; | ||
145 | rq->ring.desc_avail--; | ||
146 | |||
147 | /* Move the posted_index every nth descriptor | ||
148 | */ | ||
149 | |||
150 | #ifndef VNIC_RQ_RETURN_RATE | ||
151 | #define VNIC_RQ_RETURN_RATE 0xf /* keep 2^n - 1 */ | ||
152 | #endif | ||
153 | |||
154 | if ((buf->index & VNIC_RQ_RETURN_RATE) == 0) { | ||
155 | /* Adding write memory barrier prevents compiler and/or CPU | ||
156 | * reordering, thus avoiding descriptor posting before | ||
157 | * descriptor is initialized. Otherwise, hardware can read | ||
158 | * stale descriptor fields. | ||
159 | */ | ||
160 | wmb(); | ||
161 | iowrite32(buf->index, &rq->ctrl->posted_index); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static inline int vnic_rq_posting_soon(struct vnic_rq *rq) | ||
166 | { | ||
167 | return (rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0; | ||
168 | } | ||
169 | |||
170 | static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count) | ||
171 | { | ||
172 | rq->ring.desc_avail += count; | ||
173 | } | ||
174 | |||
175 | enum desc_return_options { | ||
176 | VNIC_RQ_RETURN_DESC, | ||
177 | VNIC_RQ_DEFER_RETURN_DESC, | ||
178 | }; | ||
179 | |||
180 | static inline void vnic_rq_service(struct vnic_rq *rq, | ||
181 | struct cq_desc *cq_desc, u16 completed_index, | ||
182 | int desc_return, void (*buf_service)(struct vnic_rq *rq, | ||
183 | struct cq_desc *cq_desc, struct vnic_rq_buf *buf, | ||
184 | int skipped, void *opaque), void *opaque) | ||
185 | { | ||
186 | struct vnic_rq_buf *buf; | ||
187 | int skipped; | ||
188 | |||
189 | buf = rq->to_clean; | ||
190 | while (1) { | ||
191 | |||
192 | skipped = (buf->index != completed_index); | ||
193 | |||
194 | (*buf_service)(rq, cq_desc, buf, skipped, opaque); | ||
195 | |||
196 | if (desc_return == VNIC_RQ_RETURN_DESC) | ||
197 | rq->ring.desc_avail++; | ||
198 | |||
199 | rq->to_clean = buf->next; | ||
200 | |||
201 | if (!skipped) | ||
202 | break; | ||
203 | |||
204 | buf = rq->to_clean; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | static inline int vnic_rq_fill(struct vnic_rq *rq, | ||
209 | int (*buf_fill)(struct vnic_rq *rq)) | ||
210 | { | ||
211 | int err; | ||
212 | |||
213 | while (vnic_rq_desc_avail(rq) > 1) { | ||
214 | |||
215 | err = (*buf_fill)(rq); | ||
216 | if (err) | ||
217 | return err; | ||
218 | } | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | void vnic_rq_free(struct vnic_rq *rq); | ||
224 | int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, | ||
225 | unsigned int desc_count, unsigned int desc_size); | ||
226 | void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, | ||
227 | unsigned int error_interrupt_enable, | ||
228 | unsigned int error_interrupt_offset); | ||
229 | unsigned int vnic_rq_error_status(struct vnic_rq *rq); | ||
230 | void vnic_rq_enable(struct vnic_rq *rq); | ||
231 | int vnic_rq_disable(struct vnic_rq *rq); | ||
232 | void vnic_rq_clean(struct vnic_rq *rq, | ||
233 | void (*buf_clean)(struct vnic_rq *rq, struct vnic_rq_buf *buf)); | ||
234 | |||
235 | #endif /* _VNIC_RQ_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_scsi.h b/drivers/scsi/fnic/vnic_scsi.h new file mode 100644 index 000000000000..46baa5254001 --- /dev/null +++ b/drivers/scsi/fnic/vnic_scsi.h | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_SCSI_H_ | ||
19 | #define _VNIC_SCSI_H_ | ||
20 | |||
21 | #define VNIC_FNIC_WQ_COPY_COUNT_MIN 1 | ||
22 | #define VNIC_FNIC_WQ_COPY_COUNT_MAX 1 | ||
23 | |||
24 | #define VNIC_FNIC_WQ_DESCS_MIN 64 | ||
25 | #define VNIC_FNIC_WQ_DESCS_MAX 128 | ||
26 | |||
27 | #define VNIC_FNIC_WQ_COPY_DESCS_MIN 64 | ||
28 | #define VNIC_FNIC_WQ_COPY_DESCS_MAX 512 | ||
29 | |||
30 | #define VNIC_FNIC_RQ_DESCS_MIN 64 | ||
31 | #define VNIC_FNIC_RQ_DESCS_MAX 128 | ||
32 | |||
33 | #define VNIC_FNIC_EDTOV_MIN 1000 | ||
34 | #define VNIC_FNIC_EDTOV_MAX 255000 | ||
35 | #define VNIC_FNIC_EDTOV_DEF 2000 | ||
36 | |||
37 | #define VNIC_FNIC_RATOV_MIN 1000 | ||
38 | #define VNIC_FNIC_RATOV_MAX 255000 | ||
39 | |||
40 | #define VNIC_FNIC_MAXDATAFIELDSIZE_MIN 256 | ||
41 | #define VNIC_FNIC_MAXDATAFIELDSIZE_MAX 2112 | ||
42 | |||
43 | #define VNIC_FNIC_FLOGI_RETRIES_MIN 0 | ||
44 | #define VNIC_FNIC_FLOGI_RETRIES_MAX 0xffffffff | ||
45 | #define VNIC_FNIC_FLOGI_RETRIES_DEF 0xffffffff | ||
46 | |||
47 | #define VNIC_FNIC_FLOGI_TIMEOUT_MIN 1000 | ||
48 | #define VNIC_FNIC_FLOGI_TIMEOUT_MAX 255000 | ||
49 | |||
50 | #define VNIC_FNIC_PLOGI_RETRIES_MIN 0 | ||
51 | #define VNIC_FNIC_PLOGI_RETRIES_MAX 255 | ||
52 | #define VNIC_FNIC_PLOGI_RETRIES_DEF 8 | ||
53 | |||
54 | #define VNIC_FNIC_PLOGI_TIMEOUT_MIN 1000 | ||
55 | #define VNIC_FNIC_PLOGI_TIMEOUT_MAX 255000 | ||
56 | |||
57 | #define VNIC_FNIC_IO_THROTTLE_COUNT_MIN 256 | ||
58 | #define VNIC_FNIC_IO_THROTTLE_COUNT_MAX 4096 | ||
59 | |||
60 | #define VNIC_FNIC_LINK_DOWN_TIMEOUT_MIN 0 | ||
61 | #define VNIC_FNIC_LINK_DOWN_TIMEOUT_MAX 240000 | ||
62 | |||
63 | #define VNIC_FNIC_PORT_DOWN_TIMEOUT_MIN 0 | ||
64 | #define VNIC_FNIC_PORT_DOWN_TIMEOUT_MAX 240000 | ||
65 | |||
66 | #define VNIC_FNIC_PORT_DOWN_IO_RETRIES_MIN 0 | ||
67 | #define VNIC_FNIC_PORT_DOWN_IO_RETRIES_MAX 255 | ||
68 | |||
69 | #define VNIC_FNIC_LUNS_PER_TARGET_MIN 1 | ||
70 | #define VNIC_FNIC_LUNS_PER_TARGET_MAX 1024 | ||
71 | |||
72 | /* Device-specific region: scsi configuration */ | ||
73 | struct vnic_fc_config { | ||
74 | u64 node_wwn; | ||
75 | u64 port_wwn; | ||
76 | u32 flags; | ||
77 | u32 wq_enet_desc_count; | ||
78 | u32 wq_copy_desc_count; | ||
79 | u32 rq_desc_count; | ||
80 | u32 flogi_retries; | ||
81 | u32 flogi_timeout; | ||
82 | u32 plogi_retries; | ||
83 | u32 plogi_timeout; | ||
84 | u32 io_throttle_count; | ||
85 | u32 link_down_timeout; | ||
86 | u32 port_down_timeout; | ||
87 | u32 port_down_io_retries; | ||
88 | u32 luns_per_tgt; | ||
89 | u16 maxdatafieldsize; | ||
90 | u16 ed_tov; | ||
91 | u16 ra_tov; | ||
92 | u16 intr_timer; | ||
93 | u8 intr_timer_type; | ||
94 | }; | ||
95 | |||
96 | #define VFCF_FCP_SEQ_LVL_ERR 0x1 /* Enable FCP-2 Error Recovery */ | ||
97 | #define VFCF_PERBI 0x2 /* persistent binding info available */ | ||
98 | |||
99 | #endif /* _VNIC_SCSI_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_stats.h b/drivers/scsi/fnic/vnic_stats.h new file mode 100644 index 000000000000..5372e23c1cb3 --- /dev/null +++ b/drivers/scsi/fnic/vnic_stats.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_STATS_H_ | ||
19 | #define _VNIC_STATS_H_ | ||
20 | |||
21 | /* Tx statistics */ | ||
22 | struct vnic_tx_stats { | ||
23 | u64 tx_frames_ok; | ||
24 | u64 tx_unicast_frames_ok; | ||
25 | u64 tx_multicast_frames_ok; | ||
26 | u64 tx_broadcast_frames_ok; | ||
27 | u64 tx_bytes_ok; | ||
28 | u64 tx_unicast_bytes_ok; | ||
29 | u64 tx_multicast_bytes_ok; | ||
30 | u64 tx_broadcast_bytes_ok; | ||
31 | u64 tx_drops; | ||
32 | u64 tx_errors; | ||
33 | u64 tx_tso; | ||
34 | u64 rsvd[16]; | ||
35 | }; | ||
36 | |||
37 | /* Rx statistics */ | ||
38 | struct vnic_rx_stats { | ||
39 | u64 rx_frames_ok; | ||
40 | u64 rx_frames_total; | ||
41 | u64 rx_unicast_frames_ok; | ||
42 | u64 rx_multicast_frames_ok; | ||
43 | u64 rx_broadcast_frames_ok; | ||
44 | u64 rx_bytes_ok; | ||
45 | u64 rx_unicast_bytes_ok; | ||
46 | u64 rx_multicast_bytes_ok; | ||
47 | u64 rx_broadcast_bytes_ok; | ||
48 | u64 rx_drop; | ||
49 | u64 rx_no_bufs; | ||
50 | u64 rx_errors; | ||
51 | u64 rx_rss; | ||
52 | u64 rx_crc_errors; | ||
53 | u64 rx_frames_64; | ||
54 | u64 rx_frames_127; | ||
55 | u64 rx_frames_255; | ||
56 | u64 rx_frames_511; | ||
57 | u64 rx_frames_1023; | ||
58 | u64 rx_frames_1518; | ||
59 | u64 rx_frames_to_max; | ||
60 | u64 rsvd[16]; | ||
61 | }; | ||
62 | |||
63 | struct vnic_stats { | ||
64 | struct vnic_tx_stats tx; | ||
65 | struct vnic_rx_stats rx; | ||
66 | }; | ||
67 | |||
68 | #endif /* _VNIC_STATS_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_wq.c b/drivers/scsi/fnic/vnic_wq.c new file mode 100644 index 000000000000..1f9ea790d130 --- /dev/null +++ b/drivers/scsi/fnic/vnic_wq.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/errno.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include "vnic_dev.h" | ||
24 | #include "vnic_wq.h" | ||
25 | |||
26 | static int vnic_wq_alloc_bufs(struct vnic_wq *wq) | ||
27 | { | ||
28 | struct vnic_wq_buf *buf; | ||
29 | struct vnic_dev *vdev; | ||
30 | unsigned int i, j, count = wq->ring.desc_count; | ||
31 | unsigned int blks = VNIC_WQ_BUF_BLKS_NEEDED(count); | ||
32 | |||
33 | vdev = wq->vdev; | ||
34 | |||
35 | for (i = 0; i < blks; i++) { | ||
36 | wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ, GFP_ATOMIC); | ||
37 | if (!wq->bufs[i]) { | ||
38 | printk(KERN_ERR "Failed to alloc wq_bufs\n"); | ||
39 | return -ENOMEM; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | for (i = 0; i < blks; i++) { | ||
44 | buf = wq->bufs[i]; | ||
45 | for (j = 0; j < VNIC_WQ_BUF_BLK_ENTRIES; j++) { | ||
46 | buf->index = i * VNIC_WQ_BUF_BLK_ENTRIES + j; | ||
47 | buf->desc = (u8 *)wq->ring.descs + | ||
48 | wq->ring.desc_size * buf->index; | ||
49 | if (buf->index + 1 == count) { | ||
50 | buf->next = wq->bufs[0]; | ||
51 | break; | ||
52 | } else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES) { | ||
53 | buf->next = wq->bufs[i + 1]; | ||
54 | } else { | ||
55 | buf->next = buf + 1; | ||
56 | buf++; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | wq->to_use = wq->to_clean = wq->bufs[0]; | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | void vnic_wq_free(struct vnic_wq *wq) | ||
67 | { | ||
68 | struct vnic_dev *vdev; | ||
69 | unsigned int i; | ||
70 | |||
71 | vdev = wq->vdev; | ||
72 | |||
73 | vnic_dev_free_desc_ring(vdev, &wq->ring); | ||
74 | |||
75 | for (i = 0; i < VNIC_WQ_BUF_BLKS_MAX; i++) { | ||
76 | kfree(wq->bufs[i]); | ||
77 | wq->bufs[i] = NULL; | ||
78 | } | ||
79 | |||
80 | wq->ctrl = NULL; | ||
81 | |||
82 | } | ||
83 | |||
84 | int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index, | ||
85 | unsigned int desc_count, unsigned int desc_size) | ||
86 | { | ||
87 | int err; | ||
88 | |||
89 | wq->index = index; | ||
90 | wq->vdev = vdev; | ||
91 | |||
92 | wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_WQ, index); | ||
93 | if (!wq->ctrl) { | ||
94 | printk(KERN_ERR "Failed to hook WQ[%d] resource\n", index); | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | |||
98 | vnic_wq_disable(wq); | ||
99 | |||
100 | err = vnic_dev_alloc_desc_ring(vdev, &wq->ring, desc_count, desc_size); | ||
101 | if (err) | ||
102 | return err; | ||
103 | |||
104 | err = vnic_wq_alloc_bufs(wq); | ||
105 | if (err) { | ||
106 | vnic_wq_free(wq); | ||
107 | return err; | ||
108 | } | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index, | ||
114 | unsigned int error_interrupt_enable, | ||
115 | unsigned int error_interrupt_offset) | ||
116 | { | ||
117 | u64 paddr; | ||
118 | |||
119 | paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET; | ||
120 | writeq(paddr, &wq->ctrl->ring_base); | ||
121 | iowrite32(wq->ring.desc_count, &wq->ctrl->ring_size); | ||
122 | iowrite32(0, &wq->ctrl->fetch_index); | ||
123 | iowrite32(0, &wq->ctrl->posted_index); | ||
124 | iowrite32(cq_index, &wq->ctrl->cq_index); | ||
125 | iowrite32(error_interrupt_enable, &wq->ctrl->error_interrupt_enable); | ||
126 | iowrite32(error_interrupt_offset, &wq->ctrl->error_interrupt_offset); | ||
127 | iowrite32(0, &wq->ctrl->error_status); | ||
128 | } | ||
129 | |||
130 | unsigned int vnic_wq_error_status(struct vnic_wq *wq) | ||
131 | { | ||
132 | return ioread32(&wq->ctrl->error_status); | ||
133 | } | ||
134 | |||
135 | void vnic_wq_enable(struct vnic_wq *wq) | ||
136 | { | ||
137 | iowrite32(1, &wq->ctrl->enable); | ||
138 | } | ||
139 | |||
140 | int vnic_wq_disable(struct vnic_wq *wq) | ||
141 | { | ||
142 | unsigned int wait; | ||
143 | |||
144 | iowrite32(0, &wq->ctrl->enable); | ||
145 | |||
146 | /* Wait for HW to ACK disable request */ | ||
147 | for (wait = 0; wait < 100; wait++) { | ||
148 | if (!(ioread32(&wq->ctrl->running))) | ||
149 | return 0; | ||
150 | udelay(1); | ||
151 | } | ||
152 | |||
153 | printk(KERN_ERR "Failed to disable WQ[%d]\n", wq->index); | ||
154 | |||
155 | return -ETIMEDOUT; | ||
156 | } | ||
157 | |||
158 | void vnic_wq_clean(struct vnic_wq *wq, | ||
159 | void (*buf_clean)(struct vnic_wq *wq, struct vnic_wq_buf *buf)) | ||
160 | { | ||
161 | struct vnic_wq_buf *buf; | ||
162 | |||
163 | BUG_ON(ioread32(&wq->ctrl->enable)); | ||
164 | |||
165 | buf = wq->to_clean; | ||
166 | |||
167 | while (vnic_wq_desc_used(wq) > 0) { | ||
168 | |||
169 | (*buf_clean)(wq, buf); | ||
170 | |||
171 | buf = wq->to_clean = buf->next; | ||
172 | wq->ring.desc_avail++; | ||
173 | } | ||
174 | |||
175 | wq->to_use = wq->to_clean = wq->bufs[0]; | ||
176 | |||
177 | iowrite32(0, &wq->ctrl->fetch_index); | ||
178 | iowrite32(0, &wq->ctrl->posted_index); | ||
179 | iowrite32(0, &wq->ctrl->error_status); | ||
180 | |||
181 | vnic_dev_clear_desc_ring(&wq->ring); | ||
182 | } | ||
diff --git a/drivers/scsi/fnic/vnic_wq.h b/drivers/scsi/fnic/vnic_wq.h new file mode 100644 index 000000000000..5cd094f79281 --- /dev/null +++ b/drivers/scsi/fnic/vnic_wq.h | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_WQ_H_ | ||
19 | #define _VNIC_WQ_H_ | ||
20 | |||
21 | #include <linux/pci.h> | ||
22 | #include "vnic_dev.h" | ||
23 | #include "vnic_cq.h" | ||
24 | |||
25 | /* | ||
26 | * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth | ||
27 | * Driver) when both are built with CONFIG options =y | ||
28 | */ | ||
29 | #define vnic_wq_desc_avail fnic_wq_desc_avail | ||
30 | #define vnic_wq_desc_used fnic_wq_desc_used | ||
31 | #define vnic_wq_next_desc fni_cwq_next_desc | ||
32 | #define vnic_wq_post fnic_wq_post | ||
33 | #define vnic_wq_service fnic_wq_service | ||
34 | #define vnic_wq_free fnic_wq_free | ||
35 | #define vnic_wq_alloc fnic_wq_alloc | ||
36 | #define vnic_wq_init fnic_wq_init | ||
37 | #define vnic_wq_error_status fnic_wq_error_status | ||
38 | #define vnic_wq_enable fnic_wq_enable | ||
39 | #define vnic_wq_disable fnic_wq_disable | ||
40 | #define vnic_wq_clean fnic_wq_clean | ||
41 | |||
42 | /* Work queue control */ | ||
43 | struct vnic_wq_ctrl { | ||
44 | u64 ring_base; /* 0x00 */ | ||
45 | u32 ring_size; /* 0x08 */ | ||
46 | u32 pad0; | ||
47 | u32 posted_index; /* 0x10 */ | ||
48 | u32 pad1; | ||
49 | u32 cq_index; /* 0x18 */ | ||
50 | u32 pad2; | ||
51 | u32 enable; /* 0x20 */ | ||
52 | u32 pad3; | ||
53 | u32 running; /* 0x28 */ | ||
54 | u32 pad4; | ||
55 | u32 fetch_index; /* 0x30 */ | ||
56 | u32 pad5; | ||
57 | u32 dca_value; /* 0x38 */ | ||
58 | u32 pad6; | ||
59 | u32 error_interrupt_enable; /* 0x40 */ | ||
60 | u32 pad7; | ||
61 | u32 error_interrupt_offset; /* 0x48 */ | ||
62 | u32 pad8; | ||
63 | u32 error_status; /* 0x50 */ | ||
64 | u32 pad9; | ||
65 | }; | ||
66 | |||
67 | struct vnic_wq_buf { | ||
68 | struct vnic_wq_buf *next; | ||
69 | dma_addr_t dma_addr; | ||
70 | void *os_buf; | ||
71 | unsigned int len; | ||
72 | unsigned int index; | ||
73 | int sop; | ||
74 | void *desc; | ||
75 | }; | ||
76 | |||
77 | /* Break the vnic_wq_buf allocations into blocks of 64 entries */ | ||
78 | #define VNIC_WQ_BUF_BLK_ENTRIES 64 | ||
79 | #define VNIC_WQ_BUF_BLK_SZ \ | ||
80 | (VNIC_WQ_BUF_BLK_ENTRIES * sizeof(struct vnic_wq_buf)) | ||
81 | #define VNIC_WQ_BUF_BLKS_NEEDED(entries) \ | ||
82 | DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES) | ||
83 | #define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096) | ||
84 | |||
85 | struct vnic_wq { | ||
86 | unsigned int index; | ||
87 | struct vnic_dev *vdev; | ||
88 | struct vnic_wq_ctrl __iomem *ctrl; /* memory-mapped */ | ||
89 | struct vnic_dev_ring ring; | ||
90 | struct vnic_wq_buf *bufs[VNIC_WQ_BUF_BLKS_MAX]; | ||
91 | struct vnic_wq_buf *to_use; | ||
92 | struct vnic_wq_buf *to_clean; | ||
93 | unsigned int pkts_outstanding; | ||
94 | }; | ||
95 | |||
96 | static inline unsigned int vnic_wq_desc_avail(struct vnic_wq *wq) | ||
97 | { | ||
98 | /* how many does SW own? */ | ||
99 | return wq->ring.desc_avail; | ||
100 | } | ||
101 | |||
102 | static inline unsigned int vnic_wq_desc_used(struct vnic_wq *wq) | ||
103 | { | ||
104 | /* how many does HW own? */ | ||
105 | return wq->ring.desc_count - wq->ring.desc_avail - 1; | ||
106 | } | ||
107 | |||
108 | static inline void *vnic_wq_next_desc(struct vnic_wq *wq) | ||
109 | { | ||
110 | return wq->to_use->desc; | ||
111 | } | ||
112 | |||
113 | static inline void vnic_wq_post(struct vnic_wq *wq, | ||
114 | void *os_buf, dma_addr_t dma_addr, | ||
115 | unsigned int len, int sop, int eop) | ||
116 | { | ||
117 | struct vnic_wq_buf *buf = wq->to_use; | ||
118 | |||
119 | buf->sop = sop; | ||
120 | buf->os_buf = eop ? os_buf : NULL; | ||
121 | buf->dma_addr = dma_addr; | ||
122 | buf->len = len; | ||
123 | |||
124 | buf = buf->next; | ||
125 | if (eop) { | ||
126 | /* Adding write memory barrier prevents compiler and/or CPU | ||
127 | * reordering, thus avoiding descriptor posting before | ||
128 | * descriptor is initialized. Otherwise, hardware can read | ||
129 | * stale descriptor fields. | ||
130 | */ | ||
131 | wmb(); | ||
132 | iowrite32(buf->index, &wq->ctrl->posted_index); | ||
133 | } | ||
134 | wq->to_use = buf; | ||
135 | |||
136 | wq->ring.desc_avail--; | ||
137 | } | ||
138 | |||
139 | static inline void vnic_wq_service(struct vnic_wq *wq, | ||
140 | struct cq_desc *cq_desc, u16 completed_index, | ||
141 | void (*buf_service)(struct vnic_wq *wq, | ||
142 | struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque), | ||
143 | void *opaque) | ||
144 | { | ||
145 | struct vnic_wq_buf *buf; | ||
146 | |||
147 | buf = wq->to_clean; | ||
148 | while (1) { | ||
149 | |||
150 | (*buf_service)(wq, cq_desc, buf, opaque); | ||
151 | |||
152 | wq->ring.desc_avail++; | ||
153 | |||
154 | wq->to_clean = buf->next; | ||
155 | |||
156 | if (buf->index == completed_index) | ||
157 | break; | ||
158 | |||
159 | buf = wq->to_clean; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | void vnic_wq_free(struct vnic_wq *wq); | ||
164 | int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index, | ||
165 | unsigned int desc_count, unsigned int desc_size); | ||
166 | void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index, | ||
167 | unsigned int error_interrupt_enable, | ||
168 | unsigned int error_interrupt_offset); | ||
169 | unsigned int vnic_wq_error_status(struct vnic_wq *wq); | ||
170 | void vnic_wq_enable(struct vnic_wq *wq); | ||
171 | int vnic_wq_disable(struct vnic_wq *wq); | ||
172 | void vnic_wq_clean(struct vnic_wq *wq, | ||
173 | void (*buf_clean)(struct vnic_wq *wq, struct vnic_wq_buf *buf)); | ||
174 | |||
175 | #endif /* _VNIC_WQ_H_ */ | ||
diff --git a/drivers/scsi/fnic/vnic_wq_copy.c b/drivers/scsi/fnic/vnic_wq_copy.c new file mode 100644 index 000000000000..9eab7e7caf38 --- /dev/null +++ b/drivers/scsi/fnic/vnic_wq_copy.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/errno.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include "vnic_wq_copy.h" | ||
24 | |||
25 | void vnic_wq_copy_enable(struct vnic_wq_copy *wq) | ||
26 | { | ||
27 | iowrite32(1, &wq->ctrl->enable); | ||
28 | } | ||
29 | |||
30 | int vnic_wq_copy_disable(struct vnic_wq_copy *wq) | ||
31 | { | ||
32 | unsigned int wait; | ||
33 | |||
34 | iowrite32(0, &wq->ctrl->enable); | ||
35 | |||
36 | /* Wait for HW to ACK disable request */ | ||
37 | for (wait = 0; wait < 100; wait++) { | ||
38 | if (!(ioread32(&wq->ctrl->running))) | ||
39 | return 0; | ||
40 | udelay(1); | ||
41 | } | ||
42 | |||
43 | printk(KERN_ERR "Failed to disable Copy WQ[%d]," | ||
44 | " fetch index=%d, posted_index=%d\n", | ||
45 | wq->index, ioread32(&wq->ctrl->fetch_index), | ||
46 | ioread32(&wq->ctrl->posted_index)); | ||
47 | |||
48 | return -ENODEV; | ||
49 | } | ||
50 | |||
51 | void vnic_wq_copy_clean(struct vnic_wq_copy *wq, | ||
52 | void (*q_clean)(struct vnic_wq_copy *wq, | ||
53 | struct fcpio_host_req *wq_desc)) | ||
54 | { | ||
55 | BUG_ON(ioread32(&wq->ctrl->enable)); | ||
56 | |||
57 | if (vnic_wq_copy_desc_in_use(wq)) | ||
58 | vnic_wq_copy_service(wq, -1, q_clean); | ||
59 | |||
60 | wq->to_use_index = wq->to_clean_index = 0; | ||
61 | |||
62 | iowrite32(0, &wq->ctrl->fetch_index); | ||
63 | iowrite32(0, &wq->ctrl->posted_index); | ||
64 | iowrite32(0, &wq->ctrl->error_status); | ||
65 | |||
66 | vnic_dev_clear_desc_ring(&wq->ring); | ||
67 | } | ||
68 | |||
69 | void vnic_wq_copy_free(struct vnic_wq_copy *wq) | ||
70 | { | ||
71 | struct vnic_dev *vdev; | ||
72 | |||
73 | vdev = wq->vdev; | ||
74 | vnic_dev_free_desc_ring(vdev, &wq->ring); | ||
75 | wq->ctrl = NULL; | ||
76 | } | ||
77 | |||
78 | int vnic_wq_copy_alloc(struct vnic_dev *vdev, struct vnic_wq_copy *wq, | ||
79 | unsigned int index, unsigned int desc_count, | ||
80 | unsigned int desc_size) | ||
81 | { | ||
82 | int err; | ||
83 | |||
84 | wq->index = index; | ||
85 | wq->vdev = vdev; | ||
86 | wq->to_use_index = wq->to_clean_index = 0; | ||
87 | wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_WQ, index); | ||
88 | if (!wq->ctrl) { | ||
89 | printk(KERN_ERR "Failed to hook COPY WQ[%d] resource\n", index); | ||
90 | return -EINVAL; | ||
91 | } | ||
92 | |||
93 | vnic_wq_copy_disable(wq); | ||
94 | |||
95 | err = vnic_dev_alloc_desc_ring(vdev, &wq->ring, desc_count, desc_size); | ||
96 | if (err) | ||
97 | return err; | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | void vnic_wq_copy_init(struct vnic_wq_copy *wq, unsigned int cq_index, | ||
103 | unsigned int error_interrupt_enable, | ||
104 | unsigned int error_interrupt_offset) | ||
105 | { | ||
106 | u64 paddr; | ||
107 | |||
108 | paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET; | ||
109 | writeq(paddr, &wq->ctrl->ring_base); | ||
110 | iowrite32(wq->ring.desc_count, &wq->ctrl->ring_size); | ||
111 | iowrite32(0, &wq->ctrl->fetch_index); | ||
112 | iowrite32(0, &wq->ctrl->posted_index); | ||
113 | iowrite32(cq_index, &wq->ctrl->cq_index); | ||
114 | iowrite32(error_interrupt_enable, &wq->ctrl->error_interrupt_enable); | ||
115 | iowrite32(error_interrupt_offset, &wq->ctrl->error_interrupt_offset); | ||
116 | } | ||
117 | |||
diff --git a/drivers/scsi/fnic/vnic_wq_copy.h b/drivers/scsi/fnic/vnic_wq_copy.h new file mode 100644 index 000000000000..6aff9740c3df --- /dev/null +++ b/drivers/scsi/fnic/vnic_wq_copy.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _VNIC_WQ_COPY_H_ | ||
19 | #define _VNIC_WQ_COPY_H_ | ||
20 | |||
21 | #include <linux/pci.h> | ||
22 | #include "vnic_wq.h" | ||
23 | #include "fcpio.h" | ||
24 | |||
25 | #define VNIC_WQ_COPY_MAX 1 | ||
26 | |||
27 | struct vnic_wq_copy { | ||
28 | unsigned int index; | ||
29 | struct vnic_dev *vdev; | ||
30 | struct vnic_wq_ctrl __iomem *ctrl; /* memory-mapped */ | ||
31 | struct vnic_dev_ring ring; | ||
32 | unsigned to_use_index; | ||
33 | unsigned to_clean_index; | ||
34 | }; | ||
35 | |||
36 | static inline unsigned int vnic_wq_copy_desc_avail(struct vnic_wq_copy *wq) | ||
37 | { | ||
38 | return wq->ring.desc_avail; | ||
39 | } | ||
40 | |||
41 | static inline unsigned int vnic_wq_copy_desc_in_use(struct vnic_wq_copy *wq) | ||
42 | { | ||
43 | return wq->ring.desc_count - 1 - wq->ring.desc_avail; | ||
44 | } | ||
45 | |||
46 | static inline void *vnic_wq_copy_next_desc(struct vnic_wq_copy *wq) | ||
47 | { | ||
48 | struct fcpio_host_req *desc = wq->ring.descs; | ||
49 | return &desc[wq->to_use_index]; | ||
50 | } | ||
51 | |||
52 | static inline void vnic_wq_copy_post(struct vnic_wq_copy *wq) | ||
53 | { | ||
54 | |||
55 | ((wq->to_use_index + 1) == wq->ring.desc_count) ? | ||
56 | (wq->to_use_index = 0) : (wq->to_use_index++); | ||
57 | wq->ring.desc_avail--; | ||
58 | |||
59 | /* Adding write memory barrier prevents compiler and/or CPU | ||
60 | * reordering, thus avoiding descriptor posting before | ||
61 | * descriptor is initialized. Otherwise, hardware can read | ||
62 | * stale descriptor fields. | ||
63 | */ | ||
64 | wmb(); | ||
65 | |||
66 | iowrite32(wq->to_use_index, &wq->ctrl->posted_index); | ||
67 | } | ||
68 | |||
69 | static inline void vnic_wq_copy_desc_process(struct vnic_wq_copy *wq, u16 index) | ||
70 | { | ||
71 | unsigned int cnt; | ||
72 | |||
73 | if (wq->to_clean_index <= index) | ||
74 | cnt = (index - wq->to_clean_index) + 1; | ||
75 | else | ||
76 | cnt = wq->ring.desc_count - wq->to_clean_index + index + 1; | ||
77 | |||
78 | wq->to_clean_index = ((index + 1) % wq->ring.desc_count); | ||
79 | wq->ring.desc_avail += cnt; | ||
80 | |||
81 | } | ||
82 | |||
83 | static inline void vnic_wq_copy_service(struct vnic_wq_copy *wq, | ||
84 | u16 completed_index, | ||
85 | void (*q_service)(struct vnic_wq_copy *wq, | ||
86 | struct fcpio_host_req *wq_desc)) | ||
87 | { | ||
88 | struct fcpio_host_req *wq_desc = wq->ring.descs; | ||
89 | unsigned int curr_index; | ||
90 | |||
91 | while (1) { | ||
92 | |||
93 | if (q_service) | ||
94 | (*q_service)(wq, &wq_desc[wq->to_clean_index]); | ||
95 | |||
96 | wq->ring.desc_avail++; | ||
97 | |||
98 | curr_index = wq->to_clean_index; | ||
99 | |||
100 | /* increment the to-clean index so that we start | ||
101 | * with an unprocessed index next time we enter the loop | ||
102 | */ | ||
103 | ((wq->to_clean_index + 1) == wq->ring.desc_count) ? | ||
104 | (wq->to_clean_index = 0) : (wq->to_clean_index++); | ||
105 | |||
106 | if (curr_index == completed_index) | ||
107 | break; | ||
108 | |||
109 | /* we have cleaned all the entries */ | ||
110 | if ((completed_index == (u16)-1) && | ||
111 | (wq->to_clean_index == wq->to_use_index)) | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void vnic_wq_copy_enable(struct vnic_wq_copy *wq); | ||
117 | int vnic_wq_copy_disable(struct vnic_wq_copy *wq); | ||
118 | void vnic_wq_copy_free(struct vnic_wq_copy *wq); | ||
119 | int vnic_wq_copy_alloc(struct vnic_dev *vdev, struct vnic_wq_copy *wq, | ||
120 | unsigned int index, unsigned int desc_count, unsigned int desc_size); | ||
121 | void vnic_wq_copy_init(struct vnic_wq_copy *wq, unsigned int cq_index, | ||
122 | unsigned int error_interrupt_enable, | ||
123 | unsigned int error_interrupt_offset); | ||
124 | void vnic_wq_copy_clean(struct vnic_wq_copy *wq, | ||
125 | void (*q_clean)(struct vnic_wq_copy *wq, | ||
126 | struct fcpio_host_req *wq_desc)); | ||
127 | |||
128 | #endif /* _VNIC_WQ_COPY_H_ */ | ||
diff --git a/drivers/scsi/fnic/wq_enet_desc.h b/drivers/scsi/fnic/wq_enet_desc.h new file mode 100644 index 000000000000..b121cbad18b8 --- /dev/null +++ b/drivers/scsi/fnic/wq_enet_desc.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Cisco Systems, Inc. All rights reserved. | ||
3 | * Copyright 2007 Nuova Systems, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | ||
18 | #ifndef _WQ_ENET_DESC_H_ | ||
19 | #define _WQ_ENET_DESC_H_ | ||
20 | |||
21 | /* Ethernet work queue descriptor: 16B */ | ||
22 | struct wq_enet_desc { | ||
23 | __le64 address; | ||
24 | __le16 length; | ||
25 | __le16 mss_loopback; | ||
26 | __le16 header_length_flags; | ||
27 | __le16 vlan_tag; | ||
28 | }; | ||
29 | |||
30 | #define WQ_ENET_ADDR_BITS 64 | ||
31 | #define WQ_ENET_LEN_BITS 14 | ||
32 | #define WQ_ENET_LEN_MASK ((1 << WQ_ENET_LEN_BITS) - 1) | ||
33 | #define WQ_ENET_MSS_BITS 14 | ||
34 | #define WQ_ENET_MSS_MASK ((1 << WQ_ENET_MSS_BITS) - 1) | ||
35 | #define WQ_ENET_MSS_SHIFT 2 | ||
36 | #define WQ_ENET_LOOPBACK_SHIFT 1 | ||
37 | #define WQ_ENET_HDRLEN_BITS 10 | ||
38 | #define WQ_ENET_HDRLEN_MASK ((1 << WQ_ENET_HDRLEN_BITS) - 1) | ||
39 | #define WQ_ENET_FLAGS_OM_BITS 2 | ||
40 | #define WQ_ENET_FLAGS_OM_MASK ((1 << WQ_ENET_FLAGS_OM_BITS) - 1) | ||
41 | #define WQ_ENET_FLAGS_EOP_SHIFT 12 | ||
42 | #define WQ_ENET_FLAGS_CQ_ENTRY_SHIFT 13 | ||
43 | #define WQ_ENET_FLAGS_FCOE_ENCAP_SHIFT 14 | ||
44 | #define WQ_ENET_FLAGS_VLAN_TAG_INSERT_SHIFT 15 | ||
45 | |||
46 | #define WQ_ENET_OFFLOAD_MODE_CSUM 0 | ||
47 | #define WQ_ENET_OFFLOAD_MODE_RESERVED 1 | ||
48 | #define WQ_ENET_OFFLOAD_MODE_CSUM_L4 2 | ||
49 | #define WQ_ENET_OFFLOAD_MODE_TSO 3 | ||
50 | |||
51 | static inline void wq_enet_desc_enc(struct wq_enet_desc *desc, | ||
52 | u64 address, u16 length, u16 mss, u16 header_length, | ||
53 | u8 offload_mode, u8 eop, u8 cq_entry, u8 fcoe_encap, | ||
54 | u8 vlan_tag_insert, u16 vlan_tag, u8 loopback) | ||
55 | { | ||
56 | desc->address = cpu_to_le64(address); | ||
57 | desc->length = cpu_to_le16(length & WQ_ENET_LEN_MASK); | ||
58 | desc->mss_loopback = cpu_to_le16((mss & WQ_ENET_MSS_MASK) << | ||
59 | WQ_ENET_MSS_SHIFT | (loopback & 1) << WQ_ENET_LOOPBACK_SHIFT); | ||
60 | desc->header_length_flags = cpu_to_le16( | ||
61 | (header_length & WQ_ENET_HDRLEN_MASK) | | ||
62 | (offload_mode & WQ_ENET_FLAGS_OM_MASK) << WQ_ENET_HDRLEN_BITS | | ||
63 | (eop & 1) << WQ_ENET_FLAGS_EOP_SHIFT | | ||
64 | (cq_entry & 1) << WQ_ENET_FLAGS_CQ_ENTRY_SHIFT | | ||
65 | (fcoe_encap & 1) << WQ_ENET_FLAGS_FCOE_ENCAP_SHIFT | | ||
66 | (vlan_tag_insert & 1) << WQ_ENET_FLAGS_VLAN_TAG_INSERT_SHIFT); | ||
67 | desc->vlan_tag = cpu_to_le16(vlan_tag); | ||
68 | } | ||
69 | |||
70 | static inline void wq_enet_desc_dec(struct wq_enet_desc *desc, | ||
71 | u64 *address, u16 *length, u16 *mss, u16 *header_length, | ||
72 | u8 *offload_mode, u8 *eop, u8 *cq_entry, u8 *fcoe_encap, | ||
73 | u8 *vlan_tag_insert, u16 *vlan_tag, u8 *loopback) | ||
74 | { | ||
75 | *address = le64_to_cpu(desc->address); | ||
76 | *length = le16_to_cpu(desc->length) & WQ_ENET_LEN_MASK; | ||
77 | *mss = (le16_to_cpu(desc->mss_loopback) >> WQ_ENET_MSS_SHIFT) & | ||
78 | WQ_ENET_MSS_MASK; | ||
79 | *loopback = (u8)((le16_to_cpu(desc->mss_loopback) >> | ||
80 | WQ_ENET_LOOPBACK_SHIFT) & 1); | ||
81 | *header_length = le16_to_cpu(desc->header_length_flags) & | ||
82 | WQ_ENET_HDRLEN_MASK; | ||
83 | *offload_mode = (u8)((le16_to_cpu(desc->header_length_flags) >> | ||
84 | WQ_ENET_HDRLEN_BITS) & WQ_ENET_FLAGS_OM_MASK); | ||
85 | *eop = (u8)((le16_to_cpu(desc->header_length_flags) >> | ||
86 | WQ_ENET_FLAGS_EOP_SHIFT) & 1); | ||
87 | *cq_entry = (u8)((le16_to_cpu(desc->header_length_flags) >> | ||
88 | WQ_ENET_FLAGS_CQ_ENTRY_SHIFT) & 1); | ||
89 | *fcoe_encap = (u8)((le16_to_cpu(desc->header_length_flags) >> | ||
90 | WQ_ENET_FLAGS_FCOE_ENCAP_SHIFT) & 1); | ||
91 | *vlan_tag_insert = (u8)((le16_to_cpu(desc->header_length_flags) >> | ||
92 | WQ_ENET_FLAGS_VLAN_TAG_INSERT_SHIFT) & 1); | ||
93 | *vlan_tag = le16_to_cpu(desc->vlan_tag); | ||
94 | } | ||
95 | |||
96 | #endif /* _WQ_ENET_DESC_H_ */ | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index babd4cc0cb25..36b1d1052ba1 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -69,7 +69,7 @@ | |||
69 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" | 69 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" |
70 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" | 70 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" |
71 | #define MPT2SAS_DRIVER_VERSION "01.100.02.00" | 71 | #define MPT2SAS_DRIVER_VERSION "01.100.02.00" |
72 | #define MPT2SAS_MAJOR_VERSION 00 | 72 | #define MPT2SAS_MAJOR_VERSION 01 |
73 | #define MPT2SAS_MINOR_VERSION 100 | 73 | #define MPT2SAS_MINOR_VERSION 100 |
74 | #define MPT2SAS_BUILD_VERSION 02 | 74 | #define MPT2SAS_BUILD_VERSION 02 |
75 | #define MPT2SAS_RELEASE_VERSION 00 | 75 | #define MPT2SAS_RELEASE_VERSION 00 |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 6f51ca485f35..e2b50d8f57a8 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -425,6 +425,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
425 | INIT_LIST_HEAD(&starget->devices); | 425 | INIT_LIST_HEAD(&starget->devices); |
426 | starget->state = STARGET_CREATED; | 426 | starget->state = STARGET_CREATED; |
427 | starget->scsi_level = SCSI_2; | 427 | starget->scsi_level = SCSI_2; |
428 | starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED; | ||
428 | retry: | 429 | retry: |
429 | spin_lock_irqsave(shost->host_lock, flags); | 430 | spin_lock_irqsave(shost->host_lock, flags); |
430 | 431 | ||
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 094795455293..0a2ce7b6325c 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -357,7 +357,7 @@ int iscsi_session_chkready(struct iscsi_cls_session *session) | |||
357 | err = 0; | 357 | err = 0; |
358 | break; | 358 | break; |
359 | case ISCSI_SESSION_FAILED: | 359 | case ISCSI_SESSION_FAILED: |
360 | err = DID_TRANSPORT_DISRUPTED << 16; | 360 | err = DID_IMM_RETRY << 16; |
361 | break; | 361 | break; |
362 | case ISCSI_SESSION_FREE: | 362 | case ISCSI_SESSION_FREE: |
363 | err = DID_TRANSPORT_FAILFAST << 16; | 363 | err = DID_TRANSPORT_FAILFAST << 16; |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index e3a5ad5ef1d6..cdc049d4350f 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -665,7 +665,7 @@ static struct uart_driver amba_reg = { | |||
665 | .cons = AMBA_CONSOLE, | 665 | .cons = AMBA_CONSOLE, |
666 | }; | 666 | }; |
667 | 667 | ||
668 | static int pl010_probe(struct amba_device *dev, void *id) | 668 | static int pl010_probe(struct amba_device *dev, struct amba_id *id) |
669 | { | 669 | { |
670 | struct uart_amba_port *uap; | 670 | struct uart_amba_port *uap; |
671 | void __iomem *base; | 671 | void __iomem *base; |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 8b2b9700f3e4..88fdac51b6c5 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -729,7 +729,7 @@ static struct uart_driver amba_reg = { | |||
729 | .cons = AMBA_CONSOLE, | 729 | .cons = AMBA_CONSOLE, |
730 | }; | 730 | }; |
731 | 731 | ||
732 | static int pl011_probe(struct amba_device *dev, void *id) | 732 | static int pl011_probe(struct amba_device *dev, struct amba_id *id) |
733 | { | 733 | { |
734 | struct uart_amba_port *uap; | 734 | struct uart_amba_port *uap; |
735 | void __iomem *base; | 735 | void __iomem *base; |
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 6579e2be1dd1..a461b3b2c72d 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -1472,8 +1472,8 @@ static void icom_remove_adapter(struct icom_adapter *icom_adapter) | |||
1472 | 1472 | ||
1473 | free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter); | 1473 | free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter); |
1474 | iounmap(icom_adapter->base_addr); | 1474 | iounmap(icom_adapter->base_addr); |
1475 | icom_free_adapter(icom_adapter); | ||
1476 | pci_release_regions(icom_adapter->pci_dev); | 1475 | pci_release_regions(icom_adapter->pci_dev); |
1476 | icom_free_adapter(icom_adapter); | ||
1477 | } | 1477 | } |
1478 | 1478 | ||
1479 | static void icom_kref_release(struct kref *kref) | 1479 | static void icom_kref_release(struct kref *kref) |
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index d0b093b66adc..5e38ba10a3a9 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -961,7 +961,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) | |||
961 | 961 | ||
962 | switch (trip_type) { | 962 | switch (trip_type) { |
963 | case THERMAL_TRIP_CRITICAL: | 963 | case THERMAL_TRIP_CRITICAL: |
964 | if (temp > trip_temp) { | 964 | if (temp >= trip_temp) { |
965 | if (tz->ops->notify) | 965 | if (tz->ops->notify) |
966 | ret = tz->ops->notify(tz, count, | 966 | ret = tz->ops->notify(tz, count, |
967 | trip_type); | 967 | trip_type); |
@@ -974,7 +974,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) | |||
974 | } | 974 | } |
975 | break; | 975 | break; |
976 | case THERMAL_TRIP_HOT: | 976 | case THERMAL_TRIP_HOT: |
977 | if (temp > trip_temp) | 977 | if (temp >= trip_temp) |
978 | if (tz->ops->notify) | 978 | if (tz->ops->notify) |
979 | tz->ops->notify(tz, count, trip_type); | 979 | tz->ops->notify(tz, count, trip_type); |
980 | break; | 980 | break; |
@@ -986,14 +986,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) | |||
986 | 986 | ||
987 | cdev = instance->cdev; | 987 | cdev = instance->cdev; |
988 | 988 | ||
989 | if (temp > trip_temp) | 989 | if (temp >= trip_temp) |
990 | cdev->ops->set_cur_state(cdev, 1); | 990 | cdev->ops->set_cur_state(cdev, 1); |
991 | else | 991 | else |
992 | cdev->ops->set_cur_state(cdev, 0); | 992 | cdev->ops->set_cur_state(cdev, 0); |
993 | } | 993 | } |
994 | break; | 994 | break; |
995 | case THERMAL_TRIP_PASSIVE: | 995 | case THERMAL_TRIP_PASSIVE: |
996 | if (temp > trip_temp || tz->passive) | 996 | if (temp >= trip_temp || tz->passive) |
997 | thermal_zone_device_passive(tz, temp, | 997 | thermal_zone_device_passive(tz, temp, |
998 | trip_temp, count); | 998 | trip_temp, count); |
999 | break; | 999 | break; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0ab8474b00cb..d9fcdaedf389 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1487,14 +1487,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) | |||
1487 | 1487 | ||
1488 | remove_sysfs_attrs(port); | 1488 | remove_sysfs_attrs(port); |
1489 | 1489 | ||
1490 | /* all open ports are closed at this point | 1490 | kref_put(&priv->kref, ftdi_sio_priv_release); |
1491 | * (by usbserial.c:__serial_close, which calls ftdi_close) | ||
1492 | */ | ||
1493 | |||
1494 | if (priv) { | ||
1495 | usb_set_serial_port_data(port, NULL); | ||
1496 | kref_put(&priv->kref, ftdi_sio_priv_release); | ||
1497 | } | ||
1498 | 1491 | ||
1499 | return 0; | 1492 | return 0; |
1500 | } | 1493 | } |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index 61050ab14128..d1f80bac54f0 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -437,7 +437,7 @@ static int clcdfb_register(struct clcd_fb *fb) | |||
437 | return ret; | 437 | return ret; |
438 | } | 438 | } |
439 | 439 | ||
440 | static int clcdfb_probe(struct amba_device *dev, void *id) | 440 | static int clcdfb_probe(struct amba_device *dev, struct amba_id *id) |
441 | { | 441 | { |
442 | struct clcd_board *board = dev->dev.platform_data; | 442 | struct clcd_board *board = dev->dev.platform_data; |
443 | struct clcd_fb *fb; | 443 | struct clcd_fb *fb; |
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index dfb72f5e4c96..148cbcc39602 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c | |||
@@ -880,20 +880,22 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) | |||
880 | 880 | ||
881 | static int get_dss_clocks(void) | 881 | static int get_dss_clocks(void) |
882 | { | 882 | { |
883 | if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) { | 883 | dispc.dss_ick = clk_get(dispc.fbdev->dev, "ick"); |
884 | dev_err(dispc.fbdev->dev, "can't get dss_ick\n"); | 884 | if (IS_ERR(dispc.dss_ick)) { |
885 | dev_err(dispc.fbdev->dev, "can't get ick\n"); | ||
885 | return PTR_ERR(dispc.dss_ick); | 886 | return PTR_ERR(dispc.dss_ick); |
886 | } | 887 | } |
887 | 888 | ||
888 | if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) { | 889 | dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck"); |
890 | if (IS_ERR(dispc.dss1_fck)) { | ||
889 | dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); | 891 | dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); |
890 | clk_put(dispc.dss_ick); | 892 | clk_put(dispc.dss_ick); |
891 | return PTR_ERR(dispc.dss1_fck); | 893 | return PTR_ERR(dispc.dss1_fck); |
892 | } | 894 | } |
893 | 895 | ||
894 | if (IS_ERR((dispc.dss_54m_fck = | 896 | dispc.dss_54m_fck = clk_get(dispc.fbdev->dev, "tv_fck"); |
895 | clk_get(dispc.fbdev->dev, "dss_54m_fck")))) { | 897 | if (IS_ERR(dispc.dss_54m_fck)) { |
896 | dev_err(dispc.fbdev->dev, "can't get dss_54m_fck\n"); | 898 | dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); |
897 | clk_put(dispc.dss_ick); | 899 | clk_put(dispc.dss_ick); |
898 | clk_put(dispc.dss1_fck); | 900 | clk_put(dispc.dss1_fck); |
899 | return PTR_ERR(dispc.dss_54m_fck); | 901 | return PTR_ERR(dispc.dss_54m_fck); |
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index a13c8dcad2a8..9332d6ca6456 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c | |||
@@ -83,12 +83,14 @@ static inline u32 rfbi_read_reg(int idx) | |||
83 | 83 | ||
84 | static int rfbi_get_clocks(void) | 84 | static int rfbi_get_clocks(void) |
85 | { | 85 | { |
86 | if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) { | 86 | rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "ick"); |
87 | dev_err(rfbi.fbdev->dev, "can't get dss_ick\n"); | 87 | if (IS_ERR(rfbi.dss_ick)) { |
88 | dev_err(rfbi.fbdev->dev, "can't get ick\n"); | ||
88 | return PTR_ERR(rfbi.dss_ick); | 89 | return PTR_ERR(rfbi.dss_ick); |
89 | } | 90 | } |
90 | 91 | ||
91 | if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) { | 92 | rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck"); |
93 | if (IS_ERR(rfbi.dss1_fck)) { | ||
92 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); | 94 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); |
93 | clk_put(rfbi.dss_ick); | 95 | clk_put(rfbi.dss_ick); |
94 | return PTR_ERR(rfbi.dss1_fck); | 96 | return PTR_ERR(rfbi.dss1_fck); |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 92ea0ab44ce2..f10d2fbeda06 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -47,6 +47,7 @@ struct sh_mobile_lcdc_priv { | |||
47 | #endif | 47 | #endif |
48 | unsigned long lddckr; | 48 | unsigned long lddckr; |
49 | struct sh_mobile_lcdc_chan ch[2]; | 49 | struct sh_mobile_lcdc_chan ch[2]; |
50 | int started; | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | /* shared registers */ | 53 | /* shared registers */ |
@@ -451,6 +452,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
451 | 452 | ||
452 | /* start the lcdc */ | 453 | /* start the lcdc */ |
453 | sh_mobile_lcdc_start_stop(priv, 1); | 454 | sh_mobile_lcdc_start_stop(priv, 1); |
455 | priv->started = 1; | ||
454 | 456 | ||
455 | /* tell the board code to enable the panel */ | 457 | /* tell the board code to enable the panel */ |
456 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 458 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
@@ -493,7 +495,10 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
493 | } | 495 | } |
494 | 496 | ||
495 | /* stop the lcdc */ | 497 | /* stop the lcdc */ |
496 | sh_mobile_lcdc_start_stop(priv, 0); | 498 | if (priv->started) { |
499 | sh_mobile_lcdc_start_stop(priv, 0); | ||
500 | priv->started = 0; | ||
501 | } | ||
497 | 502 | ||
498 | /* stop clocks */ | 503 | /* stop clocks */ |
499 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) | 504 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 5759ba53dc96..d06260251c30 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -2475,7 +2475,7 @@ querySymLinkRetry: | |||
2475 | /* BB FIXME investigate remapping reserved chars here */ | 2475 | /* BB FIXME investigate remapping reserved chars here */ |
2476 | *symlinkinfo = cifs_strndup_from_ucs(data_start, count, | 2476 | *symlinkinfo = cifs_strndup_from_ucs(data_start, count, |
2477 | is_unicode, nls_codepage); | 2477 | is_unicode, nls_codepage); |
2478 | if (!symlinkinfo) | 2478 | if (!*symlinkinfo) |
2479 | rc = -ENOMEM; | 2479 | rc = -ENOMEM; |
2480 | } | 2480 | } |
2481 | } | 2481 | } |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 11431ed72a7f..3758965d73d5 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -225,6 +225,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
225 | if (!(oflags & FMODE_READ)) | 225 | if (!(oflags & FMODE_READ)) |
226 | write_only = true; | 226 | write_only = true; |
227 | 227 | ||
228 | mode &= ~current_umask(); | ||
228 | rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, | 229 | rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, |
229 | pnetfid, presp_data, &oplock, full_path, | 230 | pnetfid, presp_data, &oplock, full_path, |
230 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 231 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
@@ -310,7 +311,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
310 | return -ENOMEM; | 311 | return -ENOMEM; |
311 | } | 312 | } |
312 | 313 | ||
313 | mode &= ~current_umask(); | ||
314 | if (oplockEnabled) | 314 | if (oplockEnabled) |
315 | oplock = REQ_OPLOCK; | 315 | oplock = REQ_OPLOCK; |
316 | 316 | ||
@@ -336,7 +336,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
336 | else /* success, no need to query */ | 336 | else /* success, no need to query */ |
337 | goto cifs_create_set_dentry; | 337 | goto cifs_create_set_dentry; |
338 | } else if ((rc != -EIO) && (rc != -EREMOTE) && | 338 | } else if ((rc != -EIO) && (rc != -EREMOTE) && |
339 | (rc != -EOPNOTSUPP)) /* path not found or net err */ | 339 | (rc != -EOPNOTSUPP) && (rc != -EINVAL)) |
340 | goto cifs_create_out; | 340 | goto cifs_create_out; |
341 | /* else fallthrough to retry, using older open call, this is | 341 | /* else fallthrough to retry, using older open call, this is |
342 | case where server does not support this SMB level, and | 342 | case where server does not support this SMB level, and |
@@ -609,7 +609,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
609 | int xid; | 609 | int xid; |
610 | int rc = 0; /* to get around spurious gcc warning, set to zero here */ | 610 | int rc = 0; /* to get around spurious gcc warning, set to zero here */ |
611 | int oplock = 0; | 611 | int oplock = 0; |
612 | int mode; | ||
613 | __u16 fileHandle = 0; | 612 | __u16 fileHandle = 0; |
614 | bool posix_open = false; | 613 | bool posix_open = false; |
615 | struct cifs_sb_info *cifs_sb; | 614 | struct cifs_sb_info *cifs_sb; |
@@ -658,30 +657,36 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
658 | } | 657 | } |
659 | cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); | 658 | cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); |
660 | 659 | ||
660 | /* Posix open is only called (at lookup time) for file create now. | ||
661 | * For opens (rather than creates), because we do not know if it | ||
662 | * is a file or directory yet, and current Samba no longer allows | ||
663 | * us to do posix open on dirs, we could end up wasting an open call | ||
664 | * on what turns out to be a dir. For file opens, we wait to call posix | ||
665 | * open till cifs_open. It could be added here (lookup) in the future | ||
666 | * but the performance tradeoff of the extra network request when EISDIR | ||
667 | * or EACCES is returned would have to be weighed against the 50% | ||
668 | * reduction in network traffic in the other paths. | ||
669 | */ | ||
661 | if (pTcon->unix_ext) { | 670 | if (pTcon->unix_ext) { |
662 | if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && | 671 | if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && |
663 | (nd->flags & LOOKUP_OPEN)) { | 672 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && |
664 | if (!((nd->intent.open.flags & O_CREAT) && | 673 | (nd->intent.open.flags & O_CREAT)) { |
665 | (nd->intent.open.flags & O_EXCL))) { | 674 | rc = cifs_posix_open(full_path, &newInode, |
666 | mode = nd->intent.open.create_mode & | 675 | parent_dir_inode->i_sb, |
667 | ~current_umask(); | 676 | nd->intent.open.create_mode, |
668 | rc = cifs_posix_open(full_path, &newInode, | ||
669 | parent_dir_inode->i_sb, mode, | ||
670 | nd->intent.open.flags, &oplock, | 677 | nd->intent.open.flags, &oplock, |
671 | &fileHandle, xid); | 678 | &fileHandle, xid); |
672 | /* | 679 | /* |
673 | * This code works around a bug in | 680 | * The check below works around a bug in POSIX |
674 | * samba posix open in samba versions 3.3.1 | 681 | * open in samba versions 3.3.1 and earlier where |
675 | * and earlier where create works | 682 | * open could incorrectly fail with invalid parameter. |
676 | * but open fails with invalid parameter. | 683 | * If either that or op not supported returned, follow |
677 | * If either of these error codes are | 684 | * the normal lookup. |
678 | * returned, follow the normal lookup. | 685 | */ |
679 | * Otherwise, the error during posix open | 686 | if ((rc == 0) || (rc == -ENOENT)) |
680 | * is handled. | 687 | posix_open = true; |
681 | */ | 688 | else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP)) |
682 | if ((rc != -EINVAL) && (rc != -EOPNOTSUPP)) | 689 | pTcon->broken_posix_open = true; |
683 | posix_open = true; | ||
684 | } | ||
685 | } | 690 | } |
686 | if (!posix_open) | 691 | if (!posix_open) |
687 | rc = cifs_get_inode_info_unix(&newInode, full_path, | 692 | rc = cifs_get_inode_info_unix(&newInode, full_path, |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 38c06f826575..302ea15f02e6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -130,10 +130,6 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode, | |||
130 | struct cifsFileInfo *pCifsFile, int oplock, u16 netfid) | 130 | struct cifsFileInfo *pCifsFile, int oplock, u16 netfid) |
131 | { | 131 | { |
132 | 132 | ||
133 | file->private_data = kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); | ||
134 | if (file->private_data == NULL) | ||
135 | return -ENOMEM; | ||
136 | pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); | ||
137 | write_lock(&GlobalSMBSeslock); | 133 | write_lock(&GlobalSMBSeslock); |
138 | 134 | ||
139 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 135 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
@@ -184,6 +180,38 @@ psx_client_can_cache: | |||
184 | return 0; | 180 | return 0; |
185 | } | 181 | } |
186 | 182 | ||
183 | static struct cifsFileInfo * | ||
184 | cifs_fill_filedata(struct file *file) | ||
185 | { | ||
186 | struct list_head *tmp; | ||
187 | struct cifsFileInfo *pCifsFile = NULL; | ||
188 | struct cifsInodeInfo *pCifsInode = NULL; | ||
189 | |||
190 | /* search inode for this file and fill in file->private_data */ | ||
191 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | ||
192 | read_lock(&GlobalSMBSeslock); | ||
193 | list_for_each(tmp, &pCifsInode->openFileList) { | ||
194 | pCifsFile = list_entry(tmp, struct cifsFileInfo, flist); | ||
195 | if ((pCifsFile->pfile == NULL) && | ||
196 | (pCifsFile->pid == current->tgid)) { | ||
197 | /* mode set in cifs_create */ | ||
198 | |||
199 | /* needed for writepage */ | ||
200 | pCifsFile->pfile = file; | ||
201 | file->private_data = pCifsFile; | ||
202 | break; | ||
203 | } | ||
204 | } | ||
205 | read_unlock(&GlobalSMBSeslock); | ||
206 | |||
207 | if (file->private_data != NULL) { | ||
208 | return pCifsFile; | ||
209 | } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) | ||
210 | cERROR(1, ("could not find file instance for " | ||
211 | "new file %p", file)); | ||
212 | return NULL; | ||
213 | } | ||
214 | |||
187 | /* all arguments to this function must be checked for validity in caller */ | 215 | /* all arguments to this function must be checked for validity in caller */ |
188 | static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | 216 | static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, |
189 | struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, | 217 | struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, |
@@ -258,7 +286,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
258 | struct cifsTconInfo *tcon; | 286 | struct cifsTconInfo *tcon; |
259 | struct cifsFileInfo *pCifsFile; | 287 | struct cifsFileInfo *pCifsFile; |
260 | struct cifsInodeInfo *pCifsInode; | 288 | struct cifsInodeInfo *pCifsInode; |
261 | struct list_head *tmp; | ||
262 | char *full_path = NULL; | 289 | char *full_path = NULL; |
263 | int desiredAccess; | 290 | int desiredAccess; |
264 | int disposition; | 291 | int disposition; |
@@ -270,32 +297,12 @@ int cifs_open(struct inode *inode, struct file *file) | |||
270 | cifs_sb = CIFS_SB(inode->i_sb); | 297 | cifs_sb = CIFS_SB(inode->i_sb); |
271 | tcon = cifs_sb->tcon; | 298 | tcon = cifs_sb->tcon; |
272 | 299 | ||
273 | /* search inode for this file and fill in file->private_data */ | ||
274 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 300 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
275 | read_lock(&GlobalSMBSeslock); | 301 | pCifsFile = cifs_fill_filedata(file); |
276 | list_for_each(tmp, &pCifsInode->openFileList) { | 302 | if (pCifsFile) { |
277 | pCifsFile = list_entry(tmp, struct cifsFileInfo, | ||
278 | flist); | ||
279 | if ((pCifsFile->pfile == NULL) && | ||
280 | (pCifsFile->pid == current->tgid)) { | ||
281 | /* mode set in cifs_create */ | ||
282 | |||
283 | /* needed for writepage */ | ||
284 | pCifsFile->pfile = file; | ||
285 | |||
286 | file->private_data = pCifsFile; | ||
287 | break; | ||
288 | } | ||
289 | } | ||
290 | read_unlock(&GlobalSMBSeslock); | ||
291 | |||
292 | if (file->private_data != NULL) { | ||
293 | rc = 0; | ||
294 | FreeXid(xid); | 303 | FreeXid(xid); |
295 | return rc; | 304 | return 0; |
296 | } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) | 305 | } |
297 | cERROR(1, ("could not find file instance for " | ||
298 | "new file %p", file)); | ||
299 | 306 | ||
300 | full_path = build_path_from_dentry(file->f_path.dentry); | 307 | full_path = build_path_from_dentry(file->f_path.dentry); |
301 | if (full_path == NULL) { | 308 | if (full_path == NULL) { |
@@ -325,6 +332,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
325 | /* no need for special case handling of setting mode | 332 | /* no need for special case handling of setting mode |
326 | on read only files needed here */ | 333 | on read only files needed here */ |
327 | 334 | ||
335 | pCifsFile = cifs_fill_filedata(file); | ||
328 | cifs_posix_open_inode_helper(inode, file, pCifsInode, | 336 | cifs_posix_open_inode_helper(inode, file, pCifsInode, |
329 | pCifsFile, oplock, netfid); | 337 | pCifsFile, oplock, netfid); |
330 | goto out; | 338 | goto out; |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index ea9d11e3dcbb..cd83c53fcbb5 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -107,48 +107,48 @@ void * | |||
107 | cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | 107 | cifs_follow_link(struct dentry *direntry, struct nameidata *nd) |
108 | { | 108 | { |
109 | struct inode *inode = direntry->d_inode; | 109 | struct inode *inode = direntry->d_inode; |
110 | int rc = -EACCES; | 110 | int rc = -ENOMEM; |
111 | int xid; | 111 | int xid; |
112 | char *full_path = NULL; | 112 | char *full_path = NULL; |
113 | char *target_path = ERR_PTR(-ENOMEM); | 113 | char *target_path = NULL; |
114 | struct cifs_sb_info *cifs_sb; | 114 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
115 | struct cifsTconInfo *pTcon; | 115 | struct cifsTconInfo *tcon = cifs_sb->tcon; |
116 | 116 | ||
117 | xid = GetXid(); | 117 | xid = GetXid(); |
118 | 118 | ||
119 | full_path = build_path_from_dentry(direntry); | 119 | /* |
120 | * For now, we just handle symlinks with unix extensions enabled. | ||
121 | * Eventually we should handle NTFS reparse points, and MacOS | ||
122 | * symlink support. For instance... | ||
123 | * | ||
124 | * rc = CIFSSMBQueryReparseLinkInfo(...) | ||
125 | * | ||
126 | * For now, just return -EACCES when the server doesn't support posix | ||
127 | * extensions. Note that we still allow querying symlinks when posix | ||
128 | * extensions are manually disabled. We could disable these as well | ||
129 | * but there doesn't seem to be any harm in allowing the client to | ||
130 | * read them. | ||
131 | */ | ||
132 | if (!(tcon->ses->capabilities & CAP_UNIX)) { | ||
133 | rc = -EACCES; | ||
134 | goto out; | ||
135 | } | ||
120 | 136 | ||
137 | full_path = build_path_from_dentry(direntry); | ||
121 | if (!full_path) | 138 | if (!full_path) |
122 | goto out; | 139 | goto out; |
123 | 140 | ||
124 | cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); | 141 | cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); |
125 | cifs_sb = CIFS_SB(inode->i_sb); | ||
126 | pTcon = cifs_sb->tcon; | ||
127 | |||
128 | /* We could change this to: | ||
129 | if (pTcon->unix_ext) | ||
130 | but there does not seem any point in refusing to | ||
131 | get symlink info if we can, even if unix extensions | ||
132 | turned off for this mount */ | ||
133 | |||
134 | if (pTcon->ses->capabilities & CAP_UNIX) | ||
135 | rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, | ||
136 | &target_path, | ||
137 | cifs_sb->local_nls); | ||
138 | else { | ||
139 | /* BB add read reparse point symlink code here */ | ||
140 | /* rc = CIFSSMBQueryReparseLinkInfo */ | ||
141 | /* BB Add code to Query ReparsePoint info */ | ||
142 | /* BB Add MAC style xsymlink check here if enabled */ | ||
143 | } | ||
144 | 142 | ||
143 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, | ||
144 | cifs_sb->local_nls); | ||
145 | kfree(full_path); | ||
146 | out: | ||
145 | if (rc != 0) { | 147 | if (rc != 0) { |
146 | kfree(target_path); | 148 | kfree(target_path); |
147 | target_path = ERR_PTR(rc); | 149 | target_path = ERR_PTR(rc); |
148 | } | 150 | } |
149 | 151 | ||
150 | kfree(full_path); | ||
151 | out: | ||
152 | FreeXid(xid); | 152 | FreeXid(xid); |
153 | nd_set_link(nd, target_path); | 153 | nd_set_link(nd, target_path); |
154 | return NULL; | 154 | return NULL; |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 370b190a09d1..89f98e9a024b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1943,7 +1943,8 @@ int nfs_permission(struct inode *inode, int mask) | |||
1943 | case S_IFREG: | 1943 | case S_IFREG: |
1944 | /* NFSv4 has atomic_open... */ | 1944 | /* NFSv4 has atomic_open... */ |
1945 | if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) | 1945 | if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) |
1946 | && (mask & MAY_OPEN)) | 1946 | && (mask & MAY_OPEN) |
1947 | && !(mask & MAY_EXEC)) | ||
1947 | goto out; | 1948 | goto out; |
1948 | break; | 1949 | break; |
1949 | case S_IFDIR: | 1950 | case S_IFDIR: |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 50ff3f2cdf24..d6759b92006f 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -576,7 +576,7 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, | |||
576 | ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); | 576 | ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); |
577 | 577 | ||
578 | out_free: | 578 | out_free: |
579 | while (--n > 0) | 579 | while (--n >= 0) |
580 | vfree(kbufs[n]); | 580 | vfree(kbufs[n]); |
581 | kfree(kbufs[4]); | 581 | kfree(kbufs[4]); |
582 | return ret; | 582 | return ret; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 1215a4f50cd2..3567fb9e3fb1 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -448,13 +448,11 @@ int remove_save_link(struct inode *inode, int truncate) | |||
448 | static void reiserfs_kill_sb(struct super_block *s) | 448 | static void reiserfs_kill_sb(struct super_block *s) |
449 | { | 449 | { |
450 | if (REISERFS_SB(s)) { | 450 | if (REISERFS_SB(s)) { |
451 | #ifdef CONFIG_REISERFS_FS_XATTR | ||
452 | if (REISERFS_SB(s)->xattr_root) { | 451 | if (REISERFS_SB(s)->xattr_root) { |
453 | d_invalidate(REISERFS_SB(s)->xattr_root); | 452 | d_invalidate(REISERFS_SB(s)->xattr_root); |
454 | dput(REISERFS_SB(s)->xattr_root); | 453 | dput(REISERFS_SB(s)->xattr_root); |
455 | REISERFS_SB(s)->xattr_root = NULL; | 454 | REISERFS_SB(s)->xattr_root = NULL; |
456 | } | 455 | } |
457 | #endif | ||
458 | if (REISERFS_SB(s)->priv_root) { | 456 | if (REISERFS_SB(s)->priv_root) { |
459 | d_invalidate(REISERFS_SB(s)->priv_root); | 457 | d_invalidate(REISERFS_SB(s)->priv_root); |
460 | dput(REISERFS_SB(s)->priv_root); | 458 | dput(REISERFS_SB(s)->priv_root); |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 2237e10c7c7c..8e7deb0e6964 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -123,7 +123,9 @@ static struct dentry *open_xa_root(struct super_block *sb, int flags) | |||
123 | mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR); | 123 | mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR); |
124 | 124 | ||
125 | xaroot = dget(REISERFS_SB(sb)->xattr_root); | 125 | xaroot = dget(REISERFS_SB(sb)->xattr_root); |
126 | if (!xaroot->d_inode) { | 126 | if (!xaroot) |
127 | xaroot = ERR_PTR(-ENODATA); | ||
128 | else if (!xaroot->d_inode) { | ||
127 | int err = -ENODATA; | 129 | int err = -ENODATA; |
128 | if (xattr_may_create(flags)) | 130 | if (xattr_may_create(flags)) |
129 | err = xattr_mkdir(privroot->d_inode, xaroot, 0700); | 131 | err = xattr_mkdir(privroot->d_inode, xaroot, 0700); |
@@ -685,20 +687,6 @@ out: | |||
685 | return err; | 687 | return err; |
686 | } | 688 | } |
687 | 689 | ||
688 | /* Actual operations that are exported to VFS-land */ | ||
689 | struct xattr_handler *reiserfs_xattr_handlers[] = { | ||
690 | &reiserfs_xattr_user_handler, | ||
691 | &reiserfs_xattr_trusted_handler, | ||
692 | #ifdef CONFIG_REISERFS_FS_SECURITY | ||
693 | &reiserfs_xattr_security_handler, | ||
694 | #endif | ||
695 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
696 | &reiserfs_posix_acl_access_handler, | ||
697 | &reiserfs_posix_acl_default_handler, | ||
698 | #endif | ||
699 | NULL | ||
700 | }; | ||
701 | |||
702 | /* | 690 | /* |
703 | * In order to implement different sets of xattr operations for each xattr | 691 | * In order to implement different sets of xattr operations for each xattr |
704 | * prefix with the generic xattr API, a filesystem should create a | 692 | * prefix with the generic xattr API, a filesystem should create a |
@@ -883,23 +871,6 @@ static int reiserfs_check_acl(struct inode *inode, int mask) | |||
883 | return error; | 871 | return error; |
884 | } | 872 | } |
885 | 873 | ||
886 | int reiserfs_permission(struct inode *inode, int mask) | ||
887 | { | ||
888 | /* | ||
889 | * We don't do permission checks on the internal objects. | ||
890 | * Permissions are determined by the "owning" object. | ||
891 | */ | ||
892 | if (IS_PRIVATE(inode)) | ||
893 | return 0; | ||
894 | /* | ||
895 | * Stat data v1 doesn't support ACLs. | ||
896 | */ | ||
897 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | ||
898 | return generic_permission(inode, mask, NULL); | ||
899 | else | ||
900 | return generic_permission(inode, mask, reiserfs_check_acl); | ||
901 | } | ||
902 | |||
903 | static int create_privroot(struct dentry *dentry) | 874 | static int create_privroot(struct dentry *dentry) |
904 | { | 875 | { |
905 | int err; | 876 | int err; |
@@ -922,6 +893,28 @@ static int create_privroot(struct dentry *dentry) | |||
922 | return 0; | 893 | return 0; |
923 | } | 894 | } |
924 | 895 | ||
896 | #else | ||
897 | int __init reiserfs_xattr_register_handlers(void) { return 0; } | ||
898 | void reiserfs_xattr_unregister_handlers(void) {} | ||
899 | static int create_privroot(struct dentry *dentry) { return 0; } | ||
900 | #endif | ||
901 | |||
902 | /* Actual operations that are exported to VFS-land */ | ||
903 | struct xattr_handler *reiserfs_xattr_handlers[] = { | ||
904 | #ifdef CONFIG_REISERFS_FS_XATTR | ||
905 | &reiserfs_xattr_user_handler, | ||
906 | &reiserfs_xattr_trusted_handler, | ||
907 | #endif | ||
908 | #ifdef CONFIG_REISERFS_FS_SECURITY | ||
909 | &reiserfs_xattr_security_handler, | ||
910 | #endif | ||
911 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
912 | &reiserfs_posix_acl_access_handler, | ||
913 | &reiserfs_posix_acl_default_handler, | ||
914 | #endif | ||
915 | NULL | ||
916 | }; | ||
917 | |||
925 | static int xattr_mount_check(struct super_block *s) | 918 | static int xattr_mount_check(struct super_block *s) |
926 | { | 919 | { |
927 | /* We need generation numbers to ensure that the oid mapping is correct | 920 | /* We need generation numbers to ensure that the oid mapping is correct |
@@ -941,10 +934,24 @@ static int xattr_mount_check(struct super_block *s) | |||
941 | return 0; | 934 | return 0; |
942 | } | 935 | } |
943 | 936 | ||
944 | #else | 937 | int reiserfs_permission(struct inode *inode, int mask) |
945 | int __init reiserfs_xattr_register_handlers(void) { return 0; } | 938 | { |
946 | void reiserfs_xattr_unregister_handlers(void) {} | 939 | /* |
940 | * We don't do permission checks on the internal objects. | ||
941 | * Permissions are determined by the "owning" object. | ||
942 | */ | ||
943 | if (IS_PRIVATE(inode)) | ||
944 | return 0; | ||
945 | |||
946 | #ifdef CONFIG_REISERFS_FS_XATTR | ||
947 | /* | ||
948 | * Stat data v1 doesn't support ACLs. | ||
949 | */ | ||
950 | if (get_inode_sd_version(inode) != STAT_DATA_V1) | ||
951 | return generic_permission(inode, mask, reiserfs_check_acl); | ||
947 | #endif | 952 | #endif |
953 | return generic_permission(inode, mask, NULL); | ||
954 | } | ||
948 | 955 | ||
949 | /* This will catch lookups from the fs root to .reiserfs_priv */ | 956 | /* This will catch lookups from the fs root to .reiserfs_priv */ |
950 | static int | 957 | static int |
@@ -992,7 +999,6 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) | |||
992 | int err = 0; | 999 | int err = 0; |
993 | struct dentry *privroot = REISERFS_SB(s)->priv_root; | 1000 | struct dentry *privroot = REISERFS_SB(s)->priv_root; |
994 | 1001 | ||
995 | #ifdef CONFIG_REISERFS_FS_XATTR | ||
996 | err = xattr_mount_check(s); | 1002 | err = xattr_mount_check(s); |
997 | if (err) | 1003 | if (err) |
998 | goto error; | 1004 | goto error; |
@@ -1023,14 +1029,11 @@ error: | |||
1023 | clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); | 1029 | clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); |
1024 | clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); | 1030 | clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); |
1025 | } | 1031 | } |
1026 | #endif | ||
1027 | 1032 | ||
1028 | /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ | 1033 | /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ |
1029 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
1030 | if (reiserfs_posixacl(s)) | 1034 | if (reiserfs_posixacl(s)) |
1031 | s->s_flags |= MS_POSIXACL; | 1035 | s->s_flags |= MS_POSIXACL; |
1032 | else | 1036 | else |
1033 | #endif | ||
1034 | s->s_flags &= ~MS_POSIXACL; | 1037 | s->s_flags &= ~MS_POSIXACL; |
1035 | 1038 | ||
1036 | return err; | 1039 | return err; |
diff --git a/include/asm-generic/local.h b/include/asm-generic/local.h index dbd6150763e9..fc218444e315 100644 --- a/include/asm-generic/local.h +++ b/include/asm-generic/local.h | |||
@@ -42,7 +42,7 @@ typedef struct | |||
42 | 42 | ||
43 | #define local_cmpxchg(l, o, n) atomic_long_cmpxchg((&(l)->a), (o), (n)) | 43 | #define local_cmpxchg(l, o, n) atomic_long_cmpxchg((&(l)->a), (o), (n)) |
44 | #define local_xchg(l, n) atomic_long_xchg((&(l)->a), (n)) | 44 | #define local_xchg(l, n) atomic_long_xchg((&(l)->a), (n)) |
45 | #define local_add_unless(l, a, u) atomic_long_add_unless((&(l)->a), (a), (u)) | 45 | #define local_add_unless(l, _a, u) atomic_long_add_unless((&(l)->a), (_a), (u)) |
46 | #define local_inc_not_zero(l) atomic_long_inc_not_zero(&(l)->a) | 46 | #define local_inc_not_zero(l) atomic_long_inc_not_zero(&(l)->a) |
47 | 47 | ||
48 | /* Non-atomic variants, ie. preemption disabled and won't be touched | 48 | /* Non-atomic variants, ie. preemption disabled and won't be touched |
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 51e6e54b2aa1..9b93cafa82a0 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h | |||
@@ -28,7 +28,7 @@ struct amba_id { | |||
28 | 28 | ||
29 | struct amba_driver { | 29 | struct amba_driver { |
30 | struct device_driver drv; | 30 | struct device_driver drv; |
31 | int (*probe)(struct amba_device *, void *); | 31 | int (*probe)(struct amba_device *, struct amba_id *); |
32 | int (*remove)(struct amba_device *); | 32 | int (*remove)(struct amba_device *); |
33 | void (*shutdown)(struct amba_device *); | 33 | void (*shutdown)(struct amba_device *); |
34 | int (*suspend)(struct amba_device *, pm_message_t); | 34 | int (*suspend)(struct amba_device *, pm_message_t); |
diff --git a/include/linux/ide.h b/include/linux/ide.h index ff65fffb078f..9fed365a598b 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1109,7 +1109,7 @@ void ide_fix_driveid(u16 *); | |||
1109 | 1109 | ||
1110 | extern void ide_fixstring(u8 *, const int, const int); | 1110 | extern void ide_fixstring(u8 *, const int, const int); |
1111 | 1111 | ||
1112 | int ide_busy_sleep(ide_hwif_t *, unsigned long, int); | 1112 | int ide_busy_sleep(ide_drive_t *, unsigned long, int); |
1113 | 1113 | ||
1114 | int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); | 1114 | int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); |
1115 | 1115 | ||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 186ec6ab334d..a47c879e1304 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -1097,6 +1097,32 @@ unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long); | |||
1097 | #define pfn_valid_within(pfn) (1) | 1097 | #define pfn_valid_within(pfn) (1) |
1098 | #endif | 1098 | #endif |
1099 | 1099 | ||
1100 | #ifdef CONFIG_ARCH_HAS_HOLES_MEMORYMODEL | ||
1101 | /* | ||
1102 | * pfn_valid() is meant to be able to tell if a given PFN has valid memmap | ||
1103 | * associated with it or not. In FLATMEM, it is expected that holes always | ||
1104 | * have valid memmap as long as there is valid PFNs either side of the hole. | ||
1105 | * In SPARSEMEM, it is assumed that a valid section has a memmap for the | ||
1106 | * entire section. | ||
1107 | * | ||
1108 | * However, an ARM, and maybe other embedded architectures in the future | ||
1109 | * free memmap backing holes to save memory on the assumption the memmap is | ||
1110 | * never used. The page_zone linkages are then broken even though pfn_valid() | ||
1111 | * returns true. A walker of the full memmap must then do this additional | ||
1112 | * check to ensure the memmap they are looking at is sane by making sure | ||
1113 | * the zone and PFN linkages are still valid. This is expensive, but walkers | ||
1114 | * of the full memmap are extremely rare. | ||
1115 | */ | ||
1116 | int memmap_valid_within(unsigned long pfn, | ||
1117 | struct page *page, struct zone *zone); | ||
1118 | #else | ||
1119 | static inline int memmap_valid_within(unsigned long pfn, | ||
1120 | struct page *page, struct zone *zone) | ||
1121 | { | ||
1122 | return 1; | ||
1123 | } | ||
1124 | #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ | ||
1125 | |||
1100 | #endif /* !__GENERATING_BOUNDS.H */ | 1126 | #endif /* !__GENERATING_BOUNDS.H */ |
1101 | #endif /* !__ASSEMBLY__ */ | 1127 | #endif /* !__ASSEMBLY__ */ |
1102 | #endif /* _LINUX_MMZONE_H */ | 1128 | #endif /* _LINUX_MMZONE_H */ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 06ba90c211a5..0f71812d67d3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -1406,7 +1406,7 @@ | |||
1406 | #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 | 1406 | #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 |
1407 | #define PCI_DEVICE_ID_VIA_838X_1 0xB188 | 1407 | #define PCI_DEVICE_ID_VIA_838X_1 0xB188 |
1408 | #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 | 1408 | #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 |
1409 | #define PCI_DEVICE_ID_VIA_C409_IDE 0XC409 | 1409 | #define PCI_DEVICE_ID_VIA_VX855_IDE 0xC409 |
1410 | #define PCI_DEVICE_ID_VIA_ANON 0xFFFF | 1410 | #define PCI_DEVICE_ID_VIA_ANON 0xFFFF |
1411 | 1411 | ||
1412 | #define PCI_VENDOR_ID_SIEMENS 0x110A | 1412 | #define PCI_VENDOR_ID_SIEMENS 0x110A |
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index cdedc01036e4..99928dce37ea 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h | |||
@@ -41,6 +41,7 @@ int reiserfs_xattr_init(struct super_block *sb, int mount_flags); | |||
41 | int reiserfs_lookup_privroot(struct super_block *sb); | 41 | int reiserfs_lookup_privroot(struct super_block *sb); |
42 | int reiserfs_delete_xattrs(struct inode *inode); | 42 | int reiserfs_delete_xattrs(struct inode *inode); |
43 | int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); | 43 | int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); |
44 | int reiserfs_permission(struct inode *inode, int mask); | ||
44 | 45 | ||
45 | #ifdef CONFIG_REISERFS_FS_XATTR | 46 | #ifdef CONFIG_REISERFS_FS_XATTR |
46 | #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) | 47 | #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) |
@@ -50,7 +51,6 @@ int reiserfs_setxattr(struct dentry *dentry, const char *name, | |||
50 | const void *value, size_t size, int flags); | 51 | const void *value, size_t size, int flags); |
51 | ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size); | 52 | ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size); |
52 | int reiserfs_removexattr(struct dentry *dentry, const char *name); | 53 | int reiserfs_removexattr(struct dentry *dentry, const char *name); |
53 | int reiserfs_permission(struct inode *inode, int mask); | ||
54 | 54 | ||
55 | int reiserfs_xattr_get(struct inode *, const char *, void *, size_t); | 55 | int reiserfs_xattr_get(struct inode *, const char *, void *, size_t); |
56 | int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int); | 56 | int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int); |
@@ -117,8 +117,6 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode) | |||
117 | #define reiserfs_listxattr NULL | 117 | #define reiserfs_listxattr NULL |
118 | #define reiserfs_removexattr NULL | 118 | #define reiserfs_removexattr NULL |
119 | 119 | ||
120 | #define reiserfs_permission NULL | ||
121 | |||
122 | static inline void reiserfs_init_xattr_rwsem(struct inode *inode) | 120 | static inline void reiserfs_init_xattr_rwsem(struct inode *inode) |
123 | { | 121 | { |
124 | } | 122 | } |
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index c9184f756cad..68a8d873bbd9 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h | |||
@@ -680,7 +680,7 @@ fc_remote_port_chkready(struct fc_rport *rport) | |||
680 | if (rport->roles & FC_PORT_ROLE_FCP_TARGET) | 680 | if (rport->roles & FC_PORT_ROLE_FCP_TARGET) |
681 | result = 0; | 681 | result = 0; |
682 | else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) | 682 | else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) |
683 | result = DID_TRANSPORT_DISRUPTED << 16; | 683 | result = DID_IMM_RETRY << 16; |
684 | else | 684 | else |
685 | result = DID_NO_CONNECT << 16; | 685 | result = DID_NO_CONNECT << 16; |
686 | break; | 686 | break; |
@@ -688,7 +688,7 @@ fc_remote_port_chkready(struct fc_rport *rport) | |||
688 | if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) | 688 | if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) |
689 | result = DID_TRANSPORT_FAILFAST << 16; | 689 | result = DID_TRANSPORT_FAILFAST << 16; |
690 | else | 690 | else |
691 | result = DID_TRANSPORT_DISRUPTED << 16; | 691 | result = DID_IMM_RETRY << 16; |
692 | break; | 692 | break; |
693 | default: | 693 | default: |
694 | result = DID_NO_CONNECT << 16; | 694 | result = DID_NO_CONNECT << 16; |
diff --git a/kernel/futex.c b/kernel/futex.c index eef8cd26b5e5..d546b2d53a62 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -193,6 +193,7 @@ static void drop_futex_key_refs(union futex_key *key) | |||
193 | * @uaddr: virtual address of the futex | 193 | * @uaddr: virtual address of the futex |
194 | * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED | 194 | * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED |
195 | * @key: address where result is stored. | 195 | * @key: address where result is stored. |
196 | * @rw: mapping needs to be read/write (values: VERIFY_READ, VERIFY_WRITE) | ||
196 | * | 197 | * |
197 | * Returns a negative error code or 0 | 198 | * Returns a negative error code or 0 |
198 | * The key words are stored in *key on success. | 199 | * The key words are stored in *key on success. |
@@ -203,7 +204,8 @@ static void drop_futex_key_refs(union futex_key *key) | |||
203 | * | 204 | * |
204 | * lock_page() might sleep, the caller should not hold a spinlock. | 205 | * lock_page() might sleep, the caller should not hold a spinlock. |
205 | */ | 206 | */ |
206 | static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) | 207 | static int |
208 | get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) | ||
207 | { | 209 | { |
208 | unsigned long address = (unsigned long)uaddr; | 210 | unsigned long address = (unsigned long)uaddr; |
209 | struct mm_struct *mm = current->mm; | 211 | struct mm_struct *mm = current->mm; |
@@ -226,7 +228,7 @@ static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) | |||
226 | * but access_ok() should be faster than find_vma() | 228 | * but access_ok() should be faster than find_vma() |
227 | */ | 229 | */ |
228 | if (!fshared) { | 230 | if (!fshared) { |
229 | if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))) | 231 | if (unlikely(!access_ok(rw, uaddr, sizeof(u32)))) |
230 | return -EFAULT; | 232 | return -EFAULT; |
231 | key->private.mm = mm; | 233 | key->private.mm = mm; |
232 | key->private.address = address; | 234 | key->private.address = address; |
@@ -235,7 +237,7 @@ static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) | |||
235 | } | 237 | } |
236 | 238 | ||
237 | again: | 239 | again: |
238 | err = get_user_pages_fast(address, 1, 0, &page); | 240 | err = get_user_pages_fast(address, 1, rw == VERIFY_WRITE, &page); |
239 | if (err < 0) | 241 | if (err < 0) |
240 | return err; | 242 | return err; |
241 | 243 | ||
@@ -677,7 +679,7 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset) | |||
677 | if (!bitset) | 679 | if (!bitset) |
678 | return -EINVAL; | 680 | return -EINVAL; |
679 | 681 | ||
680 | ret = get_futex_key(uaddr, fshared, &key); | 682 | ret = get_futex_key(uaddr, fshared, &key, VERIFY_READ); |
681 | if (unlikely(ret != 0)) | 683 | if (unlikely(ret != 0)) |
682 | goto out; | 684 | goto out; |
683 | 685 | ||
@@ -723,10 +725,10 @@ futex_wake_op(u32 __user *uaddr1, int fshared, u32 __user *uaddr2, | |||
723 | int ret, op_ret; | 725 | int ret, op_ret; |
724 | 726 | ||
725 | retry: | 727 | retry: |
726 | ret = get_futex_key(uaddr1, fshared, &key1); | 728 | ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ); |
727 | if (unlikely(ret != 0)) | 729 | if (unlikely(ret != 0)) |
728 | goto out; | 730 | goto out; |
729 | ret = get_futex_key(uaddr2, fshared, &key2); | 731 | ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE); |
730 | if (unlikely(ret != 0)) | 732 | if (unlikely(ret != 0)) |
731 | goto out_put_key1; | 733 | goto out_put_key1; |
732 | 734 | ||
@@ -814,10 +816,10 @@ static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2, | |||
814 | int ret, drop_count = 0; | 816 | int ret, drop_count = 0; |
815 | 817 | ||
816 | retry: | 818 | retry: |
817 | ret = get_futex_key(uaddr1, fshared, &key1); | 819 | ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ); |
818 | if (unlikely(ret != 0)) | 820 | if (unlikely(ret != 0)) |
819 | goto out; | 821 | goto out; |
820 | ret = get_futex_key(uaddr2, fshared, &key2); | 822 | ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_READ); |
821 | if (unlikely(ret != 0)) | 823 | if (unlikely(ret != 0)) |
822 | goto out_put_key1; | 824 | goto out_put_key1; |
823 | 825 | ||
@@ -1140,7 +1142,7 @@ static int futex_wait(u32 __user *uaddr, int fshared, | |||
1140 | q.bitset = bitset; | 1142 | q.bitset = bitset; |
1141 | retry: | 1143 | retry: |
1142 | q.key = FUTEX_KEY_INIT; | 1144 | q.key = FUTEX_KEY_INIT; |
1143 | ret = get_futex_key(uaddr, fshared, &q.key); | 1145 | ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_READ); |
1144 | if (unlikely(ret != 0)) | 1146 | if (unlikely(ret != 0)) |
1145 | goto out; | 1147 | goto out; |
1146 | 1148 | ||
@@ -1330,7 +1332,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared, | |||
1330 | q.pi_state = NULL; | 1332 | q.pi_state = NULL; |
1331 | retry: | 1333 | retry: |
1332 | q.key = FUTEX_KEY_INIT; | 1334 | q.key = FUTEX_KEY_INIT; |
1333 | ret = get_futex_key(uaddr, fshared, &q.key); | 1335 | ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_WRITE); |
1334 | if (unlikely(ret != 0)) | 1336 | if (unlikely(ret != 0)) |
1335 | goto out; | 1337 | goto out; |
1336 | 1338 | ||
@@ -1594,7 +1596,7 @@ retry: | |||
1594 | if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current)) | 1596 | if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current)) |
1595 | return -EPERM; | 1597 | return -EPERM; |
1596 | 1598 | ||
1597 | ret = get_futex_key(uaddr, fshared, &key); | 1599 | ret = get_futex_key(uaddr, fshared, &key, VERIFY_WRITE); |
1598 | if (unlikely(ret != 0)) | 1600 | if (unlikely(ret != 0)) |
1599 | goto out; | 1601 | goto out; |
1600 | 1602 | ||
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h index a2cc7e9a6e84..699a2ac3a0d7 100644 --- a/kernel/lockdep_internals.h +++ b/kernel/lockdep_internals.h | |||
@@ -54,9 +54,9 @@ enum { | |||
54 | * table (if it's not there yet), and we check it for lock order | 54 | * table (if it's not there yet), and we check it for lock order |
55 | * conflicts and deadlocks. | 55 | * conflicts and deadlocks. |
56 | */ | 56 | */ |
57 | #define MAX_LOCKDEP_ENTRIES 8192UL | 57 | #define MAX_LOCKDEP_ENTRIES 16384UL |
58 | 58 | ||
59 | #define MAX_LOCKDEP_CHAINS_BITS 14 | 59 | #define MAX_LOCKDEP_CHAINS_BITS 15 |
60 | #define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS) | 60 | #define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS) |
61 | 61 | ||
62 | #define MAX_LOCKDEP_CHAIN_HLOCKS (MAX_LOCKDEP_CHAINS*5) | 62 | #define MAX_LOCKDEP_CHAIN_HLOCKS (MAX_LOCKDEP_CHAINS*5) |
diff --git a/kernel/panic.c b/kernel/panic.c index 874ecf1307ae..984b3ecbd72c 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -340,39 +340,44 @@ void oops_exit(void) | |||
340 | } | 340 | } |
341 | 341 | ||
342 | #ifdef WANT_WARN_ON_SLOWPATH | 342 | #ifdef WANT_WARN_ON_SLOWPATH |
343 | void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) | 343 | struct slowpath_args { |
344 | { | 344 | const char *fmt; |
345 | va_list args; | 345 | va_list args; |
346 | char function[KSYM_SYMBOL_LEN]; | 346 | }; |
347 | unsigned long caller = (unsigned long)__builtin_return_address(0); | ||
348 | const char *board; | ||
349 | 347 | ||
350 | sprint_symbol(function, caller); | 348 | static void warn_slowpath_common(const char *file, int line, void *caller, struct slowpath_args *args) |
349 | { | ||
350 | const char *board; | ||
351 | 351 | ||
352 | printk(KERN_WARNING "------------[ cut here ]------------\n"); | 352 | printk(KERN_WARNING "------------[ cut here ]------------\n"); |
353 | printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, | 353 | printk(KERN_WARNING "WARNING: at %s:%d %pS()\n", file, line, caller); |
354 | line, function); | ||
355 | board = dmi_get_system_info(DMI_PRODUCT_NAME); | 354 | board = dmi_get_system_info(DMI_PRODUCT_NAME); |
356 | if (board) | 355 | if (board) |
357 | printk(KERN_WARNING "Hardware name: %s\n", board); | 356 | printk(KERN_WARNING "Hardware name: %s\n", board); |
358 | 357 | ||
359 | if (*fmt) { | 358 | if (args) |
360 | va_start(args, fmt); | 359 | vprintk(args->fmt, args->args); |
361 | vprintk(fmt, args); | ||
362 | va_end(args); | ||
363 | } | ||
364 | 360 | ||
365 | print_modules(); | 361 | print_modules(); |
366 | dump_stack(); | 362 | dump_stack(); |
367 | print_oops_end_marker(); | 363 | print_oops_end_marker(); |
368 | add_taint(TAINT_WARN); | 364 | add_taint(TAINT_WARN); |
369 | } | 365 | } |
366 | |||
367 | void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) | ||
368 | { | ||
369 | struct slowpath_args args; | ||
370 | |||
371 | args.fmt = fmt; | ||
372 | va_start(args.args, fmt); | ||
373 | warn_slowpath_common(file, line, __builtin_return_address(0), &args); | ||
374 | va_end(args.args); | ||
375 | } | ||
370 | EXPORT_SYMBOL(warn_slowpath_fmt); | 376 | EXPORT_SYMBOL(warn_slowpath_fmt); |
371 | 377 | ||
372 | void warn_slowpath_null(const char *file, int line) | 378 | void warn_slowpath_null(const char *file, int line) |
373 | { | 379 | { |
374 | static const char *empty = ""; | 380 | warn_slowpath_common(file, line, __builtin_return_address(0), NULL); |
375 | warn_slowpath_fmt(file, line, empty); | ||
376 | } | 381 | } |
377 | EXPORT_SYMBOL(warn_slowpath_null); | 382 | EXPORT_SYMBOL(warn_slowpath_null); |
378 | #endif | 383 | #endif |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index e71ca9cd81b2..b0dc9e7a0d17 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -241,9 +241,9 @@ static int create_image(int platform_mode) | |||
241 | 241 | ||
242 | local_irq_disable(); | 242 | local_irq_disable(); |
243 | 243 | ||
244 | sysdev_suspend(PMSG_FREEZE); | 244 | error = sysdev_suspend(PMSG_FREEZE); |
245 | if (error) { | 245 | if (error) { |
246 | printk(KERN_ERR "PM: Some devices failed to power down, " | 246 | printk(KERN_ERR "PM: Some system devices failed to power down, " |
247 | "aborting hibernation\n"); | 247 | "aborting hibernation\n"); |
248 | goto Enable_irqs; | 248 | goto Enable_irqs; |
249 | } | 249 | } |
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 819f17ac796e..e1d16c9a7680 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c | |||
@@ -38,7 +38,8 @@ | |||
38 | */ | 38 | */ |
39 | unsigned long long __attribute__((weak)) sched_clock(void) | 39 | unsigned long long __attribute__((weak)) sched_clock(void) |
40 | { | 40 | { |
41 | return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ); | 41 | return (unsigned long long)(jiffies - INITIAL_JIFFIES) |
42 | * (NSEC_PER_SEC / HZ); | ||
42 | } | 43 | } |
43 | 44 | ||
44 | static __read_mostly int sched_clock_running; | 45 | static __read_mostly int sched_clock_running; |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a884c09006c4..cda81ec58d9f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -2380,7 +2380,7 @@ static const char readme_msg[] = | |||
2380 | "# echo print-parent > /debug/tracing/trace_options\n" | 2380 | "# echo print-parent > /debug/tracing/trace_options\n" |
2381 | "# echo 1 > /debug/tracing/tracing_enabled\n" | 2381 | "# echo 1 > /debug/tracing/tracing_enabled\n" |
2382 | "# cat /debug/tracing/trace > /tmp/trace.txt\n" | 2382 | "# cat /debug/tracing/trace > /tmp/trace.txt\n" |
2383 | "echo 0 > /debug/tracing/tracing_enabled\n" | 2383 | "# echo 0 > /debug/tracing/tracing_enabled\n" |
2384 | ; | 2384 | ; |
2385 | 2385 | ||
2386 | static ssize_t | 2386 | static ssize_t |
diff --git a/mm/mmzone.c b/mm/mmzone.c index 16ce8b955dcf..f5b7d1760213 100644 --- a/mm/mmzone.c +++ b/mm/mmzone.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | 7 | ||
8 | #include <linux/stddef.h> | 8 | #include <linux/stddef.h> |
9 | #include <linux/mm.h> | ||
9 | #include <linux/mmzone.h> | 10 | #include <linux/mmzone.h> |
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | 12 | ||
@@ -72,3 +73,17 @@ struct zoneref *next_zones_zonelist(struct zoneref *z, | |||
72 | *zone = zonelist_zone(z); | 73 | *zone = zonelist_zone(z); |
73 | return z; | 74 | return z; |
74 | } | 75 | } |
76 | |||
77 | #ifdef CONFIG_ARCH_HAS_HOLES_MEMORYMODEL | ||
78 | int memmap_valid_within(unsigned long pfn, | ||
79 | struct page *page, struct zone *zone) | ||
80 | { | ||
81 | if (page_to_pfn(page) != pfn) | ||
82 | return 0; | ||
83 | |||
84 | if (page_zone(page) != zone) | ||
85 | return 0; | ||
86 | |||
87 | return 1; | ||
88 | } | ||
89 | #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ | ||
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 30351f0063ac..bb553c3e955d 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -94,12 +94,12 @@ unsigned long vm_dirty_bytes; | |||
94 | /* | 94 | /* |
95 | * The interval between `kupdate'-style writebacks | 95 | * The interval between `kupdate'-style writebacks |
96 | */ | 96 | */ |
97 | unsigned int dirty_writeback_interval = 5 * 100; /* sentiseconds */ | 97 | unsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */ |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * The longest time for which data is allowed to remain dirty | 100 | * The longest time for which data is allowed to remain dirty |
101 | */ | 101 | */ |
102 | unsigned int dirty_expire_interval = 30 * 100; /* sentiseconds */ | 102 | unsigned int dirty_expire_interval = 30 * 100; /* centiseconds */ |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Flag that makes the machine dump writes/reads and block dirtyings. | 105 | * Flag that makes the machine dump writes/reads and block dirtyings. |
@@ -770,7 +770,7 @@ static void wb_kupdate(unsigned long arg) | |||
770 | 770 | ||
771 | sync_supers(); | 771 | sync_supers(); |
772 | 772 | ||
773 | oldest_jif = jiffies - msecs_to_jiffies(dirty_expire_interval); | 773 | oldest_jif = jiffies - msecs_to_jiffies(dirty_expire_interval * 10); |
774 | start_jif = jiffies; | 774 | start_jif = jiffies; |
775 | next_jif = start_jif + msecs_to_jiffies(dirty_writeback_interval * 10); | 775 | next_jif = start_jif + msecs_to_jiffies(dirty_writeback_interval * 10); |
776 | nr_to_write = global_page_state(NR_FILE_DIRTY) + | 776 | nr_to_write = global_page_state(NR_FILE_DIRTY) + |
@@ -14,7 +14,7 @@ | |||
14 | * Original design by Rik van Riel <riel@conectiva.com.br> 2001 | 14 | * Original design by Rik van Riel <riel@conectiva.com.br> 2001 |
15 | * File methods by Dave McCracken <dmccr@us.ibm.com> 2003, 2004 | 15 | * File methods by Dave McCracken <dmccr@us.ibm.com> 2003, 2004 |
16 | * Anonymous methods by Andrea Arcangeli <andrea@suse.de> 2004 | 16 | * Anonymous methods by Andrea Arcangeli <andrea@suse.de> 2004 |
17 | * Contributions by Hugh Dickins <hugh@veritas.com> 2003, 2004 | 17 | * Contributions by Hugh Dickins 2003, 2004 |
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* | 20 | /* |
@@ -60,6 +60,7 @@ | |||
60 | #include <linux/kernel.h> | 60 | #include <linux/kernel.h> |
61 | #include <linux/slab.h> | 61 | #include <linux/slab.h> |
62 | #include <linux/mm.h> | 62 | #include <linux/mm.h> |
63 | #include <linux/swap.h> /* struct reclaim_state */ | ||
63 | #include <linux/cache.h> | 64 | #include <linux/cache.h> |
64 | #include <linux/init.h> | 65 | #include <linux/init.h> |
65 | #include <linux/module.h> | 66 | #include <linux/module.h> |
@@ -255,6 +256,8 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) | |||
255 | 256 | ||
256 | static void slob_free_pages(void *b, int order) | 257 | static void slob_free_pages(void *b, int order) |
257 | { | 258 | { |
259 | if (current->reclaim_state) | ||
260 | current->reclaim_state->reclaimed_slab += 1 << order; | ||
258 | free_pages((unsigned long)b, order); | 261 | free_pages((unsigned long)b, order); |
259 | } | 262 | } |
260 | 263 | ||
@@ -407,7 +410,7 @@ static void slob_free(void *block, int size) | |||
407 | spin_unlock_irqrestore(&slob_lock, flags); | 410 | spin_unlock_irqrestore(&slob_lock, flags); |
408 | clear_slob_page(sp); | 411 | clear_slob_page(sp); |
409 | free_slob_page(sp); | 412 | free_slob_page(sp); |
410 | free_page((unsigned long)b); | 413 | slob_free_pages(b, 0); |
411 | return; | 414 | return; |
412 | } | 415 | } |
413 | 416 | ||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/swap.h> /* struct reclaim_state */ | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/bit_spinlock.h> | 14 | #include <linux/bit_spinlock.h> |
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
@@ -1170,6 +1171,8 @@ static void __free_slab(struct kmem_cache *s, struct page *page) | |||
1170 | 1171 | ||
1171 | __ClearPageSlab(page); | 1172 | __ClearPageSlab(page); |
1172 | reset_page_mapcount(page); | 1173 | reset_page_mapcount(page); |
1174 | if (current->reclaim_state) | ||
1175 | current->reclaim_state->reclaimed_slab += pages; | ||
1173 | __free_pages(page, order); | 1176 | __free_pages(page, order); |
1174 | } | 1177 | } |
1175 | 1178 | ||
@@ -1909,7 +1912,7 @@ static inline int calculate_order(int size) | |||
1909 | * Doh this slab cannot be placed using slub_max_order. | 1912 | * Doh this slab cannot be placed using slub_max_order. |
1910 | */ | 1913 | */ |
1911 | order = slab_order(size, 1, MAX_ORDER, 1); | 1914 | order = slab_order(size, 1, MAX_ORDER, 1); |
1912 | if (order <= MAX_ORDER) | 1915 | if (order < MAX_ORDER) |
1913 | return order; | 1916 | return order; |
1914 | return -ENOSYS; | 1917 | return -ENOSYS; |
1915 | } | 1918 | } |
@@ -2522,6 +2525,7 @@ __setup("slub_min_order=", setup_slub_min_order); | |||
2522 | static int __init setup_slub_max_order(char *str) | 2525 | static int __init setup_slub_max_order(char *str) |
2523 | { | 2526 | { |
2524 | get_option(&str, &slub_max_order); | 2527 | get_option(&str, &slub_max_order); |
2528 | slub_max_order = min(slub_max_order, MAX_ORDER - 1); | ||
2525 | 2529 | ||
2526 | return 1; | 2530 | return 1; |
2527 | } | 2531 | } |
diff --git a/mm/vmstat.c b/mm/vmstat.c index 66f6130976cb..74d66dba0cbe 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -509,22 +509,11 @@ static void pagetypeinfo_showblockcount_print(struct seq_file *m, | |||
509 | continue; | 509 | continue; |
510 | 510 | ||
511 | page = pfn_to_page(pfn); | 511 | page = pfn_to_page(pfn); |
512 | #ifdef CONFIG_ARCH_FLATMEM_HAS_HOLES | 512 | |
513 | /* | 513 | /* Watch for unexpected holes punched in the memmap */ |
514 | * Ordinarily, memory holes in flatmem still have a valid | 514 | if (!memmap_valid_within(pfn, page, zone)) |
515 | * memmap for the PFN range. However, an architecture for | ||
516 | * embedded systems (e.g. ARM) can free up the memmap backing | ||
517 | * holes to save memory on the assumption the memmap is | ||
518 | * never used. The page_zone linkages are then broken even | ||
519 | * though pfn_valid() returns true. Skip the page if the | ||
520 | * linkages are broken. Even if this test passed, the impact | ||
521 | * is that the counters for the movable type are off but | ||
522 | * fragmentation monitoring is likely meaningless on small | ||
523 | * systems. | ||
524 | */ | ||
525 | if (page_zone(page) != zone) | ||
526 | continue; | 515 | continue; |
527 | #endif | 516 | |
528 | mtype = get_pageblock_migratetype(page); | 517 | mtype = get_pageblock_migratetype(page); |
529 | 518 | ||
530 | if (mtype < MIGRATE_TYPES) | 519 | if (mtype < MIGRATE_TYPES) |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 30b88777c3df..5ee1a3682bf2 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -134,6 +134,10 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) | |||
134 | if (skb->protocol == htons(ETH_P_PAUSE)) | 134 | if (skb->protocol == htons(ETH_P_PAUSE)) |
135 | goto drop; | 135 | goto drop; |
136 | 136 | ||
137 | /* If STP is turned off, then forward */ | ||
138 | if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0) | ||
139 | goto forward; | ||
140 | |||
137 | if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, | 141 | if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, |
138 | NULL, br_handle_local_finish)) | 142 | NULL, br_handle_local_finish)) |
139 | return NULL; /* frame consumed by filter */ | 143 | return NULL; /* frame consumed by filter */ |
@@ -141,6 +145,7 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) | |||
141 | return skb; /* continue processing */ | 145 | return skb; /* continue processing */ |
142 | } | 146 | } |
143 | 147 | ||
148 | forward: | ||
144 | switch (p->state) { | 149 | switch (p->state) { |
145 | case BR_STATE_FORWARDING: | 150 | case BR_STATE_FORWARDING: |
146 | rhook = rcu_dereference(br_should_route_hook); | 151 | rhook = rcu_dereference(br_should_route_hook); |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 6e63ec3f1fcf..0660515f3992 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -297,6 +297,9 @@ void br_topology_change_detection(struct net_bridge *br) | |||
297 | { | 297 | { |
298 | int isroot = br_is_root_bridge(br); | 298 | int isroot = br_is_root_bridge(br); |
299 | 299 | ||
300 | if (br->stp_enabled != BR_KERNEL_STP) | ||
301 | return; | ||
302 | |||
300 | pr_info("%s: topology change detected, %s\n", br->dev->name, | 303 | pr_info("%s: topology change detected, %s\n", br->dev->name, |
301 | isroot ? "propagating" : "sending tcn bpdu"); | 304 | isroot ? "propagating" : "sending tcn bpdu"); |
302 | 305 | ||
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 9cc9f95b109e..6d62d4618cfc 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c | |||
@@ -66,9 +66,9 @@ | |||
66 | 66 | ||
67 | NOTES. | 67 | NOTES. |
68 | 68 | ||
69 | * The stored value for avbps is scaled by 2^5, so that maximal | 69 | * avbps is scaled by 2^5, avpps is scaled by 2^10. |
70 | rate is ~1Gbit, avpps is scaled by 2^10. | 70 | * both values are reported as 32 bit unsigned values. bps can |
71 | 71 | overflow for fast links : max speed being 34360Mbit/sec | |
72 | * Minimal interval is HZ/4=250msec (it is the greatest common divisor | 72 | * Minimal interval is HZ/4=250msec (it is the greatest common divisor |
73 | for HZ=100 and HZ=1024 8)), maximal interval | 73 | for HZ=100 and HZ=1024 8)), maximal interval |
74 | is (HZ*2^EST_MAX_INTERVAL)/4 = 8sec. Shorter intervals | 74 | is (HZ*2^EST_MAX_INTERVAL)/4 = 8sec. Shorter intervals |
@@ -86,9 +86,9 @@ struct gen_estimator | |||
86 | spinlock_t *stats_lock; | 86 | spinlock_t *stats_lock; |
87 | int ewma_log; | 87 | int ewma_log; |
88 | u64 last_bytes; | 88 | u64 last_bytes; |
89 | u64 avbps; | ||
89 | u32 last_packets; | 90 | u32 last_packets; |
90 | u32 avpps; | 91 | u32 avpps; |
91 | u32 avbps; | ||
92 | struct rcu_head e_rcu; | 92 | struct rcu_head e_rcu; |
93 | struct rb_node node; | 93 | struct rb_node node; |
94 | }; | 94 | }; |
@@ -115,6 +115,7 @@ static void est_timer(unsigned long arg) | |||
115 | rcu_read_lock(); | 115 | rcu_read_lock(); |
116 | list_for_each_entry_rcu(e, &elist[idx].list, list) { | 116 | list_for_each_entry_rcu(e, &elist[idx].list, list) { |
117 | u64 nbytes; | 117 | u64 nbytes; |
118 | u64 brate; | ||
118 | u32 npackets; | 119 | u32 npackets; |
119 | u32 rate; | 120 | u32 rate; |
120 | 121 | ||
@@ -125,9 +126,9 @@ static void est_timer(unsigned long arg) | |||
125 | 126 | ||
126 | nbytes = e->bstats->bytes; | 127 | nbytes = e->bstats->bytes; |
127 | npackets = e->bstats->packets; | 128 | npackets = e->bstats->packets; |
128 | rate = (nbytes - e->last_bytes)<<(7 - idx); | 129 | brate = (nbytes - e->last_bytes)<<(7 - idx); |
129 | e->last_bytes = nbytes; | 130 | e->last_bytes = nbytes; |
130 | e->avbps += ((long)rate - (long)e->avbps) >> e->ewma_log; | 131 | e->avbps += ((s64)(brate - e->avbps)) >> e->ewma_log; |
131 | e->rate_est->bps = (e->avbps+0xF)>>5; | 132 | e->rate_est->bps = (e->avbps+0xF)>>5; |
132 | 133 | ||
133 | rate = (npackets - e->last_packets)<<(12 - idx); | 134 | rate = (npackets - e->last_packets)<<(12 - idx); |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index b5873bdff612..64f51eec6576 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -175,9 +175,13 @@ static void service_arp_queue(struct netpoll_info *npi) | |||
175 | void netpoll_poll(struct netpoll *np) | 175 | void netpoll_poll(struct netpoll *np) |
176 | { | 176 | { |
177 | struct net_device *dev = np->dev; | 177 | struct net_device *dev = np->dev; |
178 | const struct net_device_ops *ops = dev->netdev_ops; | 178 | const struct net_device_ops *ops; |
179 | |||
180 | if (!dev || !netif_running(dev)) | ||
181 | return; | ||
179 | 182 | ||
180 | if (!dev || !netif_running(dev) || !ops->ndo_poll_controller) | 183 | ops = dev->netdev_ops; |
184 | if (!ops->ndo_poll_controller) | ||
181 | return; | 185 | return; |
182 | 186 | ||
183 | /* Process pending work on NIC */ | 187 | /* Process pending work on NIC */ |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d152394b2611..e505b5392e1e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2288,7 +2288,7 @@ unsigned int skb_seq_read(unsigned int consumed, const u8 **data, | |||
2288 | next_skb: | 2288 | next_skb: |
2289 | block_limit = skb_headlen(st->cur_skb) + st->stepped_offset; | 2289 | block_limit = skb_headlen(st->cur_skb) + st->stepped_offset; |
2290 | 2290 | ||
2291 | if (abs_offset < block_limit) { | 2291 | if (abs_offset < block_limit && !st->frag_data) { |
2292 | *data = st->cur_skb->data + (abs_offset - st->stepped_offset); | 2292 | *data = st->cur_skb->data + (abs_offset - st->stepped_offset); |
2293 | return block_limit - abs_offset; | 2293 | return block_limit - abs_offset; |
2294 | } | 2294 | } |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 9d26a3da37e5..5b919f7b45db 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -408,7 +408,7 @@ config INET_XFRM_MODE_BEET | |||
408 | 408 | ||
409 | config INET_LRO | 409 | config INET_LRO |
410 | bool "Large Receive Offload (ipv4/tcp)" | 410 | bool "Large Receive Offload (ipv4/tcp)" |
411 | 411 | default y | |
412 | ---help--- | 412 | ---help--- |
413 | Support for Large Receive Offload (ipv4/tcp). | 413 | Support for Large Receive Offload (ipv4/tcp). |
414 | 414 | ||
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 90d22ae0a419..88bf051d0cbb 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -139,6 +139,8 @@ __be32 ic_servaddr = NONE; /* Boot server IP address */ | |||
139 | __be32 root_server_addr = NONE; /* Address of NFS server */ | 139 | __be32 root_server_addr = NONE; /* Address of NFS server */ |
140 | u8 root_server_path[256] = { 0, }; /* Path to mount as root */ | 140 | u8 root_server_path[256] = { 0, }; /* Path to mount as root */ |
141 | 141 | ||
142 | u32 ic_dev_xid; /* Device under configuration */ | ||
143 | |||
142 | /* vendor class identifier */ | 144 | /* vendor class identifier */ |
143 | static char vendor_class_identifier[253] __initdata; | 145 | static char vendor_class_identifier[253] __initdata; |
144 | 146 | ||
@@ -932,6 +934,13 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str | |||
932 | goto drop_unlock; | 934 | goto drop_unlock; |
933 | } | 935 | } |
934 | 936 | ||
937 | /* Is it a reply for the device we are configuring? */ | ||
938 | if (b->xid != ic_dev_xid) { | ||
939 | if (net_ratelimit()) | ||
940 | printk(KERN_ERR "DHCP/BOOTP: Ignoring delayed packet \n"); | ||
941 | goto drop_unlock; | ||
942 | } | ||
943 | |||
935 | /* Parse extensions */ | 944 | /* Parse extensions */ |
936 | if (ext_len >= 4 && | 945 | if (ext_len >= 4 && |
937 | !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */ | 946 | !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */ |
@@ -1115,6 +1124,9 @@ static int __init ic_dynamic(void) | |||
1115 | get_random_bytes(&timeout, sizeof(timeout)); | 1124 | get_random_bytes(&timeout, sizeof(timeout)); |
1116 | timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM); | 1125 | timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM); |
1117 | for (;;) { | 1126 | for (;;) { |
1127 | /* Track the device we are configuring */ | ||
1128 | ic_dev_xid = d->xid; | ||
1129 | |||
1118 | #ifdef IPCONFIG_BOOTP | 1130 | #ifdef IPCONFIG_BOOTP |
1119 | if (do_bootp && (d->able & IC_BOOTP)) | 1131 | if (do_bootp && (d->able & IC_BOOTP)) |
1120 | ic_bootp_send_if(d, jiffies - start_jiffies); | 1132 | ic_bootp_send_if(d, jiffies - start_jiffies); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 1d7f49c6f0ca..7a0f0b27bf1f 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1321,6 +1321,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1321 | struct task_struct *user_recv = NULL; | 1321 | struct task_struct *user_recv = NULL; |
1322 | int copied_early = 0; | 1322 | int copied_early = 0; |
1323 | struct sk_buff *skb; | 1323 | struct sk_buff *skb; |
1324 | u32 urg_hole = 0; | ||
1324 | 1325 | ||
1325 | lock_sock(sk); | 1326 | lock_sock(sk); |
1326 | 1327 | ||
@@ -1532,7 +1533,8 @@ do_prequeue: | |||
1532 | } | 1533 | } |
1533 | } | 1534 | } |
1534 | } | 1535 | } |
1535 | if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) { | 1536 | if ((flags & MSG_PEEK) && |
1537 | (peek_seq - copied - urg_hole != tp->copied_seq)) { | ||
1536 | if (net_ratelimit()) | 1538 | if (net_ratelimit()) |
1537 | printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", | 1539 | printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", |
1538 | current->comm, task_pid_nr(current)); | 1540 | current->comm, task_pid_nr(current)); |
@@ -1553,6 +1555,7 @@ do_prequeue: | |||
1553 | if (!urg_offset) { | 1555 | if (!urg_offset) { |
1554 | if (!sock_flag(sk, SOCK_URGINLINE)) { | 1556 | if (!sock_flag(sk, SOCK_URGINLINE)) { |
1555 | ++*seq; | 1557 | ++*seq; |
1558 | urg_hole++; | ||
1556 | offset++; | 1559 | offset++; |
1557 | used--; | 1560 | used--; |
1558 | if (!used) | 1561 | if (!used) |
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index ec697cebb63b..3b6418297231 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
@@ -303,6 +303,8 @@ restart: | |||
303 | switch (teql_resolve(skb, skb_res, slave)) { | 303 | switch (teql_resolve(skb, skb_res, slave)) { |
304 | case 0: | 304 | case 0: |
305 | if (__netif_tx_trylock(slave_txq)) { | 305 | if (__netif_tx_trylock(slave_txq)) { |
306 | unsigned int length = qdisc_pkt_len(skb); | ||
307 | |||
306 | if (!netif_tx_queue_stopped(slave_txq) && | 308 | if (!netif_tx_queue_stopped(slave_txq) && |
307 | !netif_tx_queue_frozen(slave_txq) && | 309 | !netif_tx_queue_frozen(slave_txq) && |
308 | slave_ops->ndo_start_xmit(skb, slave) == 0) { | 310 | slave_ops->ndo_start_xmit(skb, slave) == 0) { |
@@ -310,8 +312,7 @@ restart: | |||
310 | master->slaves = NEXT_SLAVE(q); | 312 | master->slaves = NEXT_SLAVE(q); |
311 | netif_wake_queue(dev); | 313 | netif_wake_queue(dev); |
312 | master->stats.tx_packets++; | 314 | master->stats.tx_packets++; |
313 | master->stats.tx_bytes += | 315 | master->stats.tx_bytes += length; |
314 | qdisc_pkt_len(skb); | ||
315 | return 0; | 316 | return 0; |
316 | } | 317 | } |
317 | __netif_tx_unlock(slave_txq); | 318 | __netif_tx_unlock(slave_txq); |
diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 32c8554f3946..00790472f641 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion | |||
@@ -1,5 +1,13 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # Print additional version information for non-release trees. | 2 | # |
3 | # This scripts adds local version information from the version | ||
4 | # control systems git, mercurial (hg) and subversion (svn). | ||
5 | # | ||
6 | # If something goes wrong, send a mail the kernel build mailinglist | ||
7 | # (see MAINTAINERS) and CC Nico Schottelius | ||
8 | # <nico-linuxsetlocalversion -at- schottelius.org>. | ||
9 | # | ||
10 | # | ||
3 | 11 | ||
4 | usage() { | 12 | usage() { |
5 | echo "Usage: $0 [srctree]" >&2 | 13 | echo "Usage: $0 [srctree]" >&2 |
@@ -10,12 +18,20 @@ cd "${1:-.}" || usage | |||
10 | 18 | ||
11 | # Check for git and a git repo. | 19 | # Check for git and a git repo. |
12 | if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then | 20 | if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then |
13 | # Do we have an untagged tag? | 21 | |
14 | if atag=`git describe 2>/dev/null`; then | 22 | # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it, |
15 | echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' | 23 | # because this version is defined in the top level Makefile. |
16 | # add -g${head}, if there is no usable tag | 24 | if [ -z "`git describe --exact-match 2>/dev/null`" ]; then |
17 | else | 25 | |
18 | printf '%s%s' -g $head | 26 | # If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"), |
27 | # we pretty print it. | ||
28 | if atag="`git describe 2>/dev/null`"; then | ||
29 | echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' | ||
30 | |||
31 | # If we don't have a tag at all we print -g{commitish}. | ||
32 | else | ||
33 | printf '%s%s' -g $head | ||
34 | fi | ||
19 | fi | 35 | fi |
20 | 36 | ||
21 | # Is this git on svn? | 37 | # Is this git on svn? |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 7fbd68fab944..5c48e36038f2 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -1074,7 +1074,7 @@ static unsigned int __devinit aaci_size_fifo(struct aaci *aaci) | |||
1074 | return i; | 1074 | return i; |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | static int __devinit aaci_probe(struct amba_device *dev, void *id) | 1077 | static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) |
1078 | { | 1078 | { |
1079 | struct aaci *aaci; | 1079 | struct aaci *aaci; |
1080 | int ret, i; | 1080 | int ret, i; |
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c index 771955a9be71..199b03377142 100644 --- a/sound/drivers/pcsp/pcsp_mixer.c +++ b/sound/drivers/pcsp/pcsp_mixer.c | |||
@@ -51,7 +51,7 @@ static int pcsp_treble_info(struct snd_kcontrol *kcontrol, | |||
51 | if (uinfo->value.enumerated.item > chip->max_treble) | 51 | if (uinfo->value.enumerated.item > chip->max_treble) |
52 | uinfo->value.enumerated.item = chip->max_treble; | 52 | uinfo->value.enumerated.item = chip->max_treble; |
53 | sprintf(uinfo->value.enumerated.name, "%lu", | 53 | sprintf(uinfo->value.enumerated.name, "%lu", |
54 | PCSP_CALC_RATE(uinfo->value.enumerated.item)); | 54 | (unsigned long)PCSP_CALC_RATE(uinfo->value.enumerated.item)); |
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | 57 | ||
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 81bc93e5f1e3..7337abdbe4e3 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -958,10 +958,13 @@ static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97) | |||
958 | } | 958 | } |
959 | 959 | ||
960 | static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker = | 960 | static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker = |
961 | AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", AC97_SIGMATEL_DAC2INVERT, 2, 1, 0); | 961 | AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", |
962 | AC97_SIGMATEL_DAC2INVERT, 2, 1, 0); | ||
962 | 963 | ||
964 | /* "Sigmatel " removed due to excessive name length: */ | ||
963 | static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert = | 965 | static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert = |
964 | AC97_SINGLE("Sigmatel Surround Phase Inversion Playback Switch", AC97_SIGMATEL_DAC2INVERT, 3, 1, 0); | 966 | AC97_SINGLE("Surround Phase Inversion Playback Switch", |
967 | AC97_SIGMATEL_DAC2INVERT, 3, 1, 0); | ||
965 | 968 | ||
966 | static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = { | 969 | static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = { |
967 | AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0), | 970 | AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0), |
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index ad2888705d2a..c111efe61c3c 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
@@ -800,7 +800,7 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) | |||
800 | "Capture Volume", | 800 | "Capture Volume", |
801 | "External Amplifier", | 801 | "External Amplifier", |
802 | "Sigmatel 4-Speaker Stereo Playback Switch", | 802 | "Sigmatel 4-Speaker Stereo Playback Switch", |
803 | "Sigmatel Surround Phase Inversion Playback ", | 803 | "Surround Phase Inversion Playback Switch", |
804 | NULL | 804 | NULL |
805 | }; | 805 | }; |
806 | static char *ca0106_rename_ctls[] = { | 806 | static char *ca0106_rename_ctls[] = { |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b8a0d3e79272..bcbb736f94f0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -12058,6 +12058,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { | |||
12058 | SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), | 12058 | SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), |
12059 | SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), | 12059 | SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), |
12060 | SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), | 12060 | SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), |
12061 | SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA), | ||
12061 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), | 12062 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), |
12062 | SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), | 12063 | SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), |
12063 | SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), | 12064 | SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), |