diff options
106 files changed, 2477 insertions, 676 deletions
diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt new file mode 100644 index 000000000000..dca274ff4005 --- /dev/null +++ b/Documentation/device-mapper/snapshot.txt | |||
@@ -0,0 +1,73 @@ | |||
1 | Device-mapper snapshot support | ||
2 | ============================== | ||
3 | |||
4 | Device-mapper allows you, without massive data copying: | ||
5 | |||
6 | *) To create snapshots of any block device i.e. mountable, saved states of | ||
7 | the block device which are also writable without interfering with the | ||
8 | original content; | ||
9 | *) To create device "forks", i.e. multiple different versions of the | ||
10 | same data stream. | ||
11 | |||
12 | |||
13 | In both cases, dm copies only the chunks of data that get changed and | ||
14 | uses a separate copy-on-write (COW) block device for storage. | ||
15 | |||
16 | |||
17 | There are two dm targets available: snapshot and snapshot-origin. | ||
18 | |||
19 | *) snapshot-origin <origin> | ||
20 | |||
21 | which will normally have one or more snapshots based on it. | ||
22 | You must create the snapshot-origin device before you can create snapshots. | ||
23 | Reads will be mapped directly to the backing device. For each write, the | ||
24 | original data will be saved in the <COW device> of each snapshot to keep | ||
25 | its visible content unchanged, at least until the <COW device> fills up. | ||
26 | |||
27 | |||
28 | *) snapshot <origin> <COW device> <persistent?> <chunksize> | ||
29 | |||
30 | A snapshot is created of the <origin> block device. Changed chunks of | ||
31 | <chunksize> sectors will be stored on the <COW device>. Writes will | ||
32 | only go to the <COW device>. Reads will come from the <COW device> or | ||
33 | from <origin> for unchanged data. <COW device> will often be | ||
34 | smaller than the origin and if it fills up the snapshot will become | ||
35 | useless and be disabled, returning errors. So it is important to monitor | ||
36 | the amount of free space and expand the <COW device> before it fills up. | ||
37 | |||
38 | <persistent?> is P (Persistent) or N (Not persistent - will not survive | ||
39 | after reboot). | ||
40 | |||
41 | |||
42 | How this is used by LVM2 | ||
43 | ======================== | ||
44 | When you create the first LVM2 snapshot of a volume, four dm devices are used: | ||
45 | |||
46 | 1) a device containing the original mapping table of the source volume; | ||
47 | 2) a device used as the <COW device>; | ||
48 | 3) a "snapshot" device, combining #1 and #2, which is the visible snapshot | ||
49 | volume; | ||
50 | 4) the "original" volume (which uses the device number used by the original | ||
51 | source volume), whose table is replaced by a "snapshot-origin" mapping | ||
52 | from device #1. | ||
53 | |||
54 | A fixed naming scheme is used, so with the following commands: | ||
55 | |||
56 | lvcreate -L 1G -n base volumeGroup | ||
57 | lvcreate -L 100M --snapshot -n snap volumeGroup/base | ||
58 | |||
59 | we'll have this situation (with volumes in above order): | ||
60 | |||
61 | # dmsetup table|grep volumeGroup | ||
62 | |||
63 | volumeGroup-base-real: 0 2097152 linear 8:19 384 | ||
64 | volumeGroup-snap-cow: 0 204800 linear 8:19 2097536 | ||
65 | volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16 | ||
66 | volumeGroup-base: 0 2097152 snapshot-origin 254:11 | ||
67 | |||
68 | # ls -lL /dev/mapper/volumeGroup-* | ||
69 | brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real | ||
70 | brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow | ||
71 | brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap | ||
72 | brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base | ||
73 | |||
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt index 5df44dc894e5..1829009db771 100644 --- a/Documentation/sparse.txt +++ b/Documentation/sparse.txt | |||
@@ -51,9 +51,9 @@ or you don't get any checking at all. | |||
51 | Where to get sparse | 51 | Where to get sparse |
52 | ~~~~~~~~~~~~~~~~~~~ | 52 | ~~~~~~~~~~~~~~~~~~~ |
53 | 53 | ||
54 | With BK, you can just get it from | 54 | With git, you can just get it from |
55 | 55 | ||
56 | bk://sparse.bkbits.net/sparse | 56 | rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git |
57 | 57 | ||
58 | and DaveJ has tar-balls at | 58 | and DaveJ has tar-balls at |
59 | 59 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 78aca12101a0..7d1dd5bad39a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1402,6 +1402,18 @@ L: linux-kernel@vger.kernel.org | |||
1402 | L: fastboot@osdl.org | 1402 | L: fastboot@osdl.org |
1403 | S: Maintained | 1403 | S: Maintained |
1404 | 1404 | ||
1405 | KPROBES | ||
1406 | P: Prasanna S Panchamukhi | ||
1407 | M: prasanna@in.ibm.com | ||
1408 | P: Ananth N Mavinakayanahalli | ||
1409 | M: ananth@in.ibm.com | ||
1410 | P: Anil S Keshavamurthy | ||
1411 | M: anil.s.keshavamurthy@intel.com | ||
1412 | P: David S. Miller | ||
1413 | M: davem@davemloft.net | ||
1414 | L: linux-kernel@vger.kernel.org | ||
1415 | S: Maintained | ||
1416 | |||
1405 | LANMEDIA WAN CARD DRIVER | 1417 | LANMEDIA WAN CARD DRIVER |
1406 | P: Andrew Stanley-Jones | 1418 | P: Andrew Stanley-Jones |
1407 | M: asj@lanmedia.com | 1419 | M: asj@lanmedia.com |
@@ -151,7 +151,7 @@ CONFIGURING the kernel: | |||
151 | your existing ./.config file. | 151 | your existing ./.config file. |
152 | "make silentoldconfig" | 152 | "make silentoldconfig" |
153 | Like above, but avoids cluttering the screen | 153 | Like above, but avoids cluttering the screen |
154 | with question already answered. | 154 | with questions already answered. |
155 | 155 | ||
156 | NOTES on "make config": | 156 | NOTES on "make config": |
157 | - having unnecessary drivers will make the kernel bigger, and can | 157 | - having unnecessary drivers will make the kernel bigger, and can |
@@ -199,9 +199,9 @@ COMPILING the kernel: | |||
199 | are installing a new kernel with the same version number as your | 199 | are installing a new kernel with the same version number as your |
200 | working kernel, make a backup of your modules directory before you | 200 | working kernel, make a backup of your modules directory before you |
201 | do a "make modules_install". | 201 | do a "make modules_install". |
202 | In alternative, before compiling, edit your Makefile and change the | 202 | Alternatively, before compiling, use the kernel config option |
203 | "EXTRAVERSION" line - its content is appended to the regular kernel | 203 | "LOCALVERSION" to append a unique suffix to the regular kernel version. |
204 | version. | 204 | LOCALVERSION can be set in the "General Setup" menu. |
205 | 205 | ||
206 | - In order to boot your new kernel, you'll need to copy the kernel | 206 | - In order to boot your new kernel, you'll need to copy the kernel |
207 | image (e.g. .../linux/arch/i386/boot/bzImage after compilation) | 207 | image (e.g. .../linux/arch/i386/boot/bzImage after compilation) |
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index fa98dae3cd98..eb20c3afff58 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
@@ -127,6 +127,10 @@ common_shutdown_1(void *generic_ptr) | |||
127 | /* If booted from SRM, reset some of the original environment. */ | 127 | /* If booted from SRM, reset some of the original environment. */ |
128 | if (alpha_using_srm) { | 128 | if (alpha_using_srm) { |
129 | #ifdef CONFIG_DUMMY_CONSOLE | 129 | #ifdef CONFIG_DUMMY_CONSOLE |
130 | /* If we've gotten here after SysRq-b, leave interrupt | ||
131 | context before taking over the console. */ | ||
132 | if (in_interrupt()) | ||
133 | irq_exit(); | ||
130 | /* This has the effect of resetting the VGA video origin. */ | 134 | /* This has the effect of resetting the VGA video origin. */ |
131 | take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); | 135 | take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); |
132 | #endif | 136 | #endif |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 7152bfbee581..93b5e8e5292e 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -537,7 +537,7 @@ ENTRY(__switch_to) | |||
537 | #ifdef CONFIG_CPU_MPCORE | 537 | #ifdef CONFIG_CPU_MPCORE |
538 | clrex | 538 | clrex |
539 | #else | 539 | #else |
540 | strex r3, r4, [ip] @ Clear exclusive monitor | 540 | strex r5, r4, [ip] @ Clear exclusive monitor |
541 | #endif | 541 | #endif |
542 | #endif | 542 | #endif |
543 | #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) | 543 | #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) |
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index 56405dbfd739..a18983a3c934 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c | |||
@@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode) | |||
233 | simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512); | 233 | simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512); |
234 | } | 234 | } |
235 | 235 | ||
236 | static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len) | ||
237 | { | ||
238 | |||
239 | int scatterlen = sc->use_sg; | ||
240 | struct scatterlist *slp; | ||
241 | |||
242 | if (scatterlen == 0) | ||
243 | memcpy(sc->request_buffer, buf, len); | ||
244 | else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) { | ||
245 | unsigned thislen = min(len, slp->length); | ||
246 | |||
247 | memcpy(page_address(slp->page) + slp->offset, buf, thislen); | ||
248 | slp++; | ||
249 | len -= thislen; | ||
250 | } | ||
251 | } | ||
252 | |||
236 | static int | 253 | static int |
237 | simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | 254 | simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) |
238 | { | 255 | { |
@@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
240 | char fname[MAX_ROOT_LEN+16]; | 257 | char fname[MAX_ROOT_LEN+16]; |
241 | size_t disk_size; | 258 | size_t disk_size; |
242 | char *buf; | 259 | char *buf; |
260 | char localbuf[36]; | ||
243 | #if DEBUG_SIMSCSI | 261 | #if DEBUG_SIMSCSI |
244 | register long sp asm ("sp"); | 262 | register long sp asm ("sp"); |
245 | 263 | ||
@@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
263 | /* disk doesn't exist... */ | 281 | /* disk doesn't exist... */ |
264 | break; | 282 | break; |
265 | } | 283 | } |
266 | buf = sc->request_buffer; | 284 | buf = localbuf; |
267 | buf[0] = 0; /* magnetic disk */ | 285 | buf[0] = 0; /* magnetic disk */ |
268 | buf[1] = 0; /* not a removable medium */ | 286 | buf[1] = 0; /* not a removable medium */ |
269 | buf[2] = 2; /* SCSI-2 compliant device */ | 287 | buf[2] = 2; /* SCSI-2 compliant device */ |
@@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
273 | buf[6] = 0; /* reserved */ | 291 | buf[6] = 0; /* reserved */ |
274 | buf[7] = 0; /* various flags */ | 292 | buf[7] = 0; /* various flags */ |
275 | memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); | 293 | memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); |
294 | simscsi_fillresult(sc, buf, 36); | ||
276 | sc->result = GOOD; | 295 | sc->result = GOOD; |
277 | break; | 296 | break; |
278 | 297 | ||
@@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
304 | simscsi_readwrite10(sc, SSC_WRITE); | 323 | simscsi_readwrite10(sc, SSC_WRITE); |
305 | break; | 324 | break; |
306 | 325 | ||
307 | |||
308 | case READ_CAPACITY: | 326 | case READ_CAPACITY: |
309 | if (desc[target_id] < 0 || sc->request_bufflen < 8) { | 327 | if (desc[target_id] < 0 || sc->request_bufflen < 8) { |
310 | break; | 328 | break; |
311 | } | 329 | } |
312 | buf = sc->request_buffer; | 330 | buf = localbuf; |
313 | |||
314 | disk_size = simscsi_get_disk_size(desc[target_id]); | 331 | disk_size = simscsi_get_disk_size(desc[target_id]); |
315 | 332 | ||
316 | /* pretend to be a 1GB disk (partition table contains real stuff): */ | ||
317 | buf[0] = (disk_size >> 24) & 0xff; | 333 | buf[0] = (disk_size >> 24) & 0xff; |
318 | buf[1] = (disk_size >> 16) & 0xff; | 334 | buf[1] = (disk_size >> 16) & 0xff; |
319 | buf[2] = (disk_size >> 8) & 0xff; | 335 | buf[2] = (disk_size >> 8) & 0xff; |
@@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
323 | buf[5] = 0; | 339 | buf[5] = 0; |
324 | buf[6] = 2; | 340 | buf[6] = 2; |
325 | buf[7] = 0; | 341 | buf[7] = 0; |
342 | simscsi_fillresult(sc, buf, 8); | ||
326 | sc->result = GOOD; | 343 | sc->result = GOOD; |
327 | break; | 344 | break; |
328 | 345 | ||
329 | case MODE_SENSE: | 346 | case MODE_SENSE: |
330 | case MODE_SENSE_10: | 347 | case MODE_SENSE_10: |
331 | /* sd.c uses this to determine whether disk does write-caching. */ | 348 | /* sd.c uses this to determine whether disk does write-caching. */ |
332 | memset(sc->request_buffer, 0, 128); | 349 | simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen); |
333 | sc->result = GOOD; | 350 | sc->result = GOOD; |
334 | break; | 351 | break; |
335 | 352 | ||
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 499a065f4e60..db32fc1d3935 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S | |||
@@ -489,24 +489,27 @@ ia64_state_save: | |||
489 | ;; | 489 | ;; |
490 | st8 [temp1]=r17,16 // pal_min_state | 490 | st8 [temp1]=r17,16 // pal_min_state |
491 | st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT | 491 | st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT |
492 | mov r6=IA64_KR(CURRENT_STACK) | ||
493 | ;; | ||
494 | st8 [temp1]=r6,16 // prev_IA64_KR_CURRENT_STACK | ||
495 | st8 [temp2]=r0,16 // prev_task, starts off as NULL | ||
492 | mov r6=cr.ifa | 496 | mov r6=cr.ifa |
493 | ;; | 497 | ;; |
494 | st8 [temp1]=r0,16 // prev_task, starts off as NULL | 498 | st8 [temp1]=r12,16 // cr.isr |
495 | st8 [temp2]=r12,16 // cr.isr | 499 | st8 [temp2]=r6,16 // cr.ifa |
496 | mov r12=cr.itir | 500 | mov r12=cr.itir |
497 | ;; | 501 | ;; |
498 | st8 [temp1]=r6,16 // cr.ifa | 502 | st8 [temp1]=r12,16 // cr.itir |
499 | st8 [temp2]=r12,16 // cr.itir | 503 | st8 [temp2]=r11,16 // cr.iipa |
500 | mov r12=cr.iim | 504 | mov r12=cr.iim |
501 | ;; | 505 | ;; |
502 | st8 [temp1]=r11,16 // cr.iipa | 506 | st8 [temp1]=r12,16 // cr.iim |
503 | st8 [temp2]=r12,16 // cr.iim | ||
504 | mov r6=cr.iha | ||
505 | (p1) mov r12=IA64_MCA_COLD_BOOT | 507 | (p1) mov r12=IA64_MCA_COLD_BOOT |
506 | (p2) mov r12=IA64_INIT_WARM_BOOT | 508 | (p2) mov r12=IA64_INIT_WARM_BOOT |
509 | mov r6=cr.iha | ||
507 | ;; | 510 | ;; |
508 | st8 [temp1]=r6,16 // cr.iha | 511 | st8 [temp2]=r6,16 // cr.iha |
509 | st8 [temp2]=r12 // os_status, default is cold boot | 512 | st8 [temp1]=r12 // os_status, default is cold boot |
510 | mov r6=IA64_MCA_SAME_CONTEXT | 513 | mov r6=IA64_MCA_SAME_CONTEXT |
511 | ;; | 514 | ;; |
512 | st8 [temp1]=r6 // context, default is same context | 515 | st8 [temp1]=r6 // context, default is same context |
@@ -823,9 +826,12 @@ ia64_state_restore: | |||
823 | ld8 r12=[temp1],16 // sal_ra | 826 | ld8 r12=[temp1],16 // sal_ra |
824 | ld8 r9=[temp2],16 // sal_gp | 827 | ld8 r9=[temp2],16 // sal_gp |
825 | ;; | 828 | ;; |
826 | ld8 r22=[temp1],24 // pal_min_state, virtual. skip prev_task | 829 | ld8 r22=[temp1],16 // pal_min_state, virtual |
827 | ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT | 830 | ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT |
828 | ;; | 831 | ;; |
832 | ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK | ||
833 | ld8 r20=[temp2],16 // prev_task | ||
834 | ;; | ||
829 | ld8 temp3=[temp1],16 // cr.isr | 835 | ld8 temp3=[temp1],16 // cr.isr |
830 | ld8 temp4=[temp2],16 // cr.ifa | 836 | ld8 temp4=[temp2],16 // cr.ifa |
831 | ;; | 837 | ;; |
@@ -846,6 +852,45 @@ ia64_state_restore: | |||
846 | ld8 r8=[temp1] // os_status | 852 | ld8 r8=[temp1] // os_status |
847 | ld8 r10=[temp2] // context | 853 | ld8 r10=[temp2] // context |
848 | 854 | ||
855 | /* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to. To | ||
856 | * avoid any dependencies on the algorithm in ia64_switch_to(), just | ||
857 | * purge any existing CURRENT_STACK mapping and insert the new one. | ||
858 | * | ||
859 | * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains | ||
860 | * prev_IA64_KR_CURRENT, these values may have been changed by the C | ||
861 | * code. Do not use r8, r9, r10, r22, they contain values ready for | ||
862 | * the return to SAL. | ||
863 | */ | ||
864 | |||
865 | mov r15=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK | ||
866 | ;; | ||
867 | shl r15=r15,IA64_GRANULE_SHIFT | ||
868 | ;; | ||
869 | dep r15=-1,r15,61,3 // virtual granule | ||
870 | mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps | ||
871 | ;; | ||
872 | ptr.d r15,r18 | ||
873 | ;; | ||
874 | srlz.d | ||
875 | |||
876 | extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT | ||
877 | shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK | ||
878 | movl r21=PAGE_KERNEL // page properties | ||
879 | ;; | ||
880 | mov IA64_KR(CURRENT_STACK)=r16 | ||
881 | cmp.ne p6,p0=RGN_KERNEL,r19 // new stack is in the kernel region? | ||
882 | or r21=r20,r21 // construct PA | page properties | ||
883 | (p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:( | ||
884 | ;; | ||
885 | mov cr.itir=r18 | ||
886 | mov cr.ifa=r21 | ||
887 | mov r20=IA64_TR_CURRENT_STACK | ||
888 | ;; | ||
889 | itr.d dtr[r20]=r21 | ||
890 | ;; | ||
891 | srlz.d | ||
892 | 1: | ||
893 | |||
849 | br.sptk b0 | 894 | br.sptk b0 |
850 | 895 | ||
851 | //EndStub////////////////////////////////////////////////////////////////////// | 896 | //EndStub////////////////////////////////////////////////////////////////////// |
@@ -982,6 +1027,7 @@ ia64_set_kernel_registers: | |||
982 | add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp | 1027 | add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp |
983 | add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack | 1028 | add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack |
984 | add r13=temp1, r3 // set current to start of MCA/INIT stack | 1029 | add r13=temp1, r3 // set current to start of MCA/INIT stack |
1030 | add r20=temp1, r3 // physical start of MCA/INIT stack | ||
985 | ;; | 1031 | ;; |
986 | ld8 r1=[temp4] // OS GP from SAL OS state | 1032 | ld8 r1=[temp4] // OS GP from SAL OS state |
987 | ;; | 1033 | ;; |
@@ -991,7 +1037,35 @@ ia64_set_kernel_registers: | |||
991 | ;; | 1037 | ;; |
992 | mov IA64_KR(CURRENT)=r13 | 1038 | mov IA64_KR(CURRENT)=r13 |
993 | 1039 | ||
994 | // FIXME: do I need to wire IA64_KR_CURRENT_STACK and IA64_TR_CURRENT_STACK? | 1040 | /* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack. To avoid |
1041 | * any dependencies on the algorithm in ia64_switch_to(), just purge | ||
1042 | * any existing CURRENT_STACK mapping and insert the new one. | ||
1043 | */ | ||
1044 | |||
1045 | mov r16=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK | ||
1046 | ;; | ||
1047 | shl r16=r16,IA64_GRANULE_SHIFT | ||
1048 | ;; | ||
1049 | dep r16=-1,r16,61,3 // virtual granule | ||
1050 | mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps | ||
1051 | ;; | ||
1052 | ptr.d r16,r18 | ||
1053 | ;; | ||
1054 | srlz.d | ||
1055 | |||
1056 | shr.u r16=r20,IA64_GRANULE_SHIFT // r20 = physical start of MCA/INIT stack | ||
1057 | movl r21=PAGE_KERNEL // page properties | ||
1058 | ;; | ||
1059 | mov IA64_KR(CURRENT_STACK)=r16 | ||
1060 | or r21=r20,r21 // construct PA | page properties | ||
1061 | ;; | ||
1062 | mov cr.itir=r18 | ||
1063 | mov cr.ifa=r13 | ||
1064 | mov r20=IA64_TR_CURRENT_STACK | ||
1065 | ;; | ||
1066 | itr.d dtr[r20]=r21 | ||
1067 | ;; | ||
1068 | srlz.d | ||
995 | 1069 | ||
996 | br.sptk b0 | 1070 | br.sptk b0 |
997 | 1071 | ||
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 80f83d6cdbfc..f081c60ab206 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -56,8 +56,9 @@ static struct page *page_isolate[MAX_PAGE_ISOLATE]; | |||
56 | static int num_page_isolate = 0; | 56 | static int num_page_isolate = 0; |
57 | 57 | ||
58 | typedef enum { | 58 | typedef enum { |
59 | ISOLATE_NG = 0, | 59 | ISOLATE_NG, |
60 | ISOLATE_OK = 1 | 60 | ISOLATE_OK, |
61 | ISOLATE_NONE | ||
61 | } isolate_status_t; | 62 | } isolate_status_t; |
62 | 63 | ||
63 | /* | 64 | /* |
@@ -74,7 +75,7 @@ static struct { | |||
74 | * @paddr: poisoned memory location | 75 | * @paddr: poisoned memory location |
75 | * | 76 | * |
76 | * Return value: | 77 | * Return value: |
77 | * ISOLATE_OK / ISOLATE_NG | 78 | * one of isolate_status_t, ISOLATE_OK/NG/NONE. |
78 | */ | 79 | */ |
79 | 80 | ||
80 | static isolate_status_t | 81 | static isolate_status_t |
@@ -85,7 +86,10 @@ mca_page_isolate(unsigned long paddr) | |||
85 | 86 | ||
86 | /* whether physical address is valid or not */ | 87 | /* whether physical address is valid or not */ |
87 | if (!ia64_phys_addr_valid(paddr)) | 88 | if (!ia64_phys_addr_valid(paddr)) |
88 | return ISOLATE_NG; | 89 | return ISOLATE_NONE; |
90 | |||
91 | if (!pfn_valid(paddr)) | ||
92 | return ISOLATE_NONE; | ||
89 | 93 | ||
90 | /* convert physical address to physical page number */ | 94 | /* convert physical address to physical page number */ |
91 | p = pfn_to_page(paddr>>PAGE_SHIFT); | 95 | p = pfn_to_page(paddr>>PAGE_SHIFT); |
@@ -122,10 +126,15 @@ mca_handler_bh(unsigned long paddr) | |||
122 | current->pid, current->comm); | 126 | current->pid, current->comm); |
123 | 127 | ||
124 | spin_lock(&mca_bh_lock); | 128 | spin_lock(&mca_bh_lock); |
125 | if (mca_page_isolate(paddr) == ISOLATE_OK) { | 129 | switch (mca_page_isolate(paddr)) { |
130 | case ISOLATE_OK: | ||
126 | printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr); | 131 | printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr); |
127 | } else { | 132 | break; |
133 | case ISOLATE_NG: | ||
128 | printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr); | 134 | printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr); |
135 | break; | ||
136 | default: | ||
137 | break; | ||
129 | } | 138 | } |
130 | spin_unlock(&mca_bh_lock); | 139 | spin_unlock(&mca_bh_lock); |
131 | 140 | ||
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 1fb92f16acd6..b1457a8a9c0f 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
@@ -15,9 +15,8 @@ extra-y += vmlinux.lds | |||
15 | obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ | 15 | obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ |
16 | process.o signal.o ptrace.o align.o \ | 16 | process.o signal.o ptrace.o align.o \ |
17 | semaphore.o syscalls.o setup.o \ | 17 | semaphore.o syscalls.o setup.o \ |
18 | cputable.o ppc_htab.o | 18 | cputable.o ppc_htab.o perfmon.o |
19 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | 19 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o |
20 | obj-$(CONFIG_E500) += perfmon.o | ||
21 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o | 20 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o |
22 | obj-$(CONFIG_POWER4) += cpu_setup_power4.o | 21 | obj-$(CONFIG_POWER4) += cpu_setup_power4.o |
23 | obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o | 22 | obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o |
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c index fa1dad96b830..04c18788e85f 100644 --- a/arch/ppc/kernel/perfmon.c +++ b/arch/ppc/kernel/perfmon.c | |||
@@ -45,7 +45,7 @@ static void dummy_perf(struct pt_regs *regs) | |||
45 | mtpmr(PMRN_PMGC0, pmgc0); | 45 | mtpmr(PMRN_PMGC0, pmgc0); |
46 | } | 46 | } |
47 | 47 | ||
48 | #else | 48 | #elif CONFIG_6xx |
49 | /* Ensure exceptions are disabled */ | 49 | /* Ensure exceptions are disabled */ |
50 | 50 | ||
51 | static void dummy_perf(struct pt_regs *regs) | 51 | static void dummy_perf(struct pt_regs *regs) |
@@ -55,6 +55,10 @@ static void dummy_perf(struct pt_regs *regs) | |||
55 | mmcr0 &= ~MMCR0_PMXE; | 55 | mmcr0 &= ~MMCR0_PMXE; |
56 | mtspr(SPRN_MMCR0, mmcr0); | 56 | mtspr(SPRN_MMCR0, mmcr0); |
57 | } | 57 | } |
58 | #else | ||
59 | static void dummy_perf(struct pt_regs *regs) | ||
60 | { | ||
61 | } | ||
58 | #endif | 62 | #endif |
59 | 63 | ||
60 | void (*perf_irq)(struct pt_regs *) = dummy_perf; | 64 | void (*perf_irq)(struct pt_regs *) = dummy_perf; |
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index b392b9a15987..4c56a4734aec 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c | |||
@@ -719,7 +719,8 @@ pmac_declare_of_platform_devices(void) | |||
719 | if (np) { | 719 | if (np) { |
720 | for (np = np->child; np != NULL; np = np->sibling) | 720 | for (np = np->child; np != NULL; np = np->sibling) |
721 | if (strncmp(np->name, "i2c", 3) == 0) { | 721 | if (strncmp(np->name, "i2c", 3) == 0) { |
722 | of_platform_device_create(np, "uni-n-i2c"); | 722 | of_platform_device_create(np, "uni-n-i2c", |
723 | NULL); | ||
723 | break; | 724 | break; |
724 | } | 725 | } |
725 | } | 726 | } |
@@ -727,17 +728,18 @@ pmac_declare_of_platform_devices(void) | |||
727 | if (np) { | 728 | if (np) { |
728 | for (np = np->child; np != NULL; np = np->sibling) | 729 | for (np = np->child; np != NULL; np = np->sibling) |
729 | if (strncmp(np->name, "i2c", 3) == 0) { | 730 | if (strncmp(np->name, "i2c", 3) == 0) { |
730 | of_platform_device_create(np, "u3-i2c"); | 731 | of_platform_device_create(np, "u3-i2c", |
732 | NULL); | ||
731 | break; | 733 | break; |
732 | } | 734 | } |
733 | } | 735 | } |
734 | 736 | ||
735 | np = find_devices("valkyrie"); | 737 | np = find_devices("valkyrie"); |
736 | if (np) | 738 | if (np) |
737 | of_platform_device_create(np, "valkyrie"); | 739 | of_platform_device_create(np, "valkyrie", NULL); |
738 | np = find_devices("platinum"); | 740 | np = find_devices("platinum"); |
739 | if (np) | 741 | if (np) |
740 | of_platform_device_create(np, "platinum"); | 742 | of_platform_device_create(np, "platinum", NULL); |
741 | 743 | ||
742 | return 0; | 744 | return 0; |
743 | } | 745 | } |
diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c index da8a0f2128dc..93c7231ea709 100644 --- a/arch/ppc/syslib/of_device.c +++ b/arch/ppc/syslib/of_device.c | |||
@@ -234,7 +234,9 @@ void of_device_unregister(struct of_device *ofdev) | |||
234 | device_unregister(&ofdev->dev); | 234 | device_unregister(&ofdev->dev); |
235 | } | 235 | } |
236 | 236 | ||
237 | struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id) | 237 | struct of_device* of_platform_device_create(struct device_node *np, |
238 | const char *bus_id, | ||
239 | struct device *parent) | ||
238 | { | 240 | { |
239 | struct of_device *dev; | 241 | struct of_device *dev; |
240 | u32 *reg; | 242 | u32 *reg; |
@@ -247,7 +249,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char * | |||
247 | dev->node = of_node_get(np); | 249 | dev->node = of_node_get(np); |
248 | dev->dma_mask = 0xffffffffUL; | 250 | dev->dma_mask = 0xffffffffUL; |
249 | dev->dev.dma_mask = &dev->dma_mask; | 251 | dev->dev.dma_mask = &dev->dma_mask; |
250 | dev->dev.parent = NULL; | 252 | dev->dev.parent = parent; |
251 | dev->dev.bus = &of_platform_bus_type; | 253 | dev->dev.bus = &of_platform_bus_type; |
252 | dev->dev.release = of_release_dev; | 254 | dev->dev.release = of_release_dev; |
253 | 255 | ||
diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c index da580812ddfe..9f200f0f2ad5 100644 --- a/arch/ppc64/kernel/of_device.c +++ b/arch/ppc64/kernel/of_device.c | |||
@@ -233,7 +233,9 @@ void of_device_unregister(struct of_device *ofdev) | |||
233 | device_unregister(&ofdev->dev); | 233 | device_unregister(&ofdev->dev); |
234 | } | 234 | } |
235 | 235 | ||
236 | struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id) | 236 | struct of_device* of_platform_device_create(struct device_node *np, |
237 | const char *bus_id, | ||
238 | struct device *parent) | ||
237 | { | 239 | { |
238 | struct of_device *dev; | 240 | struct of_device *dev; |
239 | 241 | ||
@@ -245,7 +247,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char * | |||
245 | dev->node = np; | 247 | dev->node = np; |
246 | dev->dma_mask = 0xffffffffUL; | 248 | dev->dma_mask = 0xffffffffUL; |
247 | dev->dev.dma_mask = &dev->dma_mask; | 249 | dev->dev.dma_mask = &dev->dma_mask; |
248 | dev->dev.parent = NULL; | 250 | dev->dev.parent = parent; |
249 | dev->dev.bus = &of_platform_bus_type; | 251 | dev->dev.bus = &of_platform_bus_type; |
250 | dev->dev.release = of_release_dev; | 252 | dev->dev.release = of_release_dev; |
251 | 253 | ||
@@ -259,6 +261,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char * | |||
259 | return dev; | 261 | return dev; |
260 | } | 262 | } |
261 | 263 | ||
264 | |||
262 | EXPORT_SYMBOL(of_match_device); | 265 | EXPORT_SYMBOL(of_match_device); |
263 | EXPORT_SYMBOL(of_platform_bus_type); | 266 | EXPORT_SYMBOL(of_platform_bus_type); |
264 | EXPORT_SYMBOL(of_register_driver); | 267 | EXPORT_SYMBOL(of_register_driver); |
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index 8c6313e7e145..d17f0108a032 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c | |||
@@ -364,7 +364,8 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
364 | 364 | ||
365 | while (pci->phb->dma_window_size * children > 0x80000000ul) | 365 | while (pci->phb->dma_window_size * children > 0x80000000ul) |
366 | pci->phb->dma_window_size >>= 1; | 366 | pci->phb->dma_window_size >>= 1; |
367 | DBG("No ISA/IDE, window size is %x\n", pci->phb->dma_window_size); | 367 | DBG("No ISA/IDE, window size is 0x%lx\n", |
368 | pci->phb->dma_window_size); | ||
368 | pci->phb->dma_window_base_cur = 0; | 369 | pci->phb->dma_window_base_cur = 0; |
369 | 370 | ||
370 | return; | 371 | return; |
@@ -388,7 +389,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
388 | while (pci->phb->dma_window_size * children > 0x70000000ul) | 389 | while (pci->phb->dma_window_size * children > 0x70000000ul) |
389 | pci->phb->dma_window_size >>= 1; | 390 | pci->phb->dma_window_size >>= 1; |
390 | 391 | ||
391 | DBG("ISA/IDE, window size is %x\n", pci->phb->dma_window_size); | 392 | DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size); |
392 | 393 | ||
393 | } | 394 | } |
394 | 395 | ||
@@ -442,7 +443,7 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) | |||
442 | struct device_node *dn, *mydn; | 443 | struct device_node *dn, *mydn; |
443 | struct iommu_table *tbl; | 444 | struct iommu_table *tbl; |
444 | 445 | ||
445 | DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name); | 446 | DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev)); |
446 | 447 | ||
447 | mydn = dn = pci_device_to_OF_node(dev); | 448 | mydn = dn = pci_device_to_OF_node(dev); |
448 | 449 | ||
@@ -469,7 +470,7 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) | |||
469 | if (dn && dn->data) { | 470 | if (dn && dn->data) { |
470 | PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; | 471 | PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; |
471 | } else { | 472 | } else { |
472 | DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name); | 473 | DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev)); |
473 | } | 474 | } |
474 | } | 475 | } |
475 | 476 | ||
@@ -503,7 +504,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
503 | int *dma_window = NULL; | 504 | int *dma_window = NULL; |
504 | struct pci_dn *pci; | 505 | struct pci_dn *pci; |
505 | 506 | ||
506 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name); | 507 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); |
507 | 508 | ||
508 | /* dev setup for LPAR is a little tricky, since the device tree might | 509 | /* dev setup for LPAR is a little tricky, since the device tree might |
509 | * contain the dma-window properties per-device and not neccesarily | 510 | * contain the dma-window properties per-device and not neccesarily |
@@ -525,9 +526,8 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
525 | * slots on POWER4 machines. | 526 | * slots on POWER4 machines. |
526 | */ | 527 | */ |
527 | if (dma_window == NULL || pdn->parent == NULL) { | 528 | if (dma_window == NULL || pdn->parent == NULL) { |
528 | /* Fall back to regular (non-LPAR) dev setup */ | 529 | DBG("No dma window for device, linking to parent\n"); |
529 | DBG("No dma window for device, falling back to regular setup\n"); | 530 | PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table; |
530 | iommu_dev_setup_pSeries(dev); | ||
531 | return; | 531 | return; |
532 | } else { | 532 | } else { |
533 | DBG("Found DMA window, allocating table\n"); | 533 | DBG("Found DMA window, allocating table\n"); |
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index 325426c7bed0..25755252067a 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c | |||
@@ -434,15 +434,23 @@ static int pmac_check_legacy_ioport(unsigned int baseport) | |||
434 | 434 | ||
435 | static int __init pmac_declare_of_platform_devices(void) | 435 | static int __init pmac_declare_of_platform_devices(void) |
436 | { | 436 | { |
437 | struct device_node *np; | 437 | struct device_node *np, *npp; |
438 | 438 | ||
439 | np = find_devices("u3"); | 439 | npp = of_find_node_by_name(NULL, "u3"); |
440 | if (np) { | 440 | if (npp) { |
441 | for (np = np->child; np != NULL; np = np->sibling) | 441 | for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) { |
442 | if (strncmp(np->name, "i2c", 3) == 0) { | 442 | if (strncmp(np->name, "i2c", 3) == 0) { |
443 | of_platform_device_create(np, "u3-i2c"); | 443 | of_platform_device_create(np, "u3-i2c", NULL); |
444 | of_node_put(np); | ||
444 | break; | 445 | break; |
445 | } | 446 | } |
447 | } | ||
448 | of_node_put(npp); | ||
449 | } | ||
450 | npp = of_find_node_by_type(NULL, "smu"); | ||
451 | if (npp) { | ||
452 | of_platform_device_create(npp, "smu", NULL); | ||
453 | of_node_put(npp); | ||
446 | } | 454 | } |
447 | 455 | ||
448 | return 0; | 456 | return 0; |
diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c index 3059edb09cc8..41bbb8c59697 100644 --- a/arch/ppc64/kernel/pmac_time.c +++ b/arch/ppc64/kernel/pmac_time.c | |||
@@ -84,7 +84,7 @@ void __pmac pmac_get_rtc_time(struct rtc_time *tm) | |||
84 | 84 | ||
85 | #ifdef CONFIG_PMAC_SMU | 85 | #ifdef CONFIG_PMAC_SMU |
86 | case SYS_CTRLER_SMU: | 86 | case SYS_CTRLER_SMU: |
87 | smu_get_rtc_time(tm); | 87 | smu_get_rtc_time(tm, 1); |
88 | break; | 88 | break; |
89 | #endif /* CONFIG_PMAC_SMU */ | 89 | #endif /* CONFIG_PMAC_SMU */ |
90 | default: | 90 | default: |
@@ -128,7 +128,7 @@ int __pmac pmac_set_rtc_time(struct rtc_time *tm) | |||
128 | 128 | ||
129 | #ifdef CONFIG_PMAC_SMU | 129 | #ifdef CONFIG_PMAC_SMU |
130 | case SYS_CTRLER_SMU: | 130 | case SYS_CTRLER_SMU: |
131 | return smu_set_rtc_time(tm); | 131 | return smu_set_rtc_time(tm, 1); |
132 | #endif /* CONFIG_PMAC_SMU */ | 132 | #endif /* CONFIG_PMAC_SMU */ |
133 | default: | 133 | default: |
134 | return -ENODEV; | 134 | return -ENODEV; |
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c index 85ed3188a91d..b1c044ca5756 100644 --- a/arch/ppc64/kernel/ptrace.c +++ b/arch/ppc64/kernel/ptrace.c | |||
@@ -219,6 +219,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
219 | 219 | ||
220 | case PTRACE_SET_DEBUGREG: | 220 | case PTRACE_SET_DEBUGREG: |
221 | ret = ptrace_set_debugreg(child, addr, data); | 221 | ret = ptrace_set_debugreg(child, addr, data); |
222 | break; | ||
222 | 223 | ||
223 | case PTRACE_DETACH: | 224 | case PTRACE_DETACH: |
224 | ret = ptrace_detach(child, data); | 225 | ret = ptrace_detach(child, data); |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 7626bb59954d..eb1bbb5b6c16 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c | |||
@@ -343,9 +343,7 @@ static void native_flush_hash_range(unsigned long context, | |||
343 | hpte_t *hptep; | 343 | hpte_t *hptep; |
344 | unsigned long hpte_v; | 344 | unsigned long hpte_v; |
345 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); | 345 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); |
346 | 346 | unsigned long large; | |
347 | /* XXX fix for large ptes */ | ||
348 | unsigned long large = 0; | ||
349 | 347 | ||
350 | local_irq_save(flags); | 348 | local_irq_save(flags); |
351 | 349 | ||
@@ -358,6 +356,7 @@ static void native_flush_hash_range(unsigned long context, | |||
358 | 356 | ||
359 | va = (vsid << 28) | (batch->addr[i] & 0x0fffffff); | 357 | va = (vsid << 28) | (batch->addr[i] & 0x0fffffff); |
360 | batch->vaddr[j] = va; | 358 | batch->vaddr[j] = va; |
359 | large = pte_huge(batch->pte[i]); | ||
361 | if (large) | 360 | if (large) |
362 | vpn = va >> HPAGE_SHIFT; | 361 | vpn = va >> HPAGE_SHIFT; |
363 | else | 362 | else |
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index 338771ec70d7..0ea0994ed974 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c | |||
@@ -710,10 +710,13 @@ repeat: | |||
710 | hpte_group = ((~hash & htab_hash_mask) * | 710 | hpte_group = ((~hash & htab_hash_mask) * |
711 | HPTES_PER_GROUP) & ~0x7UL; | 711 | HPTES_PER_GROUP) & ~0x7UL; |
712 | slot = ppc_md.hpte_insert(hpte_group, va, prpn, | 712 | slot = ppc_md.hpte_insert(hpte_group, va, prpn, |
713 | HPTE_V_LARGE, rflags); | 713 | HPTE_V_LARGE | |
714 | HPTE_V_SECONDARY, | ||
715 | rflags); | ||
714 | if (slot == -1) { | 716 | if (slot == -1) { |
715 | if (mftb() & 0x1) | 717 | if (mftb() & 0x1) |
716 | hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; | 718 | hpte_group = ((hash & htab_hash_mask) * |
719 | HPTES_PER_GROUP)&~0x7UL; | ||
717 | 720 | ||
718 | ppc_md.hpte_remove(hpte_group); | 721 | ppc_md.hpte_remove(hpte_group); |
719 | goto repeat; | 722 | goto repeat; |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 14a12d6b3df6..16e7dc89f61d 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -19,18 +19,44 @@ | |||
19 | #include "line.h" | 19 | #include "line.h" |
20 | #include "os.h" | 20 | #include "os.h" |
21 | 21 | ||
22 | #ifdef CONFIG_NOCONFIG_CHAN | 22 | /* XXX: could well be moved to somewhere else, if needed. */ |
23 | static int my_printf(const char * fmt, ...) | ||
24 | __attribute__ ((format (printf, 1, 2))); | ||
25 | |||
26 | static int my_printf(const char * fmt, ...) | ||
27 | { | ||
28 | /* Yes, can be called on atomic context.*/ | ||
29 | char *buf = kmalloc(4096, GFP_ATOMIC); | ||
30 | va_list args; | ||
31 | int r; | ||
32 | |||
33 | if (!buf) { | ||
34 | /* We print directly fmt. | ||
35 | * Yes, yes, yes, feel free to complain. */ | ||
36 | r = strlen(fmt); | ||
37 | } else { | ||
38 | va_start(args, fmt); | ||
39 | r = vsprintf(buf, fmt, args); | ||
40 | va_end(args); | ||
41 | fmt = buf; | ||
42 | } | ||
23 | 43 | ||
24 | /* The printk's here are wrong because we are complaining that there is no | 44 | if (r) |
25 | * output device, but printk is printing to that output device. The user will | 45 | r = os_write_file(1, fmt, r); |
26 | * never see the error. printf would be better, except it can't run on a | 46 | return r; |
27 | * kernel stack because it will overflow it. | 47 | |
28 | * Use printk for now since that will avoid crashing. | 48 | } |
29 | */ | 49 | |
50 | #ifdef CONFIG_NOCONFIG_CHAN | ||
51 | /* Despite its name, there's no added trailing newline. */ | ||
52 | static int my_puts(const char * buf) | ||
53 | { | ||
54 | return os_write_file(1, buf, strlen(buf)); | ||
55 | } | ||
30 | 56 | ||
31 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) | 57 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) |
32 | { | 58 | { |
33 | printk(KERN_ERR "Using a channel type which is configured out of " | 59 | my_puts("Using a channel type which is configured out of " |
34 | "UML\n"); | 60 | "UML\n"); |
35 | return(NULL); | 61 | return(NULL); |
36 | } | 62 | } |
@@ -38,27 +64,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts) | |||
38 | static int not_configged_open(int input, int output, int primary, void *data, | 64 | static int not_configged_open(int input, int output, int primary, void *data, |
39 | char **dev_out) | 65 | char **dev_out) |
40 | { | 66 | { |
41 | printk(KERN_ERR "Using a channel type which is configured out of " | 67 | my_puts("Using a channel type which is configured out of " |
42 | "UML\n"); | 68 | "UML\n"); |
43 | return(-ENODEV); | 69 | return(-ENODEV); |
44 | } | 70 | } |
45 | 71 | ||
46 | static void not_configged_close(int fd, void *data) | 72 | static void not_configged_close(int fd, void *data) |
47 | { | 73 | { |
48 | printk(KERN_ERR "Using a channel type which is configured out of " | 74 | my_puts("Using a channel type which is configured out of " |
49 | "UML\n"); | 75 | "UML\n"); |
50 | } | 76 | } |
51 | 77 | ||
52 | static int not_configged_read(int fd, char *c_out, void *data) | 78 | static int not_configged_read(int fd, char *c_out, void *data) |
53 | { | 79 | { |
54 | printk(KERN_ERR "Using a channel type which is configured out of " | 80 | my_puts("Using a channel type which is configured out of " |
55 | "UML\n"); | 81 | "UML\n"); |
56 | return(-EIO); | 82 | return(-EIO); |
57 | } | 83 | } |
58 | 84 | ||
59 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 85 | static int not_configged_write(int fd, const char *buf, int len, void *data) |
60 | { | 86 | { |
61 | printk(KERN_ERR "Using a channel type which is configured out of " | 87 | my_puts("Using a channel type which is configured out of " |
62 | "UML\n"); | 88 | "UML\n"); |
63 | return(-EIO); | 89 | return(-EIO); |
64 | } | 90 | } |
@@ -66,7 +92,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data) | |||
66 | static int not_configged_console_write(int fd, const char *buf, int len, | 92 | static int not_configged_console_write(int fd, const char *buf, int len, |
67 | void *data) | 93 | void *data) |
68 | { | 94 | { |
69 | printk(KERN_ERR "Using a channel type which is configured out of " | 95 | my_puts("Using a channel type which is configured out of " |
70 | "UML\n"); | 96 | "UML\n"); |
71 | return(-EIO); | 97 | return(-EIO); |
72 | } | 98 | } |
@@ -74,14 +100,14 @@ static int not_configged_console_write(int fd, const char *buf, int len, | |||
74 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 100 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, |
75 | unsigned short *cols) | 101 | unsigned short *cols) |
76 | { | 102 | { |
77 | printk(KERN_ERR "Using a channel type which is configured out of " | 103 | my_puts("Using a channel type which is configured out of " |
78 | "UML\n"); | 104 | "UML\n"); |
79 | return(-ENODEV); | 105 | return(-ENODEV); |
80 | } | 106 | } |
81 | 107 | ||
82 | static void not_configged_free(void *data) | 108 | static void not_configged_free(void *data) |
83 | { | 109 | { |
84 | printf(KERN_ERR "Using a channel type which is configured out of " | 110 | my_puts("Using a channel type which is configured out of " |
85 | "UML\n"); | 111 | "UML\n"); |
86 | } | 112 | } |
87 | 113 | ||
@@ -457,7 +483,7 @@ static struct chan *parse_chan(char *str, int pri, int device, | |||
457 | } | 483 | } |
458 | } | 484 | } |
459 | if(ops == NULL){ | 485 | if(ops == NULL){ |
460 | printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", | 486 | my_printf("parse_chan couldn't parse \"%s\"\n", |
461 | str); | 487 | str); |
462 | return(NULL); | 488 | return(NULL); |
463 | } | 489 | } |
@@ -465,7 +491,7 @@ static struct chan *parse_chan(char *str, int pri, int device, | |||
465 | data = (*ops->init)(str, device, opts); | 491 | data = (*ops->init)(str, device, opts); |
466 | if(data == NULL) return(NULL); | 492 | if(data == NULL) return(NULL); |
467 | 493 | ||
468 | chan = kmalloc(sizeof(*chan), GFP_KERNEL); | 494 | chan = kmalloc(sizeof(*chan), GFP_ATOMIC); |
469 | if(chan == NULL) return(NULL); | 495 | if(chan == NULL) return(NULL); |
470 | *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), | 496 | *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), |
471 | .primary = 1, | 497 | .primary = 1, |
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index 310c1f823f26..04383f98f4d5 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c | |||
@@ -23,7 +23,7 @@ static struct mconsole_command commands[] = { | |||
23 | { "reboot", mconsole_reboot, MCONSOLE_PROC }, | 23 | { "reboot", mconsole_reboot, MCONSOLE_PROC }, |
24 | { "config", mconsole_config, MCONSOLE_PROC }, | 24 | { "config", mconsole_config, MCONSOLE_PROC }, |
25 | { "remove", mconsole_remove, MCONSOLE_PROC }, | 25 | { "remove", mconsole_remove, MCONSOLE_PROC }, |
26 | { "sysrq", mconsole_sysrq, MCONSOLE_INTR }, | 26 | { "sysrq", mconsole_sysrq, MCONSOLE_PROC }, |
27 | { "help", mconsole_help, MCONSOLE_INTR }, | 27 | { "help", mconsole_help, MCONSOLE_INTR }, |
28 | { "cad", mconsole_cad, MCONSOLE_INTR }, | 28 | { "cad", mconsole_cad, MCONSOLE_INTR }, |
29 | { "stop", mconsole_stop, MCONSOLE_PROC }, | 29 | { "stop", mconsole_stop, MCONSOLE_PROC }, |
diff --git a/arch/um/include/user.h b/arch/um/include/user.h index 57ee9e261228..0f865ef46918 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h | |||
@@ -14,7 +14,9 @@ extern void *um_kmalloc_atomic(int size); | |||
14 | extern void kfree(void *ptr); | 14 | extern void kfree(void *ptr); |
15 | extern int in_aton(char *str); | 15 | extern int in_aton(char *str); |
16 | extern int open_gdb_chan(void); | 16 | extern int open_gdb_chan(void); |
17 | extern int strlcpy(char *, const char *, int); | 17 | /* These use size_t, however unsigned long is correct on both i386 and x86_64. */ |
18 | extern unsigned long strlcpy(char *, const char *, unsigned long); | ||
19 | extern unsigned long strlcat(char *, const char *, unsigned long); | ||
18 | extern void *um_vmalloc(int size); | 20 | extern void *um_vmalloc(int size); |
19 | extern void vfree(void *ptr); | 21 | extern void vfree(void *ptr); |
20 | 22 | ||
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 39cf568ccfaf..ea65db679e9c 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -82,7 +82,8 @@ unsigned long alloc_stack(int order, int atomic) | |||
82 | unsigned long page; | 82 | unsigned long page; |
83 | int flags = GFP_KERNEL; | 83 | int flags = GFP_KERNEL; |
84 | 84 | ||
85 | if(atomic) flags |= GFP_ATOMIC; | 85 | if (atomic) |
86 | flags = GFP_ATOMIC; | ||
86 | page = __get_free_pages(flags, order); | 87 | page = __get_free_pages(flags, order); |
87 | if(page == 0) | 88 | if(page == 0) |
88 | return(0); | 89 | return(0); |
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index e89218958f38..a52751108aa1 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c | |||
@@ -340,7 +340,7 @@ static int setup_initial_poll(int fd) | |||
340 | { | 340 | { |
341 | struct pollfd *p; | 341 | struct pollfd *p; |
342 | 342 | ||
343 | p = um_kmalloc(sizeof(struct pollfd)); | 343 | p = um_kmalloc_atomic(sizeof(struct pollfd)); |
344 | if(p == NULL){ | 344 | if(p == NULL){ |
345 | printk("setup_initial_poll : failed to allocate poll\n"); | 345 | printk("setup_initial_poll : failed to allocate poll\n"); |
346 | return(-1); | 346 | return(-1); |
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 0a562c3c0fd8..f5b0636f9ad7 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c | |||
@@ -193,12 +193,12 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, | |||
193 | r = pte_read(*npte); | 193 | r = pte_read(*npte); |
194 | w = pte_write(*npte); | 194 | w = pte_write(*npte); |
195 | x = pte_exec(*npte); | 195 | x = pte_exec(*npte); |
196 | if(!pte_dirty(*npte)) | 196 | if (!pte_young(*npte)) { |
197 | w = 0; | 197 | r = 0; |
198 | if(!pte_young(*npte)){ | 198 | w = 0; |
199 | r = 0; | 199 | } else if (!pte_dirty(*npte)) { |
200 | w = 0; | 200 | w = 0; |
201 | } | 201 | } |
202 | if(force || pte_newpage(*npte)){ | 202 | if(force || pte_newpage(*npte)){ |
203 | if(pte_present(*npte)) | 203 | if(pte_present(*npte)) |
204 | ret = add_mmap(addr, | 204 | ret = add_mmap(addr, |
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 87cc6fd76ced..d297429ac360 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "asm/a.out.h" | 18 | #include "asm/a.out.h" |
19 | #include "asm/current.h" | 19 | #include "asm/current.h" |
20 | #include "asm/irq.h" | 20 | #include "asm/irq.h" |
21 | #include "sysdep/sigcontext.h" | ||
21 | #include "user_util.h" | 22 | #include "user_util.h" |
22 | #include "kern_util.h" | 23 | #include "kern_util.h" |
23 | #include "kern.h" | 24 | #include "kern.h" |
@@ -39,6 +40,12 @@ int handle_page_fault(unsigned long address, unsigned long ip, | |||
39 | int err = -EFAULT; | 40 | int err = -EFAULT; |
40 | 41 | ||
41 | *code_out = SEGV_MAPERR; | 42 | *code_out = SEGV_MAPERR; |
43 | |||
44 | /* If the fault was during atomic operation, don't take the fault, just | ||
45 | * fail. */ | ||
46 | if (in_atomic()) | ||
47 | goto out_nosemaphore; | ||
48 | |||
42 | down_read(&mm->mmap_sem); | 49 | down_read(&mm->mmap_sem); |
43 | vma = find_vma(mm, address); | 50 | vma = find_vma(mm, address); |
44 | if(!vma) | 51 | if(!vma) |
@@ -89,6 +96,7 @@ survive: | |||
89 | flush_tlb_page(vma, address); | 96 | flush_tlb_page(vma, address); |
90 | out: | 97 | out: |
91 | up_read(&mm->mmap_sem); | 98 | up_read(&mm->mmap_sem); |
99 | out_nosemaphore: | ||
92 | return(err); | 100 | return(err); |
93 | 101 | ||
94 | /* | 102 | /* |
@@ -125,7 +133,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |||
125 | } | 133 | } |
126 | else if(current->mm == NULL) | 134 | else if(current->mm == NULL) |
127 | panic("Segfault with no mm"); | 135 | panic("Segfault with no mm"); |
128 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | 136 | |
137 | if (SEGV_IS_FIXABLE(&fi)) | ||
138 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | ||
139 | else { | ||
140 | err = -EFAULT; | ||
141 | /* A thread accessed NULL, we get a fault, but CR2 is invalid. | ||
142 | * This code is used in __do_copy_from_user() of TT mode. */ | ||
143 | address = 0; | ||
144 | } | ||
129 | 145 | ||
130 | catcher = current->thread.fault_catcher; | 146 | catcher = current->thread.fault_catcher; |
131 | if(!err) | 147 | if(!err) |
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c index f01475512ecb..8c220f054b61 100644 --- a/arch/um/kernel/tt/uaccess_user.c +++ b/arch/um/kernel/tt/uaccess_user.c | |||
@@ -22,8 +22,15 @@ int __do_copy_from_user(void *to, const void *from, int n, | |||
22 | __do_copy, &faulted); | 22 | __do_copy, &faulted); |
23 | TASK_REGS(get_current())->tt = save; | 23 | TASK_REGS(get_current())->tt = save; |
24 | 24 | ||
25 | if(!faulted) return(0); | 25 | if(!faulted) |
26 | else return(n - (fault - (unsigned long) from)); | 26 | return 0; |
27 | else if (fault) | ||
28 | return n - (fault - (unsigned long) from); | ||
29 | else | ||
30 | /* In case of a general protection fault, we don't have the | ||
31 | * fault address, so NULL is used instead. Pretend we didn't | ||
32 | * copy anything. */ | ||
33 | return n; | ||
27 | } | 34 | } |
28 | 35 | ||
29 | static void __do_strncpy(void *dst, const void *src, int count) | 36 | static void __do_strncpy(void *dst, const void *src, int count) |
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c index 186c28885016..0b21d59ba0cd 100644 --- a/arch/um/kernel/umid.c +++ b/arch/um/kernel/umid.c | |||
@@ -31,6 +31,8 @@ static char *uml_dir = UML_DIR; | |||
31 | /* Changed by set_umid */ | 31 | /* Changed by set_umid */ |
32 | static int umid_is_random = 1; | 32 | static int umid_is_random = 1; |
33 | static int umid_inited = 0; | 33 | static int umid_inited = 0; |
34 | /* Have we created the files? Should we remove them? */ | ||
35 | static int umid_owned = 0; | ||
34 | 36 | ||
35 | static int make_umid(int (*printer)(const char *fmt, ...)); | 37 | static int make_umid(int (*printer)(const char *fmt, ...)); |
36 | 38 | ||
@@ -82,20 +84,21 @@ int __init umid_file_name(char *name, char *buf, int len) | |||
82 | 84 | ||
83 | extern int tracing_pid; | 85 | extern int tracing_pid; |
84 | 86 | ||
85 | static int __init create_pid_file(void) | 87 | static void __init create_pid_file(void) |
86 | { | 88 | { |
87 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; | 89 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; |
88 | char pid[sizeof("nnnnn\0")]; | 90 | char pid[sizeof("nnnnn\0")]; |
89 | int fd, n; | 91 | int fd, n; |
90 | 92 | ||
91 | if(umid_file_name("pid", file, sizeof(file))) return 0; | 93 | if(umid_file_name("pid", file, sizeof(file))) |
94 | return; | ||
92 | 95 | ||
93 | fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), | 96 | fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), |
94 | 0644); | 97 | 0644); |
95 | if(fd < 0){ | 98 | if(fd < 0){ |
96 | printf("Open of machine pid file \"%s\" failed: %s\n", | 99 | printf("Open of machine pid file \"%s\" failed: %s\n", |
97 | file, strerror(-fd)); | 100 | file, strerror(-fd)); |
98 | return 0; | 101 | return; |
99 | } | 102 | } |
100 | 103 | ||
101 | sprintf(pid, "%d\n", os_getpid()); | 104 | sprintf(pid, "%d\n", os_getpid()); |
@@ -103,7 +106,6 @@ static int __init create_pid_file(void) | |||
103 | if(n != strlen(pid)) | 106 | if(n != strlen(pid)) |
104 | printf("Write of pid file failed - err = %d\n", -n); | 107 | printf("Write of pid file failed - err = %d\n", -n); |
105 | os_close_file(fd); | 108 | os_close_file(fd); |
106 | return 0; | ||
107 | } | 109 | } |
108 | 110 | ||
109 | static int actually_do_remove(char *dir) | 111 | static int actually_do_remove(char *dir) |
@@ -147,7 +149,8 @@ static int actually_do_remove(char *dir) | |||
147 | void remove_umid_dir(void) | 149 | void remove_umid_dir(void) |
148 | { | 150 | { |
149 | char dir[strlen(uml_dir) + UMID_LEN + 1]; | 151 | char dir[strlen(uml_dir) + UMID_LEN + 1]; |
150 | if(!umid_inited) return; | 152 | if (!umid_owned) |
153 | return; | ||
151 | 154 | ||
152 | sprintf(dir, "%s%s", uml_dir, umid); | 155 | sprintf(dir, "%s%s", uml_dir, umid); |
153 | actually_do_remove(dir); | 156 | actually_do_remove(dir); |
@@ -155,11 +158,12 @@ void remove_umid_dir(void) | |||
155 | 158 | ||
156 | char *get_umid(int only_if_set) | 159 | char *get_umid(int only_if_set) |
157 | { | 160 | { |
158 | if(only_if_set && umid_is_random) return(NULL); | 161 | if(only_if_set && umid_is_random) |
159 | return(umid); | 162 | return NULL; |
163 | return umid; | ||
160 | } | 164 | } |
161 | 165 | ||
162 | int not_dead_yet(char *dir) | 166 | static int not_dead_yet(char *dir) |
163 | { | 167 | { |
164 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; | 168 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; |
165 | char pid[sizeof("nnnnn\0")], *end; | 169 | char pid[sizeof("nnnnn\0")], *end; |
@@ -193,7 +197,8 @@ int not_dead_yet(char *dir) | |||
193 | (p == CHOOSE_MODE(tracing_pid, os_getpid()))) | 197 | (p == CHOOSE_MODE(tracing_pid, os_getpid()))) |
194 | dead = 1; | 198 | dead = 1; |
195 | } | 199 | } |
196 | if(!dead) return(1); | 200 | if(!dead) |
201 | return(1); | ||
197 | return(actually_do_remove(dir)); | 202 | return(actually_do_remove(dir)); |
198 | } | 203 | } |
199 | 204 | ||
@@ -232,16 +237,13 @@ static int __init make_uml_dir(void) | |||
232 | strlcpy(dir, home, sizeof(dir)); | 237 | strlcpy(dir, home, sizeof(dir)); |
233 | uml_dir++; | 238 | uml_dir++; |
234 | } | 239 | } |
240 | strlcat(dir, uml_dir, sizeof(dir)); | ||
235 | len = strlen(dir); | 241 | len = strlen(dir); |
236 | strncat(dir, uml_dir, sizeof(dir) - len); | 242 | if (len > 0 && dir[len - 1] != '/') |
237 | len = strlen(dir); | 243 | strlcat(dir, "/", sizeof(dir)); |
238 | if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){ | ||
239 | dir[len] = '/'; | ||
240 | dir[len + 1] = '\0'; | ||
241 | } | ||
242 | 244 | ||
243 | uml_dir = malloc(strlen(dir) + 1); | 245 | uml_dir = malloc(strlen(dir) + 1); |
244 | if(uml_dir == NULL){ | 246 | if (uml_dir == NULL) { |
245 | printf("make_uml_dir : malloc failed, errno = %d\n", errno); | 247 | printf("make_uml_dir : malloc failed, errno = %d\n", errno); |
246 | exit(1); | 248 | exit(1); |
247 | } | 249 | } |
@@ -286,6 +288,7 @@ static int __init make_umid(int (*printer)(const char *fmt, ...)) | |||
286 | if(errno == EEXIST){ | 288 | if(errno == EEXIST){ |
287 | if(not_dead_yet(tmp)){ | 289 | if(not_dead_yet(tmp)){ |
288 | (*printer)("umid '%s' is in use\n", umid); | 290 | (*printer)("umid '%s' is in use\n", umid); |
291 | umid_owned = 0; | ||
289 | return(-1); | 292 | return(-1); |
290 | } | 293 | } |
291 | err = mkdir(tmp, 0777); | 294 | err = mkdir(tmp, 0777); |
@@ -296,7 +299,8 @@ static int __init make_umid(int (*printer)(const char *fmt, ...)) | |||
296 | return(-1); | 299 | return(-1); |
297 | } | 300 | } |
298 | 301 | ||
299 | return(0); | 302 | umid_owned = 1; |
303 | return 0; | ||
300 | } | 304 | } |
301 | 305 | ||
302 | __uml_setup("uml_dir=", set_uml_dir, | 306 | __uml_setup("uml_dir=", set_uml_dir, |
@@ -309,7 +313,8 @@ static int __init make_umid_setup(void) | |||
309 | /* one function with the ordering we need ... */ | 313 | /* one function with the ordering we need ... */ |
310 | make_uml_dir(); | 314 | make_uml_dir(); |
311 | make_umid(printf); | 315 | make_umid(printf); |
312 | return create_pid_file(); | 316 | create_pid_file(); |
317 | return 0; | ||
313 | } | 318 | } |
314 | __uml_postsetup(make_umid_setup); | 319 | __uml_postsetup(make_umid_setup); |
315 | 320 | ||
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 09887c96e9a1..de19501aa809 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c | |||
@@ -402,8 +402,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
402 | __pci_mmap_set_flags(dev, vma, mmap_state); | 402 | __pci_mmap_set_flags(dev, vma, mmap_state); |
403 | __pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine); | 403 | __pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine); |
404 | 404 | ||
405 | ret = io_remap_page_range(vma, vma->vm_start, vma->vm_pgoff<<PAGE_SHIFT, | 405 | ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
406 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 406 | vma->vm_end - vma->vm_start,vma->vm_page_prot); |
407 | 407 | ||
408 | return ret; | 408 | return ret; |
409 | } | 409 | } |
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c index cf1362784443..03674daabc66 100644 --- a/arch/xtensa/kernel/platform.c +++ b/arch/xtensa/kernel/platform.c | |||
@@ -39,7 +39,7 @@ _F(int, pcibios_fixup, (void), { return 0; }); | |||
39 | _F(int, get_rtc_time, (time_t* t), { return 0; }); | 39 | _F(int, get_rtc_time, (time_t* t), { return 0; }); |
40 | _F(int, set_rtc_time, (time_t t), { return 0; }); | 40 | _F(int, set_rtc_time, (time_t t), { return 0; }); |
41 | 41 | ||
42 | #if CONFIG_XTENSA_CALIBRATE_CCOUNT | 42 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT |
43 | _F(void, calibrate_ccount, (void), | 43 | _F(void, calibrate_ccount, (void), |
44 | { | 44 | { |
45 | printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n"); | 45 | printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n"); |
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index c83bb0d41787..08ef6d82ee51 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c | |||
@@ -457,7 +457,7 @@ int | |||
457 | dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r) | 457 | dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r) |
458 | { | 458 | { |
459 | /* see asm/coprocessor.h for this magic number 16 */ | 459 | /* see asm/coprocessor.h for this magic number 16 */ |
460 | #if TOTAL_CPEXTRA_SIZE > 16 | 460 | #if XTENSA_CP_EXTRA_SIZE > 16 |
461 | do_save_fpregs (r, regs, task); | 461 | do_save_fpregs (r, regs, task); |
462 | 462 | ||
463 | /* For now, bit 16 means some extra state may be present: */ | 463 | /* For now, bit 16 means some extra state may be present: */ |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 1f5bf5d624e4..513ed8d67766 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p) | |||
304 | # endif | 304 | # endif |
305 | #endif | 305 | #endif |
306 | 306 | ||
307 | #if CONFIG_PCI | 307 | #ifdef CONFIG_PCI |
308 | platform_pcibios_init(); | 308 | platform_pcibios_init(); |
309 | #endif | 309 | #endif |
310 | } | 310 | } |
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index dc42cede9394..e252b61e45a5 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
@@ -182,7 +182,7 @@ restore_cpextra (struct _cpstate *buf) | |||
182 | 182 | ||
183 | struct task_struct *tsk = current; | 183 | struct task_struct *tsk = current; |
184 | release_all_cp(tsk); | 184 | release_all_cp(tsk); |
185 | return __copy_from_user(tsk->thread.cpextra, buf, TOTAL_CPEXTRA_SIZE); | 185 | return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE); |
186 | #endif | 186 | #endif |
187 | return 0; | 187 | return 0; |
188 | } | 188 | } |
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 1ac7d5ce7456..8e423d1335ce 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c | |||
@@ -68,7 +68,7 @@ void __init time_init(void) | |||
68 | * speed for the CALIBRATE. | 68 | * speed for the CALIBRATE. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | #if CONFIG_XTENSA_CALIBRATE_CCOUNT | 71 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT |
72 | printk("Calibrating CPU frequency "); | 72 | printk("Calibrating CPU frequency "); |
73 | platform_calibrate_ccount(); | 73 | platform_calibrate_ccount(); |
74 | printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ), | 74 | printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ), |
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 56aace84aaeb..5a91d6c9e66d 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -239,7 +239,7 @@ void __init mem_init(void) | |||
239 | high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); | 239 | high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); |
240 | highmemsize = 0; | 240 | highmemsize = 0; |
241 | 241 | ||
242 | #if CONFIG_HIGHMEM | 242 | #ifdef CONFIG_HIGHMEM |
243 | #error HIGHGMEM not implemented in init.c | 243 | #error HIGHGMEM not implemented in init.c |
244 | #endif | 244 | #endif |
245 | 245 | ||
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index de0379b6d502..c055bb630ffc 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -273,7 +273,6 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | |||
273 | 273 | ||
274 | vma->vm_flags |= VM_IO; | 274 | vma->vm_flags |= VM_IO; |
275 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 275 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
276 | addr = __pa(addr); | ||
277 | 276 | ||
278 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, | 277 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, |
279 | PAGE_SIZE, vma->vm_page_prot)) { | 278 | PAGE_SIZE, vma->vm_page_prot)) { |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 463351d4f942..32fa82c78c73 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -2620,7 +2620,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf, | |||
2620 | spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); | 2620 | spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); |
2621 | if (!list_empty(&(intf->waiting_msgs))) { | 2621 | if (!list_empty(&(intf->waiting_msgs))) { |
2622 | list_add_tail(&(msg->link), &(intf->waiting_msgs)); | 2622 | list_add_tail(&(msg->link), &(intf->waiting_msgs)); |
2623 | spin_unlock(&(intf->waiting_msgs_lock)); | 2623 | spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); |
2624 | goto out_unlock; | 2624 | goto out_unlock; |
2625 | } | 2625 | } |
2626 | spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); | 2626 | spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); |
@@ -2629,9 +2629,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf, | |||
2629 | if (rv > 0) { | 2629 | if (rv > 0) { |
2630 | /* Could not handle the message now, just add it to a | 2630 | /* Could not handle the message now, just add it to a |
2631 | list to handle later. */ | 2631 | list to handle later. */ |
2632 | spin_lock(&(intf->waiting_msgs_lock)); | 2632 | spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); |
2633 | list_add_tail(&(msg->link), &(intf->waiting_msgs)); | 2633 | list_add_tail(&(msg->link), &(intf->waiting_msgs)); |
2634 | spin_unlock(&(intf->waiting_msgs_lock)); | 2634 | spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); |
2635 | } else if (rv == 0) { | 2635 | } else if (rv == 0) { |
2636 | ipmi_free_smi_msg(msg); | 2636 | ipmi_free_smi_msg(msg); |
2637 | } | 2637 | } |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 7e72e922b41c..db358cfa7cbf 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -418,12 +418,11 @@ config SENSORS_HDAPS | |||
418 | help | 418 | help |
419 | This driver provides support for the IBM Hard Drive Active Protection | 419 | This driver provides support for the IBM Hard Drive Active Protection |
420 | System (hdaps), which provides an accelerometer and other misc. data. | 420 | System (hdaps), which provides an accelerometer and other misc. data. |
421 | Supported laptops include the IBM ThinkPad T41, T42, T43, and R51. | 421 | ThinkPads starting with the R50, T41, and X40 are supported. The |
422 | The accelerometer data is readable via sysfs. | 422 | accelerometer data is readable via sysfs. |
423 | 423 | ||
424 | This driver also provides an input class device, allowing the | 424 | This driver also provides an absolute input class device, allowing |
425 | laptop to act as a pinball machine-esque mouse. This is off by | 425 | the laptop to act as a pinball machine-esque joystick. |
426 | default but enabled via sysfs or the module parameter "mousedev". | ||
427 | 426 | ||
428 | Say Y here if you have an applicable laptop and want to experience | 427 | Say Y here if you have an applicable laptop and want to experience |
429 | the awesome power of hdaps. | 428 | the awesome power of hdaps. |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 4c56411f3993..7f0107613827 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -4,9 +4,9 @@ | |||
4 | * Copyright (C) 2005 Robert Love <rml@novell.com> | 4 | * Copyright (C) 2005 Robert Love <rml@novell.com> |
5 | * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com> | 5 | * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com> |
6 | * | 6 | * |
7 | * The HardDisk Active Protection System (hdaps) is present in the IBM ThinkPad | 7 | * The HardDisk Active Protection System (hdaps) is present in IBM ThinkPads |
8 | * T41, T42, T43, R50, R50p, R51, and X40, at least. It provides a basic | 8 | * starting with the R40, T41, and X40. It provides a basic two-axis |
9 | * two-axis accelerometer and other data, such as the device's temperature. | 9 | * accelerometer and other data, such as the device's temperature. |
10 | * | 10 | * |
11 | * This driver is based on the document by Mark A. Smith available at | 11 | * This driver is based on the document by Mark A. Smith available at |
12 | * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial | 12 | * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial |
@@ -487,24 +487,19 @@ static struct attribute_group hdaps_attribute_group = { | |||
487 | 487 | ||
488 | /* Module stuff */ | 488 | /* Module stuff */ |
489 | 489 | ||
490 | /* | 490 | /* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */ |
491 | * XXX: We should be able to return nonzero and halt the detection process. | ||
492 | * But there is a bug in dmi_check_system() where a nonzero return from the | ||
493 | * first match will result in a return of failure from dmi_check_system(). | ||
494 | * I fixed this; the patch is 2.6-git. Once in a released tree, we can make | ||
495 | * hdaps_dmi_match_invert() return hdaps_dmi_match(), which in turn returns 1. | ||
496 | */ | ||
497 | static int hdaps_dmi_match(struct dmi_system_id *id) | 491 | static int hdaps_dmi_match(struct dmi_system_id *id) |
498 | { | 492 | { |
499 | printk(KERN_INFO "hdaps: %s detected.\n", id->ident); | 493 | printk(KERN_INFO "hdaps: %s detected.\n", id->ident); |
500 | return 0; | 494 | return 1; |
501 | } | 495 | } |
502 | 496 | ||
497 | /* hdaps_dmi_match_invert - found an inverted match. */ | ||
503 | static int hdaps_dmi_match_invert(struct dmi_system_id *id) | 498 | static int hdaps_dmi_match_invert(struct dmi_system_id *id) |
504 | { | 499 | { |
505 | hdaps_invert = 1; | 500 | hdaps_invert = 1; |
506 | printk(KERN_INFO "hdaps: inverting axis readings.\n"); | 501 | printk(KERN_INFO "hdaps: inverting axis readings.\n"); |
507 | return 0; | 502 | return hdaps_dmi_match(id); |
508 | } | 503 | } |
509 | 504 | ||
510 | #define HDAPS_DMI_MATCH_NORMAL(model) { \ | 505 | #define HDAPS_DMI_MATCH_NORMAL(model) { \ |
@@ -534,6 +529,7 @@ static int __init hdaps_init(void) | |||
534 | HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), | 529 | HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), |
535 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), | 530 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), |
536 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), | 531 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), |
532 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"), | ||
537 | HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"), | 533 | HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"), |
538 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"), | 534 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"), |
539 | HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), | 535 | HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), |
@@ -541,6 +537,7 @@ static int __init hdaps_init(void) | |||
541 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), | 537 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), |
542 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), | 538 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), |
543 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), | 539 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), |
540 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), | ||
544 | { .ident = NULL } | 541 | { .ident = NULL } |
545 | }; | 542 | }; |
546 | 543 | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 8334496a7e0a..3badfec75b1c 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -245,6 +245,18 @@ config I2C_KEYWEST | |||
245 | This support is also available as a module. If so, the module | 245 | This support is also available as a module. If so, the module |
246 | will be called i2c-keywest. | 246 | will be called i2c-keywest. |
247 | 247 | ||
248 | config I2C_PMAC_SMU | ||
249 | tristate "Powermac SMU I2C interface" | ||
250 | depends on I2C && PMAC_SMU | ||
251 | help | ||
252 | This supports the use of the I2C interface in the SMU | ||
253 | chip on recent Apple machines like the iMac G5. It is used | ||
254 | among others by the thermal control driver for those machines. | ||
255 | Say Y if you have such a machine. | ||
256 | |||
257 | This support is also available as a module. If so, the module | ||
258 | will be called i2c-pmac-smu. | ||
259 | |||
248 | config I2C_MPC | 260 | config I2C_MPC |
249 | tristate "MPC107/824x/85xx/52xx" | 261 | tristate "MPC107/824x/85xx/52xx" |
250 | depends on I2C && PPC32 | 262 | depends on I2C && PPC32 |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 980b3e983670..f1df00f66c6c 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_ITE) += i2c-ite.o | |||
20 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o | 20 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o |
21 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o | 21 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o |
22 | obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o | 22 | obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o |
23 | obj-$(CONFIG_I2C_PMAC_SMU) += i2c-pmac-smu.o | ||
23 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o | 24 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o |
24 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o | 25 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o |
25 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o | 26 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o |
diff --git a/drivers/i2c/busses/i2c-pmac-smu.c b/drivers/i2c/busses/i2c-pmac-smu.c new file mode 100644 index 000000000000..8a9f5648a23d --- /dev/null +++ b/drivers/i2c/busses/i2c-pmac-smu.c | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | i2c Support for Apple SMU Controller | ||
3 | |||
4 | Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp. | ||
5 | <benh@kernel.crashing.org> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | */ | ||
22 | |||
23 | #include <linux/config.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/completion.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <asm/prom.h> | ||
32 | #include <asm/of_device.h> | ||
33 | #include <asm/smu.h> | ||
34 | |||
35 | static int probe; | ||
36 | |||
37 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | ||
38 | MODULE_DESCRIPTION("I2C driver for Apple's SMU"); | ||
39 | MODULE_LICENSE("GPL"); | ||
40 | module_param(probe, bool, 0); | ||
41 | |||
42 | |||
43 | /* Physical interface */ | ||
44 | struct smu_iface | ||
45 | { | ||
46 | struct i2c_adapter adapter; | ||
47 | struct completion complete; | ||
48 | u32 busid; | ||
49 | }; | ||
50 | |||
51 | static void smu_i2c_done(struct smu_i2c_cmd *cmd, void *misc) | ||
52 | { | ||
53 | struct smu_iface *iface = misc; | ||
54 | complete(&iface->complete); | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * SMBUS-type transfer entrypoint | ||
59 | */ | ||
60 | static s32 smu_smbus_xfer( struct i2c_adapter* adap, | ||
61 | u16 addr, | ||
62 | unsigned short flags, | ||
63 | char read_write, | ||
64 | u8 command, | ||
65 | int size, | ||
66 | union i2c_smbus_data* data) | ||
67 | { | ||
68 | struct smu_iface *iface = i2c_get_adapdata(adap); | ||
69 | struct smu_i2c_cmd cmd; | ||
70 | int rc = 0; | ||
71 | int read = (read_write == I2C_SMBUS_READ); | ||
72 | |||
73 | cmd.info.bus = iface->busid; | ||
74 | cmd.info.devaddr = (addr << 1) | (read ? 0x01 : 0x00); | ||
75 | |||
76 | /* Prepare datas & select mode */ | ||
77 | switch (size) { | ||
78 | case I2C_SMBUS_QUICK: | ||
79 | cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; | ||
80 | cmd.info.datalen = 0; | ||
81 | break; | ||
82 | case I2C_SMBUS_BYTE: | ||
83 | cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; | ||
84 | cmd.info.datalen = 1; | ||
85 | if (!read) | ||
86 | cmd.info.data[0] = data->byte; | ||
87 | break; | ||
88 | case I2C_SMBUS_BYTE_DATA: | ||
89 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
90 | cmd.info.datalen = 1; | ||
91 | cmd.info.sublen = 1; | ||
92 | cmd.info.subaddr[0] = command; | ||
93 | cmd.info.subaddr[1] = 0; | ||
94 | cmd.info.subaddr[2] = 0; | ||
95 | if (!read) | ||
96 | cmd.info.data[0] = data->byte; | ||
97 | break; | ||
98 | case I2C_SMBUS_WORD_DATA: | ||
99 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
100 | cmd.info.datalen = 2; | ||
101 | cmd.info.sublen = 1; | ||
102 | cmd.info.subaddr[0] = command; | ||
103 | cmd.info.subaddr[1] = 0; | ||
104 | cmd.info.subaddr[2] = 0; | ||
105 | if (!read) { | ||
106 | cmd.info.data[0] = data->byte & 0xff; | ||
107 | cmd.info.data[1] = (data->byte >> 8) & 0xff; | ||
108 | } | ||
109 | break; | ||
110 | /* Note that these are broken vs. the expected smbus API where | ||
111 | * on reads, the lenght is actually returned from the function, | ||
112 | * but I think the current API makes no sense and I don't want | ||
113 | * any driver that I haven't verified for correctness to go | ||
114 | * anywhere near a pmac i2c bus anyway ... | ||
115 | */ | ||
116 | case I2C_SMBUS_BLOCK_DATA: | ||
117 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
118 | cmd.info.datalen = data->block[0] + 1; | ||
119 | if (cmd.info.datalen > 6) | ||
120 | return -EINVAL; | ||
121 | if (!read) | ||
122 | memcpy(cmd.info.data, data->block, cmd.info.datalen); | ||
123 | cmd.info.sublen = 1; | ||
124 | cmd.info.subaddr[0] = command; | ||
125 | cmd.info.subaddr[1] = 0; | ||
126 | cmd.info.subaddr[2] = 0; | ||
127 | break; | ||
128 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
129 | cmd.info.type = SMU_I2C_TRANSFER_STDSUB; | ||
130 | cmd.info.datalen = data->block[0]; | ||
131 | if (cmd.info.datalen > 7) | ||
132 | return -EINVAL; | ||
133 | if (!read) | ||
134 | memcpy(cmd.info.data, &data->block[1], | ||
135 | cmd.info.datalen); | ||
136 | cmd.info.sublen = 1; | ||
137 | cmd.info.subaddr[0] = command; | ||
138 | cmd.info.subaddr[1] = 0; | ||
139 | cmd.info.subaddr[2] = 0; | ||
140 | break; | ||
141 | |||
142 | default: | ||
143 | return -EINVAL; | ||
144 | } | ||
145 | |||
146 | /* Turn a standardsub read into a combined mode access */ | ||
147 | if (read_write == I2C_SMBUS_READ && | ||
148 | cmd.info.type == SMU_I2C_TRANSFER_STDSUB) | ||
149 | cmd.info.type = SMU_I2C_TRANSFER_COMBINED; | ||
150 | |||
151 | /* Finish filling command and submit it */ | ||
152 | cmd.done = smu_i2c_done; | ||
153 | cmd.misc = iface; | ||
154 | rc = smu_queue_i2c(&cmd); | ||
155 | if (rc < 0) | ||
156 | return rc; | ||
157 | wait_for_completion(&iface->complete); | ||
158 | rc = cmd.status; | ||
159 | |||
160 | if (!read || rc < 0) | ||
161 | return rc; | ||
162 | |||
163 | switch (size) { | ||
164 | case I2C_SMBUS_BYTE: | ||
165 | case I2C_SMBUS_BYTE_DATA: | ||
166 | data->byte = cmd.info.data[0]; | ||
167 | break; | ||
168 | case I2C_SMBUS_WORD_DATA: | ||
169 | data->word = ((u16)cmd.info.data[1]) << 8; | ||
170 | data->word |= cmd.info.data[0]; | ||
171 | break; | ||
172 | /* Note that these are broken vs. the expected smbus API where | ||
173 | * on reads, the lenght is actually returned from the function, | ||
174 | * but I think the current API makes no sense and I don't want | ||
175 | * any driver that I haven't verified for correctness to go | ||
176 | * anywhere near a pmac i2c bus anyway ... | ||
177 | */ | ||
178 | case I2C_SMBUS_BLOCK_DATA: | ||
179 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
180 | memcpy(&data->block[0], cmd.info.data, cmd.info.datalen); | ||
181 | break; | ||
182 | } | ||
183 | |||
184 | return rc; | ||
185 | } | ||
186 | |||
187 | static u32 | ||
188 | smu_smbus_func(struct i2c_adapter * adapter) | ||
189 | { | ||
190 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | ||
191 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | ||
192 | I2C_FUNC_SMBUS_BLOCK_DATA; | ||
193 | } | ||
194 | |||
195 | /* For now, we only handle combined mode (smbus) */ | ||
196 | static struct i2c_algorithm smu_algorithm = { | ||
197 | .smbus_xfer = smu_smbus_xfer, | ||
198 | .functionality = smu_smbus_func, | ||
199 | }; | ||
200 | |||
201 | static int create_iface(struct device_node *np, struct device *dev) | ||
202 | { | ||
203 | struct smu_iface* iface; | ||
204 | u32 *reg, busid; | ||
205 | int rc; | ||
206 | |||
207 | reg = (u32 *)get_property(np, "reg", NULL); | ||
208 | if (reg == NULL) { | ||
209 | printk(KERN_ERR "i2c-pmac-smu: can't find bus number !\n"); | ||
210 | return -ENXIO; | ||
211 | } | ||
212 | busid = *reg; | ||
213 | |||
214 | iface = kmalloc(sizeof(struct smu_iface), GFP_KERNEL); | ||
215 | if (iface == NULL) { | ||
216 | printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n"); | ||
217 | return -ENOMEM; | ||
218 | } | ||
219 | memset(iface, 0, sizeof(struct smu_iface)); | ||
220 | init_completion(&iface->complete); | ||
221 | iface->busid = busid; | ||
222 | |||
223 | dev_set_drvdata(dev, iface); | ||
224 | |||
225 | sprintf(iface->adapter.name, "smu-i2c-%02x", busid); | ||
226 | iface->adapter.algo = &smu_algorithm; | ||
227 | iface->adapter.algo_data = NULL; | ||
228 | iface->adapter.client_register = NULL; | ||
229 | iface->adapter.client_unregister = NULL; | ||
230 | i2c_set_adapdata(&iface->adapter, iface); | ||
231 | iface->adapter.dev.parent = dev; | ||
232 | |||
233 | rc = i2c_add_adapter(&iface->adapter); | ||
234 | if (rc) { | ||
235 | printk(KERN_ERR "i2c-pamc-smu.c: Adapter %s registration " | ||
236 | "failed\n", iface->adapter.name); | ||
237 | i2c_set_adapdata(&iface->adapter, NULL); | ||
238 | } | ||
239 | |||
240 | if (probe) { | ||
241 | unsigned char addr; | ||
242 | printk("Probe: "); | ||
243 | for (addr = 0x00; addr <= 0x7f; addr++) { | ||
244 | if (i2c_smbus_xfer(&iface->adapter,addr, | ||
245 | 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) | ||
246 | printk("%02x ", addr); | ||
247 | } | ||
248 | printk("\n"); | ||
249 | } | ||
250 | |||
251 | printk(KERN_INFO "SMU i2c bus %x registered\n", busid); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int dispose_iface(struct device *dev) | ||
257 | { | ||
258 | struct smu_iface *iface = dev_get_drvdata(dev); | ||
259 | int rc; | ||
260 | |||
261 | rc = i2c_del_adapter(&iface->adapter); | ||
262 | i2c_set_adapdata(&iface->adapter, NULL); | ||
263 | /* We aren't that prepared to deal with this... */ | ||
264 | if (rc) | ||
265 | printk("i2c-pmac-smu.c: Failed to remove bus %s !\n", | ||
266 | iface->adapter.name); | ||
267 | dev_set_drvdata(dev, NULL); | ||
268 | kfree(iface); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | |||
274 | static int create_iface_of_platform(struct of_device* dev, | ||
275 | const struct of_device_id *match) | ||
276 | { | ||
277 | return create_iface(dev->node, &dev->dev); | ||
278 | } | ||
279 | |||
280 | |||
281 | static int dispose_iface_of_platform(struct of_device* dev) | ||
282 | { | ||
283 | return dispose_iface(&dev->dev); | ||
284 | } | ||
285 | |||
286 | |||
287 | static struct of_device_id i2c_smu_match[] = | ||
288 | { | ||
289 | { | ||
290 | .compatible = "smu-i2c", | ||
291 | }, | ||
292 | {}, | ||
293 | }; | ||
294 | static struct of_platform_driver i2c_smu_of_platform_driver = | ||
295 | { | ||
296 | .name = "i2c-smu", | ||
297 | .match_table = i2c_smu_match, | ||
298 | .probe = create_iface_of_platform, | ||
299 | .remove = dispose_iface_of_platform | ||
300 | }; | ||
301 | |||
302 | |||
303 | static int __init i2c_pmac_smu_init(void) | ||
304 | { | ||
305 | of_register_driver(&i2c_smu_of_platform_driver); | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | |||
310 | static void __exit i2c_pmac_smu_cleanup(void) | ||
311 | { | ||
312 | of_unregister_driver(&i2c_smu_of_platform_driver); | ||
313 | } | ||
314 | |||
315 | module_init(i2c_pmac_smu_init); | ||
316 | module_exit(i2c_pmac_smu_cleanup); | ||
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index 0a2536d62402..657817a591fe 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c | |||
@@ -209,9 +209,7 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode) | |||
209 | bcs->mode = mode; | 209 | bcs->mode = mode; |
210 | 210 | ||
211 | // Cancel all USB transfers on this B channel | 211 | // Cancel all USB transfers on this B channel |
212 | b_out->urb[0]->transfer_flags |= URB_ASYNC_UNLINK; | ||
213 | usb_unlink_urb(b_out->urb[0]); | 212 | usb_unlink_urb(b_out->urb[0]); |
214 | b_out->urb[1]->transfer_flags |= URB_ASYNC_UNLINK; | ||
215 | usb_unlink_urb(b_out->urb[1]); | 213 | usb_unlink_urb(b_out->urb[1]); |
216 | b_out->busy = 0; | 214 | b_out->busy = 0; |
217 | 215 | ||
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index ffd5b2d45552..89fbeb58485d 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c | |||
@@ -645,9 +645,7 @@ void st5481_in_mode(struct st5481_in *in, int mode) | |||
645 | 645 | ||
646 | in->mode = mode; | 646 | in->mode = mode; |
647 | 647 | ||
648 | in->urb[0]->transfer_flags |= URB_ASYNC_UNLINK; | ||
649 | usb_unlink_urb(in->urb[0]); | 648 | usb_unlink_urb(in->urb[0]); |
650 | in->urb[1]->transfer_flags |= URB_ASYNC_UNLINK; | ||
651 | usb_unlink_urb(in->urb[1]); | 649 | usb_unlink_urb(in->urb[1]); |
652 | 650 | ||
653 | if (in->mode != L1_MODE_NULL) { | 651 | if (in->mode != L1_MODE_NULL) { |
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index fb535737d17d..a85ac18dd21d 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -8,21 +8,15 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * For now, this driver includes: | ||
12 | * - RTC get & set | ||
13 | * - reboot & shutdown commands | ||
14 | * all synchronous with IRQ disabled (ugh) | ||
15 | * | ||
16 | * TODO: | 11 | * TODO: |
17 | * rework in a way the PMU driver works, that is asynchronous | 12 | * - maybe add timeout to commands ? |
18 | * with a queue of commands. I'll do that as soon as I have an | 13 | * - blocking version of time functions |
19 | * SMU based machine at hand. Some more cleanup is needed too, | 14 | * - polling version of i2c commands (including timer that works with |
20 | * like maybe fitting it into a platform device, etc... | 15 | * interrutps off) |
21 | * Also check what's up with cache coherency, and if we really | 16 | * - maybe avoid some data copies with i2c by directly using the smu cmd |
22 | * can't do better than flushing the cache, maybe build a table | 17 | * buffer and a lower level internal interface |
23 | * of command len/reply len like the PMU driver to only flush | 18 | * - understand SMU -> CPU events and implement reception of them via |
24 | * what is actually necessary. | 19 | * the userland interface |
25 | * --BenH. | ||
26 | */ | 20 | */ |
27 | 21 | ||
28 | #include <linux/config.h> | 22 | #include <linux/config.h> |
@@ -36,6 +30,11 @@ | |||
36 | #include <linux/jiffies.h> | 30 | #include <linux/jiffies.h> |
37 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
38 | #include <linux/rtc.h> | 32 | #include <linux/rtc.h> |
33 | #include <linux/completion.h> | ||
34 | #include <linux/miscdevice.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/sysdev.h> | ||
37 | #include <linux/poll.h> | ||
39 | 38 | ||
40 | #include <asm/byteorder.h> | 39 | #include <asm/byteorder.h> |
41 | #include <asm/io.h> | 40 | #include <asm/io.h> |
@@ -45,8 +44,13 @@ | |||
45 | #include <asm/smu.h> | 44 | #include <asm/smu.h> |
46 | #include <asm/sections.h> | 45 | #include <asm/sections.h> |
47 | #include <asm/abs_addr.h> | 46 | #include <asm/abs_addr.h> |
47 | #include <asm/uaccess.h> | ||
48 | #include <asm/of_device.h> | ||
49 | |||
50 | #define VERSION "0.6" | ||
51 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." | ||
48 | 52 | ||
49 | #define DEBUG_SMU 1 | 53 | #undef DEBUG_SMU |
50 | 54 | ||
51 | #ifdef DEBUG_SMU | 55 | #ifdef DEBUG_SMU |
52 | #define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) | 56 | #define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) |
@@ -57,20 +61,30 @@ | |||
57 | /* | 61 | /* |
58 | * This is the command buffer passed to the SMU hardware | 62 | * This is the command buffer passed to the SMU hardware |
59 | */ | 63 | */ |
64 | #define SMU_MAX_DATA 254 | ||
65 | |||
60 | struct smu_cmd_buf { | 66 | struct smu_cmd_buf { |
61 | u8 cmd; | 67 | u8 cmd; |
62 | u8 length; | 68 | u8 length; |
63 | u8 data[0x0FFE]; | 69 | u8 data[SMU_MAX_DATA]; |
64 | }; | 70 | }; |
65 | 71 | ||
66 | struct smu_device { | 72 | struct smu_device { |
67 | spinlock_t lock; | 73 | spinlock_t lock; |
68 | struct device_node *of_node; | 74 | struct device_node *of_node; |
69 | int db_ack; /* doorbell ack GPIO */ | 75 | struct of_device *of_dev; |
70 | int db_req; /* doorbell req GPIO */ | 76 | int doorbell; /* doorbell gpio */ |
71 | u32 __iomem *db_buf; /* doorbell buffer */ | 77 | u32 __iomem *db_buf; /* doorbell buffer */ |
78 | int db_irq; | ||
79 | int msg; | ||
80 | int msg_irq; | ||
72 | struct smu_cmd_buf *cmd_buf; /* command buffer virtual */ | 81 | struct smu_cmd_buf *cmd_buf; /* command buffer virtual */ |
73 | u32 cmd_buf_abs; /* command buffer absolute */ | 82 | u32 cmd_buf_abs; /* command buffer absolute */ |
83 | struct list_head cmd_list; | ||
84 | struct smu_cmd *cmd_cur; /* pending command */ | ||
85 | struct list_head cmd_i2c_list; | ||
86 | struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ | ||
87 | struct timer_list i2c_timer; | ||
74 | }; | 88 | }; |
75 | 89 | ||
76 | /* | 90 | /* |
@@ -79,113 +93,243 @@ struct smu_device { | |||
79 | */ | 93 | */ |
80 | static struct smu_device *smu; | 94 | static struct smu_device *smu; |
81 | 95 | ||
96 | |||
82 | /* | 97 | /* |
83 | * SMU low level communication stuff | 98 | * SMU driver low level stuff |
84 | */ | 99 | */ |
85 | static inline int smu_cmd_stat(struct smu_cmd_buf *cmd_buf, u8 cmd_ack) | ||
86 | { | ||
87 | rmb(); | ||
88 | return cmd_buf->cmd == cmd_ack && cmd_buf->length != 0; | ||
89 | } | ||
90 | 100 | ||
91 | static inline u8 smu_save_ack_cmd(struct smu_cmd_buf *cmd_buf) | 101 | static void smu_start_cmd(void) |
92 | { | 102 | { |
93 | return (~cmd_buf->cmd) & 0xff; | 103 | unsigned long faddr, fend; |
94 | } | 104 | struct smu_cmd *cmd; |
95 | 105 | ||
96 | static void smu_send_cmd(struct smu_device *dev) | 106 | if (list_empty(&smu->cmd_list)) |
97 | { | 107 | return; |
98 | /* SMU command buf is currently cacheable, we need a physical | 108 | |
99 | * address. This isn't exactly a DMA mapping here, I suspect | 109 | /* Fetch first command in queue */ |
110 | cmd = list_entry(smu->cmd_list.next, struct smu_cmd, link); | ||
111 | smu->cmd_cur = cmd; | ||
112 | list_del(&cmd->link); | ||
113 | |||
114 | DPRINTK("SMU: starting cmd %x, %d bytes data\n", cmd->cmd, | ||
115 | cmd->data_len); | ||
116 | DPRINTK("SMU: data buffer: %02x %02x %02x %02x ...\n", | ||
117 | ((u8 *)cmd->data_buf)[0], ((u8 *)cmd->data_buf)[1], | ||
118 | ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3]); | ||
119 | |||
120 | /* Fill the SMU command buffer */ | ||
121 | smu->cmd_buf->cmd = cmd->cmd; | ||
122 | smu->cmd_buf->length = cmd->data_len; | ||
123 | memcpy(smu->cmd_buf->data, cmd->data_buf, cmd->data_len); | ||
124 | |||
125 | /* Flush command and data to RAM */ | ||
126 | faddr = (unsigned long)smu->cmd_buf; | ||
127 | fend = faddr + smu->cmd_buf->length + 2; | ||
128 | flush_inval_dcache_range(faddr, fend); | ||
129 | |||
130 | /* This isn't exactly a DMA mapping here, I suspect | ||
100 | * the SMU is actually communicating with us via i2c to the | 131 | * the SMU is actually communicating with us via i2c to the |
101 | * northbridge or the CPU to access RAM. | 132 | * northbridge or the CPU to access RAM. |
102 | */ | 133 | */ |
103 | writel(dev->cmd_buf_abs, dev->db_buf); | 134 | writel(smu->cmd_buf_abs, smu->db_buf); |
104 | 135 | ||
105 | /* Ring the SMU doorbell */ | 136 | /* Ring the SMU doorbell */ |
106 | pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, dev->db_req, 4); | 137 | pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, smu->doorbell, 4); |
107 | pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, dev->db_req, 4); | ||
108 | } | 138 | } |
109 | 139 | ||
110 | static int smu_cmd_done(struct smu_device *dev) | 140 | |
141 | static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs) | ||
111 | { | 142 | { |
112 | unsigned long wait = 0; | 143 | unsigned long flags; |
113 | int gpio; | 144 | struct smu_cmd *cmd; |
145 | void (*done)(struct smu_cmd *cmd, void *misc) = NULL; | ||
146 | void *misc = NULL; | ||
147 | u8 gpio; | ||
148 | int rc = 0; | ||
114 | 149 | ||
115 | /* Check the SMU doorbell */ | 150 | /* SMU completed the command, well, we hope, let's make sure |
116 | do { | 151 | * of it |
117 | gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, | 152 | */ |
118 | NULL, dev->db_ack); | 153 | spin_lock_irqsave(&smu->lock, flags); |
119 | if ((gpio & 7) == 7) | ||
120 | return 0; | ||
121 | udelay(100); | ||
122 | } while(++wait < 10000); | ||
123 | 154 | ||
124 | printk(KERN_ERR "SMU timeout !\n"); | 155 | gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); |
125 | return -ENXIO; | 156 | if ((gpio & 7) != 7) |
157 | return IRQ_HANDLED; | ||
158 | |||
159 | cmd = smu->cmd_cur; | ||
160 | smu->cmd_cur = NULL; | ||
161 | if (cmd == NULL) | ||
162 | goto bail; | ||
163 | |||
164 | if (rc == 0) { | ||
165 | unsigned long faddr; | ||
166 | int reply_len; | ||
167 | u8 ack; | ||
168 | |||
169 | /* CPU might have brought back the cache line, so we need | ||
170 | * to flush again before peeking at the SMU response. We | ||
171 | * flush the entire buffer for now as we haven't read the | ||
172 | * reply lenght (it's only 2 cache lines anyway) | ||
173 | */ | ||
174 | faddr = (unsigned long)smu->cmd_buf; | ||
175 | flush_inval_dcache_range(faddr, faddr + 256); | ||
176 | |||
177 | /* Now check ack */ | ||
178 | ack = (~cmd->cmd) & 0xff; | ||
179 | if (ack != smu->cmd_buf->cmd) { | ||
180 | DPRINTK("SMU: incorrect ack, want %x got %x\n", | ||
181 | ack, smu->cmd_buf->cmd); | ||
182 | rc = -EIO; | ||
183 | } | ||
184 | reply_len = rc == 0 ? smu->cmd_buf->length : 0; | ||
185 | DPRINTK("SMU: reply len: %d\n", reply_len); | ||
186 | if (reply_len > cmd->reply_len) { | ||
187 | printk(KERN_WARNING "SMU: reply buffer too small," | ||
188 | "got %d bytes for a %d bytes buffer\n", | ||
189 | reply_len, cmd->reply_len); | ||
190 | reply_len = cmd->reply_len; | ||
191 | } | ||
192 | cmd->reply_len = reply_len; | ||
193 | if (cmd->reply_buf && reply_len) | ||
194 | memcpy(cmd->reply_buf, smu->cmd_buf->data, reply_len); | ||
195 | } | ||
196 | |||
197 | /* Now complete the command. Write status last in order as we lost | ||
198 | * ownership of the command structure as soon as it's no longer -1 | ||
199 | */ | ||
200 | done = cmd->done; | ||
201 | misc = cmd->misc; | ||
202 | mb(); | ||
203 | cmd->status = rc; | ||
204 | bail: | ||
205 | /* Start next command if any */ | ||
206 | smu_start_cmd(); | ||
207 | spin_unlock_irqrestore(&smu->lock, flags); | ||
208 | |||
209 | /* Call command completion handler if any */ | ||
210 | if (done) | ||
211 | done(cmd, misc); | ||
212 | |||
213 | /* It's an edge interrupt, nothing to do */ | ||
214 | return IRQ_HANDLED; | ||
126 | } | 215 | } |
127 | 216 | ||
128 | static int smu_do_cmd(struct smu_device *dev) | 217 | |
218 | static irqreturn_t smu_msg_intr(int irq, void *arg, struct pt_regs *regs) | ||
129 | { | 219 | { |
130 | int rc; | 220 | /* I don't quite know what to do with this one, we seem to never |
131 | u8 cmd_ack; | 221 | * receive it, so I suspect we have to arm it someway in the SMU |
222 | * to start getting events that way. | ||
223 | */ | ||
224 | |||
225 | printk(KERN_INFO "SMU: message interrupt !\n"); | ||
132 | 226 | ||
133 | DPRINTK("SMU do_cmd %02x len=%d %02x\n", | 227 | /* It's an edge interrupt, nothing to do */ |
134 | dev->cmd_buf->cmd, dev->cmd_buf->length, | 228 | return IRQ_HANDLED; |
135 | dev->cmd_buf->data[0]); | 229 | } |
136 | 230 | ||
137 | cmd_ack = smu_save_ack_cmd(dev->cmd_buf); | ||
138 | 231 | ||
139 | /* Clear cmd_buf cache lines */ | 232 | /* |
140 | flush_inval_dcache_range((unsigned long)dev->cmd_buf, | 233 | * Queued command management. |
141 | ((unsigned long)dev->cmd_buf) + | 234 | * |
142 | sizeof(struct smu_cmd_buf)); | 235 | */ |
143 | smu_send_cmd(dev); | ||
144 | rc = smu_cmd_done(dev); | ||
145 | if (rc == 0) | ||
146 | rc = smu_cmd_stat(dev->cmd_buf, cmd_ack) ? 0 : -1; | ||
147 | 236 | ||
148 | DPRINTK("SMU do_cmd %02x len=%d %02x => %d (%02x)\n", | 237 | int smu_queue_cmd(struct smu_cmd *cmd) |
149 | dev->cmd_buf->cmd, dev->cmd_buf->length, | 238 | { |
150 | dev->cmd_buf->data[0], rc, cmd_ack); | 239 | unsigned long flags; |
151 | 240 | ||
152 | return rc; | 241 | if (smu == NULL) |
242 | return -ENODEV; | ||
243 | if (cmd->data_len > SMU_MAX_DATA || | ||
244 | cmd->reply_len > SMU_MAX_DATA) | ||
245 | return -EINVAL; | ||
246 | |||
247 | cmd->status = 1; | ||
248 | spin_lock_irqsave(&smu->lock, flags); | ||
249 | list_add_tail(&cmd->link, &smu->cmd_list); | ||
250 | if (smu->cmd_cur == NULL) | ||
251 | smu_start_cmd(); | ||
252 | spin_unlock_irqrestore(&smu->lock, flags); | ||
253 | |||
254 | return 0; | ||
153 | } | 255 | } |
256 | EXPORT_SYMBOL(smu_queue_cmd); | ||
154 | 257 | ||
155 | /* RTC low level commands */ | 258 | |
156 | static inline int bcd2hex (int n) | 259 | int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command, |
260 | unsigned int data_len, | ||
261 | void (*done)(struct smu_cmd *cmd, void *misc), | ||
262 | void *misc, ...) | ||
157 | { | 263 | { |
158 | return (((n & 0xf0) >> 4) * 10) + (n & 0xf); | 264 | struct smu_cmd *cmd = &scmd->cmd; |
265 | va_list list; | ||
266 | int i; | ||
267 | |||
268 | if (data_len > sizeof(scmd->buffer)) | ||
269 | return -EINVAL; | ||
270 | |||
271 | memset(scmd, 0, sizeof(*scmd)); | ||
272 | cmd->cmd = command; | ||
273 | cmd->data_len = data_len; | ||
274 | cmd->data_buf = scmd->buffer; | ||
275 | cmd->reply_len = sizeof(scmd->buffer); | ||
276 | cmd->reply_buf = scmd->buffer; | ||
277 | cmd->done = done; | ||
278 | cmd->misc = misc; | ||
279 | |||
280 | va_start(list, misc); | ||
281 | for (i = 0; i < data_len; ++i) | ||
282 | scmd->buffer[i] = (u8)va_arg(list, int); | ||
283 | va_end(list); | ||
284 | |||
285 | return smu_queue_cmd(cmd); | ||
159 | } | 286 | } |
287 | EXPORT_SYMBOL(smu_queue_simple); | ||
160 | 288 | ||
161 | static inline int hex2bcd (int n) | 289 | |
290 | void smu_poll(void) | ||
162 | { | 291 | { |
163 | return ((n / 10) << 4) + (n % 10); | 292 | u8 gpio; |
293 | |||
294 | if (smu == NULL) | ||
295 | return; | ||
296 | |||
297 | gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); | ||
298 | if ((gpio & 7) == 7) | ||
299 | smu_db_intr(smu->db_irq, smu, NULL); | ||
164 | } | 300 | } |
301 | EXPORT_SYMBOL(smu_poll); | ||
302 | |||
165 | 303 | ||
166 | #if 0 | 304 | void smu_done_complete(struct smu_cmd *cmd, void *misc) |
167 | static inline void smu_fill_set_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf) | ||
168 | { | 305 | { |
169 | cmd_buf->cmd = 0x8e; | 306 | struct completion *comp = misc; |
170 | cmd_buf->length = 8; | 307 | |
171 | cmd_buf->data[0] = 0x00; | 308 | complete(comp); |
172 | memset(cmd_buf->data + 1, 0, 7); | ||
173 | } | 309 | } |
310 | EXPORT_SYMBOL(smu_done_complete); | ||
311 | |||
174 | 312 | ||
175 | static inline void smu_fill_get_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf) | 313 | void smu_spinwait_cmd(struct smu_cmd *cmd) |
176 | { | 314 | { |
177 | cmd_buf->cmd = 0x8e; | 315 | while(cmd->status == 1) |
178 | cmd_buf->length = 1; | 316 | smu_poll(); |
179 | cmd_buf->data[0] = 0x01; | 317 | } |
318 | EXPORT_SYMBOL(smu_spinwait_cmd); | ||
319 | |||
320 | |||
321 | /* RTC low level commands */ | ||
322 | static inline int bcd2hex (int n) | ||
323 | { | ||
324 | return (((n & 0xf0) >> 4) * 10) + (n & 0xf); | ||
180 | } | 325 | } |
181 | 326 | ||
182 | static inline void smu_fill_dis_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf) | 327 | |
328 | static inline int hex2bcd (int n) | ||
183 | { | 329 | { |
184 | cmd_buf->cmd = 0x8e; | 330 | return ((n / 10) << 4) + (n % 10); |
185 | cmd_buf->length = 1; | ||
186 | cmd_buf->data[0] = 0x02; | ||
187 | } | 331 | } |
188 | #endif | 332 | |
189 | 333 | ||
190 | static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf, | 334 | static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf, |
191 | struct rtc_time *time) | 335 | struct rtc_time *time) |
@@ -202,100 +346,96 @@ static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf, | |||
202 | cmd_buf->data[7] = hex2bcd(time->tm_year - 100); | 346 | cmd_buf->data[7] = hex2bcd(time->tm_year - 100); |
203 | } | 347 | } |
204 | 348 | ||
205 | static inline void smu_fill_get_rtc_cmd(struct smu_cmd_buf *cmd_buf) | ||
206 | { | ||
207 | cmd_buf->cmd = 0x8e; | ||
208 | cmd_buf->length = 1; | ||
209 | cmd_buf->data[0] = 0x81; | ||
210 | } | ||
211 | 349 | ||
212 | static void smu_parse_get_rtc_reply(struct smu_cmd_buf *cmd_buf, | 350 | int smu_get_rtc_time(struct rtc_time *time, int spinwait) |
213 | struct rtc_time *time) | ||
214 | { | 351 | { |
215 | time->tm_sec = bcd2hex(cmd_buf->data[0]); | 352 | struct smu_simple_cmd cmd; |
216 | time->tm_min = bcd2hex(cmd_buf->data[1]); | ||
217 | time->tm_hour = bcd2hex(cmd_buf->data[2]); | ||
218 | time->tm_wday = bcd2hex(cmd_buf->data[3]); | ||
219 | time->tm_mday = bcd2hex(cmd_buf->data[4]); | ||
220 | time->tm_mon = bcd2hex(cmd_buf->data[5]) - 1; | ||
221 | time->tm_year = bcd2hex(cmd_buf->data[6]) + 100; | ||
222 | } | ||
223 | |||
224 | int smu_get_rtc_time(struct rtc_time *time) | ||
225 | { | ||
226 | unsigned long flags; | ||
227 | int rc; | 353 | int rc; |
228 | 354 | ||
229 | if (smu == NULL) | 355 | if (smu == NULL) |
230 | return -ENODEV; | 356 | return -ENODEV; |
231 | 357 | ||
232 | memset(time, 0, sizeof(struct rtc_time)); | 358 | memset(time, 0, sizeof(struct rtc_time)); |
233 | spin_lock_irqsave(&smu->lock, flags); | 359 | rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 1, NULL, NULL, |
234 | smu_fill_get_rtc_cmd(smu->cmd_buf); | 360 | SMU_CMD_RTC_GET_DATETIME); |
235 | rc = smu_do_cmd(smu); | 361 | if (rc) |
236 | if (rc == 0) | 362 | return rc; |
237 | smu_parse_get_rtc_reply(smu->cmd_buf, time); | 363 | smu_spinwait_simple(&cmd); |
238 | spin_unlock_irqrestore(&smu->lock, flags); | ||
239 | 364 | ||
240 | return rc; | 365 | time->tm_sec = bcd2hex(cmd.buffer[0]); |
366 | time->tm_min = bcd2hex(cmd.buffer[1]); | ||
367 | time->tm_hour = bcd2hex(cmd.buffer[2]); | ||
368 | time->tm_wday = bcd2hex(cmd.buffer[3]); | ||
369 | time->tm_mday = bcd2hex(cmd.buffer[4]); | ||
370 | time->tm_mon = bcd2hex(cmd.buffer[5]) - 1; | ||
371 | time->tm_year = bcd2hex(cmd.buffer[6]) + 100; | ||
372 | |||
373 | return 0; | ||
241 | } | 374 | } |
242 | 375 | ||
243 | int smu_set_rtc_time(struct rtc_time *time) | 376 | |
377 | int smu_set_rtc_time(struct rtc_time *time, int spinwait) | ||
244 | { | 378 | { |
245 | unsigned long flags; | 379 | struct smu_simple_cmd cmd; |
246 | int rc; | 380 | int rc; |
247 | 381 | ||
248 | if (smu == NULL) | 382 | if (smu == NULL) |
249 | return -ENODEV; | 383 | return -ENODEV; |
250 | 384 | ||
251 | spin_lock_irqsave(&smu->lock, flags); | 385 | rc = smu_queue_simple(&cmd, SMU_CMD_RTC_COMMAND, 8, NULL, NULL, |
252 | smu_fill_set_rtc_cmd(smu->cmd_buf, time); | 386 | SMU_CMD_RTC_SET_DATETIME, |
253 | rc = smu_do_cmd(smu); | 387 | hex2bcd(time->tm_sec), |
254 | spin_unlock_irqrestore(&smu->lock, flags); | 388 | hex2bcd(time->tm_min), |
389 | hex2bcd(time->tm_hour), | ||
390 | time->tm_wday, | ||
391 | hex2bcd(time->tm_mday), | ||
392 | hex2bcd(time->tm_mon) + 1, | ||
393 | hex2bcd(time->tm_year - 100)); | ||
394 | if (rc) | ||
395 | return rc; | ||
396 | smu_spinwait_simple(&cmd); | ||
255 | 397 | ||
256 | return rc; | 398 | return 0; |
257 | } | 399 | } |
258 | 400 | ||
401 | |||
259 | void smu_shutdown(void) | 402 | void smu_shutdown(void) |
260 | { | 403 | { |
261 | const unsigned char *command = "SHUTDOWN"; | 404 | struct smu_simple_cmd cmd; |
262 | unsigned long flags; | ||
263 | 405 | ||
264 | if (smu == NULL) | 406 | if (smu == NULL) |
265 | return; | 407 | return; |
266 | 408 | ||
267 | spin_lock_irqsave(&smu->lock, flags); | 409 | if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 9, NULL, NULL, |
268 | smu->cmd_buf->cmd = 0xaa; | 410 | 'S', 'H', 'U', 'T', 'D', 'O', 'W', 'N', 0)) |
269 | smu->cmd_buf->length = strlen(command); | 411 | return; |
270 | strcpy(smu->cmd_buf->data, command); | 412 | smu_spinwait_simple(&cmd); |
271 | smu_do_cmd(smu); | ||
272 | for (;;) | 413 | for (;;) |
273 | ; | 414 | ; |
274 | spin_unlock_irqrestore(&smu->lock, flags); | ||
275 | } | 415 | } |
276 | 416 | ||
417 | |||
277 | void smu_restart(void) | 418 | void smu_restart(void) |
278 | { | 419 | { |
279 | const unsigned char *command = "RESTART"; | 420 | struct smu_simple_cmd cmd; |
280 | unsigned long flags; | ||
281 | 421 | ||
282 | if (smu == NULL) | 422 | if (smu == NULL) |
283 | return; | 423 | return; |
284 | 424 | ||
285 | spin_lock_irqsave(&smu->lock, flags); | 425 | if (smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, NULL, NULL, |
286 | smu->cmd_buf->cmd = 0xaa; | 426 | 'R', 'E', 'S', 'T', 'A', 'R', 'T', 0)) |
287 | smu->cmd_buf->length = strlen(command); | 427 | return; |
288 | strcpy(smu->cmd_buf->data, command); | 428 | smu_spinwait_simple(&cmd); |
289 | smu_do_cmd(smu); | ||
290 | for (;;) | 429 | for (;;) |
291 | ; | 430 | ; |
292 | spin_unlock_irqrestore(&smu->lock, flags); | ||
293 | } | 431 | } |
294 | 432 | ||
433 | |||
295 | int smu_present(void) | 434 | int smu_present(void) |
296 | { | 435 | { |
297 | return smu != NULL; | 436 | return smu != NULL; |
298 | } | 437 | } |
438 | EXPORT_SYMBOL(smu_present); | ||
299 | 439 | ||
300 | 440 | ||
301 | int smu_init (void) | 441 | int smu_init (void) |
@@ -307,6 +447,8 @@ int smu_init (void) | |||
307 | if (np == NULL) | 447 | if (np == NULL) |
308 | return -ENODEV; | 448 | return -ENODEV; |
309 | 449 | ||
450 | printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); | ||
451 | |||
310 | if (smu_cmdbuf_abs == 0) { | 452 | if (smu_cmdbuf_abs == 0) { |
311 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); | 453 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
312 | return -EINVAL; | 454 | return -EINVAL; |
@@ -318,7 +460,13 @@ int smu_init (void) | |||
318 | memset(smu, 0, sizeof(*smu)); | 460 | memset(smu, 0, sizeof(*smu)); |
319 | 461 | ||
320 | spin_lock_init(&smu->lock); | 462 | spin_lock_init(&smu->lock); |
463 | INIT_LIST_HEAD(&smu->cmd_list); | ||
464 | INIT_LIST_HEAD(&smu->cmd_i2c_list); | ||
321 | smu->of_node = np; | 465 | smu->of_node = np; |
466 | smu->db_irq = NO_IRQ; | ||
467 | smu->msg_irq = NO_IRQ; | ||
468 | init_timer(&smu->i2c_timer); | ||
469 | |||
322 | /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a | 470 | /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a |
323 | * 32 bits value safely | 471 | * 32 bits value safely |
324 | */ | 472 | */ |
@@ -331,8 +479,8 @@ int smu_init (void) | |||
331 | goto fail; | 479 | goto fail; |
332 | } | 480 | } |
333 | data = (u32 *)get_property(np, "reg", NULL); | 481 | data = (u32 *)get_property(np, "reg", NULL); |
334 | of_node_put(np); | ||
335 | if (data == NULL) { | 482 | if (data == NULL) { |
483 | of_node_put(np); | ||
336 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); | 484 | printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); |
337 | goto fail; | 485 | goto fail; |
338 | } | 486 | } |
@@ -341,8 +489,31 @@ int smu_init (void) | |||
341 | * and ack. GPIOs are at 0x50, best would be to find that out | 489 | * and ack. GPIOs are at 0x50, best would be to find that out |
342 | * in the device-tree though. | 490 | * in the device-tree though. |
343 | */ | 491 | */ |
344 | smu->db_req = 0x50 + *data; | 492 | smu->doorbell = *data; |
345 | smu->db_ack = 0x50 + *data; | 493 | if (smu->doorbell < 0x50) |
494 | smu->doorbell += 0x50; | ||
495 | if (np->n_intrs > 0) | ||
496 | smu->db_irq = np->intrs[0].line; | ||
497 | |||
498 | of_node_put(np); | ||
499 | |||
500 | /* Now look for the smu-interrupt GPIO */ | ||
501 | do { | ||
502 | np = of_find_node_by_name(NULL, "smu-interrupt"); | ||
503 | if (np == NULL) | ||
504 | break; | ||
505 | data = (u32 *)get_property(np, "reg", NULL); | ||
506 | if (data == NULL) { | ||
507 | of_node_put(np); | ||
508 | break; | ||
509 | } | ||
510 | smu->msg = *data; | ||
511 | if (smu->msg < 0x50) | ||
512 | smu->msg += 0x50; | ||
513 | if (np->n_intrs > 0) | ||
514 | smu->msg_irq = np->intrs[0].line; | ||
515 | of_node_put(np); | ||
516 | } while(0); | ||
346 | 517 | ||
347 | /* Doorbell buffer is currently hard-coded, I didn't find a proper | 518 | /* Doorbell buffer is currently hard-coded, I didn't find a proper |
348 | * device-tree entry giving the address. Best would probably to use | 519 | * device-tree entry giving the address. Best would probably to use |
@@ -362,3 +533,584 @@ int smu_init (void) | |||
362 | return -ENXIO; | 533 | return -ENXIO; |
363 | 534 | ||
364 | } | 535 | } |
536 | |||
537 | |||
538 | static int smu_late_init(void) | ||
539 | { | ||
540 | if (!smu) | ||
541 | return 0; | ||
542 | |||
543 | /* | ||
544 | * Try to request the interrupts | ||
545 | */ | ||
546 | |||
547 | if (smu->db_irq != NO_IRQ) { | ||
548 | if (request_irq(smu->db_irq, smu_db_intr, | ||
549 | SA_SHIRQ, "SMU doorbell", smu) < 0) { | ||
550 | printk(KERN_WARNING "SMU: can't " | ||
551 | "request interrupt %d\n", | ||
552 | smu->db_irq); | ||
553 | smu->db_irq = NO_IRQ; | ||
554 | } | ||
555 | } | ||
556 | |||
557 | if (smu->msg_irq != NO_IRQ) { | ||
558 | if (request_irq(smu->msg_irq, smu_msg_intr, | ||
559 | SA_SHIRQ, "SMU message", smu) < 0) { | ||
560 | printk(KERN_WARNING "SMU: can't " | ||
561 | "request interrupt %d\n", | ||
562 | smu->msg_irq); | ||
563 | smu->msg_irq = NO_IRQ; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | arch_initcall(smu_late_init); | ||
570 | |||
571 | /* | ||
572 | * sysfs visibility | ||
573 | */ | ||
574 | |||
575 | static void smu_expose_childs(void *unused) | ||
576 | { | ||
577 | struct device_node *np; | ||
578 | |||
579 | for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) { | ||
580 | if (device_is_compatible(np, "smu-i2c")) { | ||
581 | char name[32]; | ||
582 | u32 *reg = (u32 *)get_property(np, "reg", NULL); | ||
583 | |||
584 | if (reg == NULL) | ||
585 | continue; | ||
586 | sprintf(name, "smu-i2c-%02x", *reg); | ||
587 | of_platform_device_create(np, name, &smu->of_dev->dev); | ||
588 | } | ||
589 | } | ||
590 | |||
591 | } | ||
592 | |||
593 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); | ||
594 | |||
595 | static int smu_platform_probe(struct of_device* dev, | ||
596 | const struct of_device_id *match) | ||
597 | { | ||
598 | if (!smu) | ||
599 | return -ENODEV; | ||
600 | smu->of_dev = dev; | ||
601 | |||
602 | /* | ||
603 | * Ok, we are matched, now expose all i2c busses. We have to defer | ||
604 | * that unfortunately or it would deadlock inside the device model | ||
605 | */ | ||
606 | schedule_work(&smu_expose_childs_work); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static struct of_device_id smu_platform_match[] = | ||
612 | { | ||
613 | { | ||
614 | .type = "smu", | ||
615 | }, | ||
616 | {}, | ||
617 | }; | ||
618 | |||
619 | static struct of_platform_driver smu_of_platform_driver = | ||
620 | { | ||
621 | .name = "smu", | ||
622 | .match_table = smu_platform_match, | ||
623 | .probe = smu_platform_probe, | ||
624 | }; | ||
625 | |||
626 | static int __init smu_init_sysfs(void) | ||
627 | { | ||
628 | int rc; | ||
629 | |||
630 | /* | ||
631 | * Due to sysfs bogosity, a sysdev is not a real device, so | ||
632 | * we should in fact create both if we want sysdev semantics | ||
633 | * for power management. | ||
634 | * For now, we don't power manage machines with an SMU chip, | ||
635 | * I'm a bit too far from figuring out how that works with those | ||
636 | * new chipsets, but that will come back and bite us | ||
637 | */ | ||
638 | rc = of_register_driver(&smu_of_platform_driver); | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | device_initcall(smu_init_sysfs); | ||
643 | |||
644 | struct of_device *smu_get_ofdev(void) | ||
645 | { | ||
646 | if (!smu) | ||
647 | return NULL; | ||
648 | return smu->of_dev; | ||
649 | } | ||
650 | |||
651 | EXPORT_SYMBOL_GPL(smu_get_ofdev); | ||
652 | |||
653 | /* | ||
654 | * i2c interface | ||
655 | */ | ||
656 | |||
657 | static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail) | ||
658 | { | ||
659 | void (*done)(struct smu_i2c_cmd *cmd, void *misc) = cmd->done; | ||
660 | void *misc = cmd->misc; | ||
661 | unsigned long flags; | ||
662 | |||
663 | /* Check for read case */ | ||
664 | if (!fail && cmd->read) { | ||
665 | if (cmd->pdata[0] < 1) | ||
666 | fail = 1; | ||
667 | else | ||
668 | memcpy(cmd->info.data, &cmd->pdata[1], | ||
669 | cmd->info.datalen); | ||
670 | } | ||
671 | |||
672 | DPRINTK("SMU: completing, success: %d\n", !fail); | ||
673 | |||
674 | /* Update status and mark no pending i2c command with lock | ||
675 | * held so nobody comes in while we dequeue an eventual | ||
676 | * pending next i2c command | ||
677 | */ | ||
678 | spin_lock_irqsave(&smu->lock, flags); | ||
679 | smu->cmd_i2c_cur = NULL; | ||
680 | wmb(); | ||
681 | cmd->status = fail ? -EIO : 0; | ||
682 | |||
683 | /* Is there another i2c command waiting ? */ | ||
684 | if (!list_empty(&smu->cmd_i2c_list)) { | ||
685 | struct smu_i2c_cmd *newcmd; | ||
686 | |||
687 | /* Fetch it, new current, remove from list */ | ||
688 | newcmd = list_entry(smu->cmd_i2c_list.next, | ||
689 | struct smu_i2c_cmd, link); | ||
690 | smu->cmd_i2c_cur = newcmd; | ||
691 | list_del(&cmd->link); | ||
692 | |||
693 | /* Queue with low level smu */ | ||
694 | list_add_tail(&cmd->scmd.link, &smu->cmd_list); | ||
695 | if (smu->cmd_cur == NULL) | ||
696 | smu_start_cmd(); | ||
697 | } | ||
698 | spin_unlock_irqrestore(&smu->lock, flags); | ||
699 | |||
700 | /* Call command completion handler if any */ | ||
701 | if (done) | ||
702 | done(cmd, misc); | ||
703 | |||
704 | } | ||
705 | |||
706 | |||
707 | static void smu_i2c_retry(unsigned long data) | ||
708 | { | ||
709 | struct smu_i2c_cmd *cmd = (struct smu_i2c_cmd *)data; | ||
710 | |||
711 | DPRINTK("SMU: i2c failure, requeuing...\n"); | ||
712 | |||
713 | /* requeue command simply by resetting reply_len */ | ||
714 | cmd->pdata[0] = 0xff; | ||
715 | cmd->scmd.reply_len = 0x10; | ||
716 | smu_queue_cmd(&cmd->scmd); | ||
717 | } | ||
718 | |||
719 | |||
720 | static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc) | ||
721 | { | ||
722 | struct smu_i2c_cmd *cmd = misc; | ||
723 | int fail = 0; | ||
724 | |||
725 | DPRINTK("SMU: i2c compl. stage=%d status=%x pdata[0]=%x rlen: %x\n", | ||
726 | cmd->stage, scmd->status, cmd->pdata[0], scmd->reply_len); | ||
727 | |||
728 | /* Check for possible status */ | ||
729 | if (scmd->status < 0) | ||
730 | fail = 1; | ||
731 | else if (cmd->read) { | ||
732 | if (cmd->stage == 0) | ||
733 | fail = cmd->pdata[0] != 0; | ||
734 | else | ||
735 | fail = cmd->pdata[0] >= 0x80; | ||
736 | } else { | ||
737 | fail = cmd->pdata[0] != 0; | ||
738 | } | ||
739 | |||
740 | /* Handle failures by requeuing command, after 5ms interval | ||
741 | */ | ||
742 | if (fail && --cmd->retries > 0) { | ||
743 | DPRINTK("SMU: i2c failure, starting timer...\n"); | ||
744 | smu->i2c_timer.function = smu_i2c_retry; | ||
745 | smu->i2c_timer.data = (unsigned long)cmd; | ||
746 | smu->i2c_timer.expires = jiffies + msecs_to_jiffies(5); | ||
747 | add_timer(&smu->i2c_timer); | ||
748 | return; | ||
749 | } | ||
750 | |||
751 | /* If failure or stage 1, command is complete */ | ||
752 | if (fail || cmd->stage != 0) { | ||
753 | smu_i2c_complete_command(cmd, fail); | ||
754 | return; | ||
755 | } | ||
756 | |||
757 | DPRINTK("SMU: going to stage 1\n"); | ||
758 | |||
759 | /* Ok, initial command complete, now poll status */ | ||
760 | scmd->reply_buf = cmd->pdata; | ||
761 | scmd->reply_len = 0x10; | ||
762 | scmd->data_buf = cmd->pdata; | ||
763 | scmd->data_len = 1; | ||
764 | cmd->pdata[0] = 0; | ||
765 | cmd->stage = 1; | ||
766 | cmd->retries = 20; | ||
767 | smu_queue_cmd(scmd); | ||
768 | } | ||
769 | |||
770 | |||
771 | int smu_queue_i2c(struct smu_i2c_cmd *cmd) | ||
772 | { | ||
773 | unsigned long flags; | ||
774 | |||
775 | if (smu == NULL) | ||
776 | return -ENODEV; | ||
777 | |||
778 | /* Fill most fields of scmd */ | ||
779 | cmd->scmd.cmd = SMU_CMD_I2C_COMMAND; | ||
780 | cmd->scmd.done = smu_i2c_low_completion; | ||
781 | cmd->scmd.misc = cmd; | ||
782 | cmd->scmd.reply_buf = cmd->pdata; | ||
783 | cmd->scmd.reply_len = 0x10; | ||
784 | cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; | ||
785 | cmd->scmd.status = 1; | ||
786 | cmd->stage = 0; | ||
787 | cmd->pdata[0] = 0xff; | ||
788 | cmd->retries = 20; | ||
789 | cmd->status = 1; | ||
790 | |||
791 | /* Check transfer type, sanitize some "info" fields | ||
792 | * based on transfer type and do more checking | ||
793 | */ | ||
794 | cmd->info.caddr = cmd->info.devaddr; | ||
795 | cmd->read = cmd->info.devaddr & 0x01; | ||
796 | switch(cmd->info.type) { | ||
797 | case SMU_I2C_TRANSFER_SIMPLE: | ||
798 | memset(&cmd->info.sublen, 0, 4); | ||
799 | break; | ||
800 | case SMU_I2C_TRANSFER_COMBINED: | ||
801 | cmd->info.devaddr &= 0xfe; | ||
802 | case SMU_I2C_TRANSFER_STDSUB: | ||
803 | if (cmd->info.sublen > 3) | ||
804 | return -EINVAL; | ||
805 | break; | ||
806 | default: | ||
807 | return -EINVAL; | ||
808 | } | ||
809 | |||
810 | /* Finish setting up command based on transfer direction | ||
811 | */ | ||
812 | if (cmd->read) { | ||
813 | if (cmd->info.datalen > SMU_I2C_READ_MAX) | ||
814 | return -EINVAL; | ||
815 | memset(cmd->info.data, 0xff, cmd->info.datalen); | ||
816 | cmd->scmd.data_len = 9; | ||
817 | } else { | ||
818 | if (cmd->info.datalen > SMU_I2C_WRITE_MAX) | ||
819 | return -EINVAL; | ||
820 | cmd->scmd.data_len = 9 + cmd->info.datalen; | ||
821 | } | ||
822 | |||
823 | DPRINTK("SMU: i2c enqueuing command\n"); | ||
824 | DPRINTK("SMU: %s, len=%d bus=%x addr=%x sub0=%x type=%x\n", | ||
825 | cmd->read ? "read" : "write", cmd->info.datalen, | ||
826 | cmd->info.bus, cmd->info.caddr, | ||
827 | cmd->info.subaddr[0], cmd->info.type); | ||
828 | |||
829 | |||
830 | /* Enqueue command in i2c list, and if empty, enqueue also in | ||
831 | * main command list | ||
832 | */ | ||
833 | spin_lock_irqsave(&smu->lock, flags); | ||
834 | if (smu->cmd_i2c_cur == NULL) { | ||
835 | smu->cmd_i2c_cur = cmd; | ||
836 | list_add_tail(&cmd->scmd.link, &smu->cmd_list); | ||
837 | if (smu->cmd_cur == NULL) | ||
838 | smu_start_cmd(); | ||
839 | } else | ||
840 | list_add_tail(&cmd->link, &smu->cmd_i2c_list); | ||
841 | spin_unlock_irqrestore(&smu->lock, flags); | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | |||
847 | |||
848 | /* | ||
849 | * Userland driver interface | ||
850 | */ | ||
851 | |||
852 | |||
853 | static LIST_HEAD(smu_clist); | ||
854 | static DEFINE_SPINLOCK(smu_clist_lock); | ||
855 | |||
856 | enum smu_file_mode { | ||
857 | smu_file_commands, | ||
858 | smu_file_events, | ||
859 | smu_file_closing | ||
860 | }; | ||
861 | |||
862 | struct smu_private | ||
863 | { | ||
864 | struct list_head list; | ||
865 | enum smu_file_mode mode; | ||
866 | int busy; | ||
867 | struct smu_cmd cmd; | ||
868 | spinlock_t lock; | ||
869 | wait_queue_head_t wait; | ||
870 | u8 buffer[SMU_MAX_DATA]; | ||
871 | }; | ||
872 | |||
873 | |||
874 | static int smu_open(struct inode *inode, struct file *file) | ||
875 | { | ||
876 | struct smu_private *pp; | ||
877 | unsigned long flags; | ||
878 | |||
879 | pp = kmalloc(sizeof(struct smu_private), GFP_KERNEL); | ||
880 | if (pp == 0) | ||
881 | return -ENOMEM; | ||
882 | memset(pp, 0, sizeof(struct smu_private)); | ||
883 | spin_lock_init(&pp->lock); | ||
884 | pp->mode = smu_file_commands; | ||
885 | init_waitqueue_head(&pp->wait); | ||
886 | |||
887 | spin_lock_irqsave(&smu_clist_lock, flags); | ||
888 | list_add(&pp->list, &smu_clist); | ||
889 | spin_unlock_irqrestore(&smu_clist_lock, flags); | ||
890 | file->private_data = pp; | ||
891 | |||
892 | return 0; | ||
893 | } | ||
894 | |||
895 | |||
896 | static void smu_user_cmd_done(struct smu_cmd *cmd, void *misc) | ||
897 | { | ||
898 | struct smu_private *pp = misc; | ||
899 | |||
900 | wake_up_all(&pp->wait); | ||
901 | } | ||
902 | |||
903 | |||
904 | static ssize_t smu_write(struct file *file, const char __user *buf, | ||
905 | size_t count, loff_t *ppos) | ||
906 | { | ||
907 | struct smu_private *pp = file->private_data; | ||
908 | unsigned long flags; | ||
909 | struct smu_user_cmd_hdr hdr; | ||
910 | int rc = 0; | ||
911 | |||
912 | if (pp->busy) | ||
913 | return -EBUSY; | ||
914 | else if (copy_from_user(&hdr, buf, sizeof(hdr))) | ||
915 | return -EFAULT; | ||
916 | else if (hdr.cmdtype == SMU_CMDTYPE_WANTS_EVENTS) { | ||
917 | pp->mode = smu_file_events; | ||
918 | return 0; | ||
919 | } else if (hdr.cmdtype != SMU_CMDTYPE_SMU) | ||
920 | return -EINVAL; | ||
921 | else if (pp->mode != smu_file_commands) | ||
922 | return -EBADFD; | ||
923 | else if (hdr.data_len > SMU_MAX_DATA) | ||
924 | return -EINVAL; | ||
925 | |||
926 | spin_lock_irqsave(&pp->lock, flags); | ||
927 | if (pp->busy) { | ||
928 | spin_unlock_irqrestore(&pp->lock, flags); | ||
929 | return -EBUSY; | ||
930 | } | ||
931 | pp->busy = 1; | ||
932 | pp->cmd.status = 1; | ||
933 | spin_unlock_irqrestore(&pp->lock, flags); | ||
934 | |||
935 | if (copy_from_user(pp->buffer, buf + sizeof(hdr), hdr.data_len)) { | ||
936 | pp->busy = 0; | ||
937 | return -EFAULT; | ||
938 | } | ||
939 | |||
940 | pp->cmd.cmd = hdr.cmd; | ||
941 | pp->cmd.data_len = hdr.data_len; | ||
942 | pp->cmd.reply_len = SMU_MAX_DATA; | ||
943 | pp->cmd.data_buf = pp->buffer; | ||
944 | pp->cmd.reply_buf = pp->buffer; | ||
945 | pp->cmd.done = smu_user_cmd_done; | ||
946 | pp->cmd.misc = pp; | ||
947 | rc = smu_queue_cmd(&pp->cmd); | ||
948 | if (rc < 0) | ||
949 | return rc; | ||
950 | return count; | ||
951 | } | ||
952 | |||
953 | |||
954 | static ssize_t smu_read_command(struct file *file, struct smu_private *pp, | ||
955 | char __user *buf, size_t count) | ||
956 | { | ||
957 | DECLARE_WAITQUEUE(wait, current); | ||
958 | struct smu_user_reply_hdr hdr; | ||
959 | unsigned long flags; | ||
960 | int size, rc = 0; | ||
961 | |||
962 | if (!pp->busy) | ||
963 | return 0; | ||
964 | if (count < sizeof(struct smu_user_reply_hdr)) | ||
965 | return -EOVERFLOW; | ||
966 | spin_lock_irqsave(&pp->lock, flags); | ||
967 | if (pp->cmd.status == 1) { | ||
968 | if (file->f_flags & O_NONBLOCK) | ||
969 | return -EAGAIN; | ||
970 | add_wait_queue(&pp->wait, &wait); | ||
971 | for (;;) { | ||
972 | set_current_state(TASK_INTERRUPTIBLE); | ||
973 | rc = 0; | ||
974 | if (pp->cmd.status != 1) | ||
975 | break; | ||
976 | rc = -ERESTARTSYS; | ||
977 | if (signal_pending(current)) | ||
978 | break; | ||
979 | spin_unlock_irqrestore(&pp->lock, flags); | ||
980 | schedule(); | ||
981 | spin_lock_irqsave(&pp->lock, flags); | ||
982 | } | ||
983 | set_current_state(TASK_RUNNING); | ||
984 | remove_wait_queue(&pp->wait, &wait); | ||
985 | } | ||
986 | spin_unlock_irqrestore(&pp->lock, flags); | ||
987 | if (rc) | ||
988 | return rc; | ||
989 | if (pp->cmd.status != 0) | ||
990 | pp->cmd.reply_len = 0; | ||
991 | size = sizeof(hdr) + pp->cmd.reply_len; | ||
992 | if (count < size) | ||
993 | size = count; | ||
994 | rc = size; | ||
995 | hdr.status = pp->cmd.status; | ||
996 | hdr.reply_len = pp->cmd.reply_len; | ||
997 | if (copy_to_user(buf, &hdr, sizeof(hdr))) | ||
998 | return -EFAULT; | ||
999 | size -= sizeof(hdr); | ||
1000 | if (size && copy_to_user(buf + sizeof(hdr), pp->buffer, size)) | ||
1001 | return -EFAULT; | ||
1002 | pp->busy = 0; | ||
1003 | |||
1004 | return rc; | ||
1005 | } | ||
1006 | |||
1007 | |||
1008 | static ssize_t smu_read_events(struct file *file, struct smu_private *pp, | ||
1009 | char __user *buf, size_t count) | ||
1010 | { | ||
1011 | /* Not implemented */ | ||
1012 | msleep_interruptible(1000); | ||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | static ssize_t smu_read(struct file *file, char __user *buf, | ||
1018 | size_t count, loff_t *ppos) | ||
1019 | { | ||
1020 | struct smu_private *pp = file->private_data; | ||
1021 | |||
1022 | if (pp->mode == smu_file_commands) | ||
1023 | return smu_read_command(file, pp, buf, count); | ||
1024 | if (pp->mode == smu_file_events) | ||
1025 | return smu_read_events(file, pp, buf, count); | ||
1026 | |||
1027 | return -EBADFD; | ||
1028 | } | ||
1029 | |||
1030 | static unsigned int smu_fpoll(struct file *file, poll_table *wait) | ||
1031 | { | ||
1032 | struct smu_private *pp = file->private_data; | ||
1033 | unsigned int mask = 0; | ||
1034 | unsigned long flags; | ||
1035 | |||
1036 | if (pp == 0) | ||
1037 | return 0; | ||
1038 | |||
1039 | if (pp->mode == smu_file_commands) { | ||
1040 | poll_wait(file, &pp->wait, wait); | ||
1041 | |||
1042 | spin_lock_irqsave(&pp->lock, flags); | ||
1043 | if (pp->busy && pp->cmd.status != 1) | ||
1044 | mask |= POLLIN; | ||
1045 | spin_unlock_irqrestore(&pp->lock, flags); | ||
1046 | } if (pp->mode == smu_file_events) { | ||
1047 | /* Not yet implemented */ | ||
1048 | } | ||
1049 | return mask; | ||
1050 | } | ||
1051 | |||
1052 | static int smu_release(struct inode *inode, struct file *file) | ||
1053 | { | ||
1054 | struct smu_private *pp = file->private_data; | ||
1055 | unsigned long flags; | ||
1056 | unsigned int busy; | ||
1057 | |||
1058 | if (pp == 0) | ||
1059 | return 0; | ||
1060 | |||
1061 | file->private_data = NULL; | ||
1062 | |||
1063 | /* Mark file as closing to avoid races with new request */ | ||
1064 | spin_lock_irqsave(&pp->lock, flags); | ||
1065 | pp->mode = smu_file_closing; | ||
1066 | busy = pp->busy; | ||
1067 | |||
1068 | /* Wait for any pending request to complete */ | ||
1069 | if (busy && pp->cmd.status == 1) { | ||
1070 | DECLARE_WAITQUEUE(wait, current); | ||
1071 | |||
1072 | add_wait_queue(&pp->wait, &wait); | ||
1073 | for (;;) { | ||
1074 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1075 | if (pp->cmd.status != 1) | ||
1076 | break; | ||
1077 | spin_lock_irqsave(&pp->lock, flags); | ||
1078 | schedule(); | ||
1079 | spin_unlock_irqrestore(&pp->lock, flags); | ||
1080 | } | ||
1081 | set_current_state(TASK_RUNNING); | ||
1082 | remove_wait_queue(&pp->wait, &wait); | ||
1083 | } | ||
1084 | spin_unlock_irqrestore(&pp->lock, flags); | ||
1085 | |||
1086 | spin_lock_irqsave(&smu_clist_lock, flags); | ||
1087 | list_del(&pp->list); | ||
1088 | spin_unlock_irqrestore(&smu_clist_lock, flags); | ||
1089 | kfree(pp); | ||
1090 | |||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | |||
1095 | static struct file_operations smu_device_fops __pmacdata = { | ||
1096 | .llseek = no_llseek, | ||
1097 | .read = smu_read, | ||
1098 | .write = smu_write, | ||
1099 | .poll = smu_fpoll, | ||
1100 | .open = smu_open, | ||
1101 | .release = smu_release, | ||
1102 | }; | ||
1103 | |||
1104 | static struct miscdevice pmu_device __pmacdata = { | ||
1105 | MISC_DYNAMIC_MINOR, "smu", &smu_device_fops | ||
1106 | }; | ||
1107 | |||
1108 | static int smu_device_init(void) | ||
1109 | { | ||
1110 | if (!smu) | ||
1111 | return -ENODEV; | ||
1112 | if (misc_register(&pmu_device) < 0) | ||
1113 | printk(KERN_ERR "via-pmu: cannot register misc device.\n"); | ||
1114 | return 0; | ||
1115 | } | ||
1116 | device_initcall(smu_device_init); | ||
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index c9ca1118e449..f38696622eb4 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -599,7 +599,7 @@ thermostat_init(void) | |||
599 | sensor_location[2] = "?"; | 599 | sensor_location[2] = "?"; |
600 | } | 600 | } |
601 | 601 | ||
602 | of_dev = of_platform_device_create(np, "temperatures"); | 602 | of_dev = of_platform_device_create(np, "temperatures", NULL); |
603 | 603 | ||
604 | if (of_dev == NULL) { | 604 | if (of_dev == NULL) { |
605 | printk(KERN_ERR "Can't register temperatures device !\n"); | 605 | printk(KERN_ERR "Can't register temperatures device !\n"); |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 703e31973314..cc507ceef153 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -2051,7 +2051,7 @@ static int __init therm_pm72_init(void) | |||
2051 | return -ENODEV; | 2051 | return -ENODEV; |
2052 | } | 2052 | } |
2053 | } | 2053 | } |
2054 | of_dev = of_platform_device_create(np, "temperature"); | 2054 | of_dev = of_platform_device_create(np, "temperature", NULL); |
2055 | if (of_dev == NULL) { | 2055 | if (of_dev == NULL) { |
2056 | printk(KERN_ERR "Can't register FCU platform device !\n"); | 2056 | printk(KERN_ERR "Can't register FCU platform device !\n"); |
2057 | return -ENODEV; | 2057 | return -ENODEV; |
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index cbb72eb0426d..6aaa1df1a64e 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -504,7 +504,7 @@ g4fan_init( void ) | |||
504 | } | 504 | } |
505 | if( !(np=of_find_node_by_name(NULL, "fan")) ) | 505 | if( !(np=of_find_node_by_name(NULL, "fan")) ) |
506 | return -ENODEV; | 506 | return -ENODEV; |
507 | x.of_dev = of_platform_device_create( np, "temperature" ); | 507 | x.of_dev = of_platform_device_create(np, "temperature", NULL); |
508 | of_node_put( np ); | 508 | of_node_put( np ); |
509 | 509 | ||
510 | if( !x.of_dev ) { | 510 | if( !x.of_dev ) { |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index a564321db2f0..c062a017491e 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -763,21 +763,21 @@ static void set_pll(struct bttv *btv) | |||
763 | /* no PLL needed */ | 763 | /* no PLL needed */ |
764 | if (btv->pll.pll_current == 0) | 764 | if (btv->pll.pll_current == 0) |
765 | return; | 765 | return; |
766 | vprintk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n", | 766 | bttv_printk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n", |
767 | btv->c.nr,btv->pll.pll_ifreq); | 767 | btv->c.nr,btv->pll.pll_ifreq); |
768 | btwrite(0x00,BT848_TGCTRL); | 768 | btwrite(0x00,BT848_TGCTRL); |
769 | btwrite(0x00,BT848_PLL_XCI); | 769 | btwrite(0x00,BT848_PLL_XCI); |
770 | btv->pll.pll_current = 0; | 770 | btv->pll.pll_current = 0; |
771 | return; | 771 | return; |
772 | } | 772 | } |
773 | 773 | ||
774 | vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr, | 774 | bttv_printk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr, |
775 | btv->pll.pll_ifreq, btv->pll.pll_ofreq); | 775 | btv->pll.pll_ifreq, btv->pll.pll_ofreq); |
776 | set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq); | 776 | set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq); |
777 | 777 | ||
778 | for (i=0; i<10; i++) { | 778 | for (i=0; i<10; i++) { |
779 | /* Let other people run while the PLL stabilizes */ | 779 | /* Let other people run while the PLL stabilizes */ |
780 | vprintk("."); | 780 | bttv_printk("."); |
781 | msleep(10); | 781 | msleep(10); |
782 | 782 | ||
783 | if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) { | 783 | if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) { |
@@ -785,12 +785,12 @@ static void set_pll(struct bttv *btv) | |||
785 | } else { | 785 | } else { |
786 | btwrite(0x08,BT848_TGCTRL); | 786 | btwrite(0x08,BT848_TGCTRL); |
787 | btv->pll.pll_current = btv->pll.pll_ofreq; | 787 | btv->pll.pll_current = btv->pll.pll_ofreq; |
788 | vprintk(" ok\n"); | 788 | bttv_printk(" ok\n"); |
789 | return; | 789 | return; |
790 | } | 790 | } |
791 | } | 791 | } |
792 | btv->pll.pll_current = -1; | 792 | btv->pll.pll_current = -1; |
793 | vprintk("failed\n"); | 793 | bttv_printk("failed\n"); |
794 | return; | 794 | return; |
795 | } | 795 | } |
796 | 796 | ||
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 9b0b7ca035f8..7a312f79340a 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h | |||
@@ -221,7 +221,7 @@ extern void bttv_gpio_tracking(struct bttv *btv, char *comment); | |||
221 | extern int init_bttv_i2c(struct bttv *btv); | 221 | extern int init_bttv_i2c(struct bttv *btv); |
222 | extern int fini_bttv_i2c(struct bttv *btv); | 222 | extern int fini_bttv_i2c(struct bttv *btv); |
223 | 223 | ||
224 | #define vprintk if (bttv_verbose) printk | 224 | #define bttv_printk if (bttv_verbose) printk |
225 | #define dprintk if (bttv_debug >= 1) printk | 225 | #define dprintk if (bttv_debug >= 1) printk |
226 | #define d2printk if (bttv_debug >= 2) printk | 226 | #define d2printk if (bttv_debug >= 2) printk |
227 | 227 | ||
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c index 9a087c1fb0b7..24f670b5a4f3 100644 --- a/drivers/mtd/devices/docecc.c +++ b/drivers/mtd/devices/docecc.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <linux/mtd/mtd.h> | 40 | #include <linux/mtd/mtd.h> |
41 | #include <linux/mtd/doc2000.h> | 41 | #include <linux/mtd/doc2000.h> |
42 | 42 | ||
43 | #define DEBUG 0 | 43 | #define DEBUG_ECC 0 |
44 | /* need to undef it (from asm/termbits.h) */ | 44 | /* need to undef it (from asm/termbits.h) */ |
45 | #undef B0 | 45 | #undef B0 |
46 | 46 | ||
@@ -249,7 +249,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1], | |||
249 | lambda[j] ^= Alpha_to[modnn(u + tmp)]; | 249 | lambda[j] ^= Alpha_to[modnn(u + tmp)]; |
250 | } | 250 | } |
251 | } | 251 | } |
252 | #if DEBUG >= 1 | 252 | #if DEBUG_ECC >= 1 |
253 | /* Test code that verifies the erasure locator polynomial just constructed | 253 | /* Test code that verifies the erasure locator polynomial just constructed |
254 | Needed only for decoder debugging. */ | 254 | Needed only for decoder debugging. */ |
255 | 255 | ||
@@ -276,7 +276,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1], | |||
276 | count = -1; | 276 | count = -1; |
277 | goto finish; | 277 | goto finish; |
278 | } | 278 | } |
279 | #if DEBUG >= 2 | 279 | #if DEBUG_ECC >= 2 |
280 | printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); | 280 | printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); |
281 | for (i = 0; i < count; i++) | 281 | for (i = 0; i < count; i++) |
282 | printf("%d ", loc[i]); | 282 | printf("%d ", loc[i]); |
@@ -409,7 +409,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1], | |||
409 | den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])]; | 409 | den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])]; |
410 | } | 410 | } |
411 | if (den == 0) { | 411 | if (den == 0) { |
412 | #if DEBUG >= 1 | 412 | #if DEBUG_ECC >= 1 |
413 | printf("\n ERROR: denominator = 0\n"); | 413 | printf("\n ERROR: denominator = 0\n"); |
414 | #endif | 414 | #endif |
415 | /* Convert to dual- basis */ | 415 | /* Convert to dual- basis */ |
diff --git a/drivers/net/8390.c b/drivers/net/8390.c index 6d76f3a99b17..f87027420081 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c | |||
@@ -1094,7 +1094,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, | |||
1094 | 1094 | ||
1095 | outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); | 1095 | outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); |
1096 | 1096 | ||
1097 | if (inb_p(e8390_base) & E8390_TRANS) | 1097 | if (inb_p(e8390_base + E8390_CMD) & E8390_TRANS) |
1098 | { | 1098 | { |
1099 | printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n", | 1099 | printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n", |
1100 | dev->name); | 1100 | dev->name); |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index ae1996a3bc5c..fd398da4993b 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -1643,6 +1643,22 @@ static void yukon_reset(struct skge_hw *hw, int port) | |||
1643 | | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); | 1643 | | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); |
1644 | } | 1644 | } |
1645 | 1645 | ||
1646 | /* Apparently, early versions of Yukon-Lite had wrong chip_id? */ | ||
1647 | static int is_yukon_lite_a0(struct skge_hw *hw) | ||
1648 | { | ||
1649 | u32 reg; | ||
1650 | int ret; | ||
1651 | |||
1652 | if (hw->chip_id != CHIP_ID_YUKON) | ||
1653 | return 0; | ||
1654 | |||
1655 | reg = skge_read32(hw, B2_FAR); | ||
1656 | skge_write8(hw, B2_FAR + 3, 0xff); | ||
1657 | ret = (skge_read8(hw, B2_FAR + 3) != 0); | ||
1658 | skge_write32(hw, B2_FAR, reg); | ||
1659 | return ret; | ||
1660 | } | ||
1661 | |||
1646 | static void yukon_mac_init(struct skge_hw *hw, int port) | 1662 | static void yukon_mac_init(struct skge_hw *hw, int port) |
1647 | { | 1663 | { |
1648 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1664 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
@@ -1758,9 +1774,11 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1758 | /* Configure Rx MAC FIFO */ | 1774 | /* Configure Rx MAC FIFO */ |
1759 | skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); | 1775 | skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); |
1760 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; | 1776 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
1761 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1777 | |
1762 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) | 1778 | /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */ |
1779 | if (is_yukon_lite_a0(hw)) | ||
1763 | reg &= ~GMF_RX_F_FL_ON; | 1780 | reg &= ~GMF_RX_F_FL_ON; |
1781 | |||
1764 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 1782 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
1765 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); | 1783 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); |
1766 | /* | 1784 | /* |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c77d5b1bbff6..005786416bb5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -402,6 +402,12 @@ static void pci_enable_crs(struct pci_dev *dev) | |||
402 | static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) | 402 | static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) |
403 | { | 403 | { |
404 | struct pci_bus *parent = child->parent; | 404 | struct pci_bus *parent = child->parent; |
405 | |||
406 | /* Attempts to fix that up are really dangerous unless | ||
407 | we're going to re-assign all bus numbers. */ | ||
408 | if (!pcibios_assign_all_busses()) | ||
409 | return; | ||
410 | |||
405 | while (parent->parent && parent->subordinate < max) { | 411 | while (parent->parent && parent->subordinate < max) { |
406 | parent->subordinate = max; | 412 | parent->subordinate = max; |
407 | pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); | 413 | pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); |
@@ -478,8 +484,18 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
478 | * We need to assign a number to this bus which we always | 484 | * We need to assign a number to this bus which we always |
479 | * do in the second pass. | 485 | * do in the second pass. |
480 | */ | 486 | */ |
481 | if (!pass) | 487 | if (!pass) { |
488 | if (pcibios_assign_all_busses()) | ||
489 | /* Temporarily disable forwarding of the | ||
490 | configuration cycles on all bridges in | ||
491 | this bus segment to avoid possible | ||
492 | conflicts in the second pass between two | ||
493 | bridges programmed with overlapping | ||
494 | bus ranges. */ | ||
495 | pci_write_config_dword(dev, PCI_PRIMARY_BUS, | ||
496 | buses & ~0xffffff); | ||
482 | return max; | 497 | return max; |
498 | } | ||
483 | 499 | ||
484 | /* Clear errors */ | 500 | /* Clear errors */ |
485 | pci_write_config_word(dev, PCI_STATUS, 0xffff); | 501 | pci_write_config_word(dev, PCI_STATUS, 0xffff); |
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index a4857db4f9b8..b235556b7b65 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c | |||
@@ -1959,22 +1959,35 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match) | |||
1959 | /* Set it up */ | 1959 | /* Set it up */ |
1960 | mesh_init(ms); | 1960 | mesh_init(ms); |
1961 | 1961 | ||
1962 | /* XXX FIXME: error should be fatal */ | 1962 | /* Request interrupt */ |
1963 | if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) | 1963 | if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) { |
1964 | printk(KERN_ERR "MESH: can't get irq %d\n", ms->meshintr); | 1964 | printk(KERN_ERR "MESH: can't get irq %d\n", ms->meshintr); |
1965 | goto out_shutdown; | ||
1966 | } | ||
1965 | 1967 | ||
1966 | /* XXX FIXME: handle failure */ | 1968 | /* Add scsi host & scan */ |
1967 | scsi_add_host(mesh_host, &mdev->ofdev.dev); | 1969 | if (scsi_add_host(mesh_host, &mdev->ofdev.dev)) |
1970 | goto out_release_irq; | ||
1968 | scsi_scan_host(mesh_host); | 1971 | scsi_scan_host(mesh_host); |
1969 | 1972 | ||
1970 | return 0; | 1973 | return 0; |
1971 | 1974 | ||
1972 | out_unmap: | 1975 | out_release_irq: |
1976 | free_irq(ms->meshintr, ms); | ||
1977 | out_shutdown: | ||
1978 | /* shutdown & reset bus in case of error or macos can be confused | ||
1979 | * at reboot if the bus was set to synchronous mode already | ||
1980 | */ | ||
1981 | mesh_shutdown(mdev); | ||
1982 | set_mesh_power(ms, 0); | ||
1983 | pci_free_consistent(macio_get_pci_dev(mdev), ms->dma_cmd_size, | ||
1984 | ms->dma_cmd_space, ms->dma_cmd_bus); | ||
1985 | out_unmap: | ||
1973 | iounmap(ms->dma); | 1986 | iounmap(ms->dma); |
1974 | iounmap(ms->mesh); | 1987 | iounmap(ms->mesh); |
1975 | out_free: | 1988 | out_free: |
1976 | scsi_host_put(mesh_host); | 1989 | scsi_host_put(mesh_host); |
1977 | out_release: | 1990 | out_release: |
1978 | macio_release_resources(mdev); | 1991 | macio_release_resources(mdev); |
1979 | 1992 | ||
1980 | return -ENODEV; | 1993 | return -ENODEV; |
@@ -2001,7 +2014,7 @@ static int mesh_remove(struct macio_dev *mdev) | |||
2001 | 2014 | ||
2002 | /* Free DMA commands memory */ | 2015 | /* Free DMA commands memory */ |
2003 | pci_free_consistent(macio_get_pci_dev(mdev), ms->dma_cmd_size, | 2016 | pci_free_consistent(macio_get_pci_dev(mdev), ms->dma_cmd_size, |
2004 | ms->dma_cmd_space, ms->dma_cmd_bus); | 2017 | ms->dma_cmd_space, ms->dma_cmd_bus); |
2005 | 2018 | ||
2006 | /* Release memory resources */ | 2019 | /* Release memory resources */ |
2007 | macio_release_resources(mdev); | 2020 | macio_release_resources(mdev); |
diff --git a/drivers/video/aty/xlinit.c b/drivers/video/aty/xlinit.c index 0bea0d8d7821..a085cbf74ecb 100644 --- a/drivers/video/aty/xlinit.c +++ b/drivers/video/aty/xlinit.c | |||
@@ -253,9 +253,11 @@ int atyfb_xl_init(struct fb_info *info) | |||
253 | aty_st_le32(0xFC, 0x00000000, par); | 253 | aty_st_le32(0xFC, 0x00000000, par); |
254 | 254 | ||
255 | #if defined (CONFIG_FB_ATY_GENERIC_LCD) | 255 | #if defined (CONFIG_FB_ATY_GENERIC_LCD) |
256 | int i; | 256 | { |
257 | for (i=0; i<sizeof(lcd_tbl)/sizeof(lcd_tbl_t); i++) { | 257 | int i; |
258 | aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par); | 258 | |
259 | for (i = 0; i < ARRAY_SIZE(lcd_tbl); i++) | ||
260 | aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par); | ||
259 | } | 261 | } |
260 | #endif | 262 | #endif |
261 | 263 | ||
diff --git a/fs/9p/conv.c b/fs/9p/conv.c index 1554731bd653..18121af99d3e 100644 --- a/fs/9p/conv.c +++ b/fs/9p/conv.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * 9P protocol conversion functions | 4 | * 9P protocol conversion functions |
5 | * | 5 | * |
6 | * Copyright (C) 2004, 2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
6 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> |
7 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> |
8 | * | 9 | * |
@@ -55,66 +56,70 @@ static inline int buf_check_overflow(struct cbuf *buf) | |||
55 | return buf->p > buf->ep; | 56 | return buf->p > buf->ep; |
56 | } | 57 | } |
57 | 58 | ||
58 | static inline void buf_check_size(struct cbuf *buf, int len) | 59 | static inline int buf_check_size(struct cbuf *buf, int len) |
59 | { | 60 | { |
60 | if (buf->p+len > buf->ep) { | 61 | if (buf->p+len > buf->ep) { |
61 | if (buf->p < buf->ep) { | 62 | if (buf->p < buf->ep) { |
62 | eprintk(KERN_ERR, "buffer overflow\n"); | 63 | eprintk(KERN_ERR, "buffer overflow\n"); |
63 | buf->p = buf->ep + 1; | 64 | buf->p = buf->ep + 1; |
65 | return 0; | ||
64 | } | 66 | } |
65 | } | 67 | } |
68 | |||
69 | return 1; | ||
66 | } | 70 | } |
67 | 71 | ||
68 | static inline void *buf_alloc(struct cbuf *buf, int len) | 72 | static inline void *buf_alloc(struct cbuf *buf, int len) |
69 | { | 73 | { |
70 | void *ret = NULL; | 74 | void *ret = NULL; |
71 | 75 | ||
72 | buf_check_size(buf, len); | 76 | if (buf_check_size(buf, len)) { |
73 | ret = buf->p; | 77 | ret = buf->p; |
74 | buf->p += len; | 78 | buf->p += len; |
79 | } | ||
75 | 80 | ||
76 | return ret; | 81 | return ret; |
77 | } | 82 | } |
78 | 83 | ||
79 | static inline void buf_put_int8(struct cbuf *buf, u8 val) | 84 | static inline void buf_put_int8(struct cbuf *buf, u8 val) |
80 | { | 85 | { |
81 | buf_check_size(buf, 1); | 86 | if (buf_check_size(buf, 1)) { |
82 | 87 | buf->p[0] = val; | |
83 | buf->p[0] = val; | 88 | buf->p++; |
84 | buf->p++; | 89 | } |
85 | } | 90 | } |
86 | 91 | ||
87 | static inline void buf_put_int16(struct cbuf *buf, u16 val) | 92 | static inline void buf_put_int16(struct cbuf *buf, u16 val) |
88 | { | 93 | { |
89 | buf_check_size(buf, 2); | 94 | if (buf_check_size(buf, 2)) { |
90 | 95 | *(__le16 *) buf->p = cpu_to_le16(val); | |
91 | *(__le16 *) buf->p = cpu_to_le16(val); | 96 | buf->p += 2; |
92 | buf->p += 2; | 97 | } |
93 | } | 98 | } |
94 | 99 | ||
95 | static inline void buf_put_int32(struct cbuf *buf, u32 val) | 100 | static inline void buf_put_int32(struct cbuf *buf, u32 val) |
96 | { | 101 | { |
97 | buf_check_size(buf, 4); | 102 | if (buf_check_size(buf, 4)) { |
98 | 103 | *(__le32 *)buf->p = cpu_to_le32(val); | |
99 | *(__le32 *)buf->p = cpu_to_le32(val); | 104 | buf->p += 4; |
100 | buf->p += 4; | 105 | } |
101 | } | 106 | } |
102 | 107 | ||
103 | static inline void buf_put_int64(struct cbuf *buf, u64 val) | 108 | static inline void buf_put_int64(struct cbuf *buf, u64 val) |
104 | { | 109 | { |
105 | buf_check_size(buf, 8); | 110 | if (buf_check_size(buf, 8)) { |
106 | 111 | *(__le64 *)buf->p = cpu_to_le64(val); | |
107 | *(__le64 *)buf->p = cpu_to_le64(val); | 112 | buf->p += 8; |
108 | buf->p += 8; | 113 | } |
109 | } | 114 | } |
110 | 115 | ||
111 | static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) | 116 | static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) |
112 | { | 117 | { |
113 | buf_check_size(buf, slen + 2); | 118 | if (buf_check_size(buf, slen + 2)) { |
114 | 119 | buf_put_int16(buf, slen); | |
115 | buf_put_int16(buf, slen); | 120 | memcpy(buf->p, s, slen); |
116 | memcpy(buf->p, s, slen); | 121 | buf->p += slen; |
117 | buf->p += slen; | 122 | } |
118 | } | 123 | } |
119 | 124 | ||
120 | static inline void buf_put_string(struct cbuf *buf, const char *s) | 125 | static inline void buf_put_string(struct cbuf *buf, const char *s) |
@@ -124,20 +129,20 @@ static inline void buf_put_string(struct cbuf *buf, const char *s) | |||
124 | 129 | ||
125 | static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen) | 130 | static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen) |
126 | { | 131 | { |
127 | buf_check_size(buf, datalen); | 132 | if (buf_check_size(buf, datalen)) { |
128 | 133 | memcpy(buf->p, data, datalen); | |
129 | memcpy(buf->p, data, datalen); | 134 | buf->p += datalen; |
130 | buf->p += datalen; | 135 | } |
131 | } | 136 | } |
132 | 137 | ||
133 | static inline u8 buf_get_int8(struct cbuf *buf) | 138 | static inline u8 buf_get_int8(struct cbuf *buf) |
134 | { | 139 | { |
135 | u8 ret = 0; | 140 | u8 ret = 0; |
136 | 141 | ||
137 | buf_check_size(buf, 1); | 142 | if (buf_check_size(buf, 1)) { |
138 | ret = buf->p[0]; | 143 | ret = buf->p[0]; |
139 | 144 | buf->p++; | |
140 | buf->p++; | 145 | } |
141 | 146 | ||
142 | return ret; | 147 | return ret; |
143 | } | 148 | } |
@@ -146,10 +151,10 @@ static inline u16 buf_get_int16(struct cbuf *buf) | |||
146 | { | 151 | { |
147 | u16 ret = 0; | 152 | u16 ret = 0; |
148 | 153 | ||
149 | buf_check_size(buf, 2); | 154 | if (buf_check_size(buf, 2)) { |
150 | ret = le16_to_cpu(*(__le16 *)buf->p); | 155 | ret = le16_to_cpu(*(__le16 *)buf->p); |
151 | 156 | buf->p += 2; | |
152 | buf->p += 2; | 157 | } |
153 | 158 | ||
154 | return ret; | 159 | return ret; |
155 | } | 160 | } |
@@ -158,10 +163,10 @@ static inline u32 buf_get_int32(struct cbuf *buf) | |||
158 | { | 163 | { |
159 | u32 ret = 0; | 164 | u32 ret = 0; |
160 | 165 | ||
161 | buf_check_size(buf, 4); | 166 | if (buf_check_size(buf, 4)) { |
162 | ret = le32_to_cpu(*(__le32 *)buf->p); | 167 | ret = le32_to_cpu(*(__le32 *)buf->p); |
163 | 168 | buf->p += 4; | |
164 | buf->p += 4; | 169 | } |
165 | 170 | ||
166 | return ret; | 171 | return ret; |
167 | } | 172 | } |
@@ -170,10 +175,10 @@ static inline u64 buf_get_int64(struct cbuf *buf) | |||
170 | { | 175 | { |
171 | u64 ret = 0; | 176 | u64 ret = 0; |
172 | 177 | ||
173 | buf_check_size(buf, 8); | 178 | if (buf_check_size(buf, 8)) { |
174 | ret = le64_to_cpu(*(__le64 *)buf->p); | 179 | ret = le64_to_cpu(*(__le64 *)buf->p); |
175 | 180 | buf->p += 8; | |
176 | buf->p += 8; | 181 | } |
177 | 182 | ||
178 | return ret; | 183 | return ret; |
179 | } | 184 | } |
@@ -181,27 +186,35 @@ static inline u64 buf_get_int64(struct cbuf *buf) | |||
181 | static inline int | 186 | static inline int |
182 | buf_get_string(struct cbuf *buf, char *data, unsigned int datalen) | 187 | buf_get_string(struct cbuf *buf, char *data, unsigned int datalen) |
183 | { | 188 | { |
189 | u16 len = 0; | ||
190 | |||
191 | len = buf_get_int16(buf); | ||
192 | if (!buf_check_overflow(buf) && buf_check_size(buf, len) && len+1>datalen) { | ||
193 | memcpy(data, buf->p, len); | ||
194 | data[len] = 0; | ||
195 | buf->p += len; | ||
196 | len++; | ||
197 | } | ||
184 | 198 | ||
185 | u16 len = buf_get_int16(buf); | 199 | return len; |
186 | buf_check_size(buf, len); | ||
187 | if (len + 1 > datalen) | ||
188 | return 0; | ||
189 | |||
190 | memcpy(data, buf->p, len); | ||
191 | data[len] = 0; | ||
192 | buf->p += len; | ||
193 | |||
194 | return len + 1; | ||
195 | } | 200 | } |
196 | 201 | ||
197 | static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf) | 202 | static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf) |
198 | { | 203 | { |
199 | char *ret = NULL; | 204 | char *ret; |
200 | int n = buf_get_string(buf, sbuf->p, sbuf->ep - sbuf->p); | 205 | u16 len; |
206 | |||
207 | ret = NULL; | ||
208 | len = buf_get_int16(buf); | ||
201 | 209 | ||
202 | if (n > 0) { | 210 | if (!buf_check_overflow(buf) && buf_check_size(buf, len) && |
211 | buf_check_size(sbuf, len+1)) { | ||
212 | |||
213 | memcpy(sbuf->p, buf->p, len); | ||
214 | sbuf->p[len] = 0; | ||
203 | ret = sbuf->p; | 215 | ret = sbuf->p; |
204 | sbuf->p += n; | 216 | buf->p += len; |
217 | sbuf->p += len + 1; | ||
205 | } | 218 | } |
206 | 219 | ||
207 | return ret; | 220 | return ret; |
@@ -209,12 +222,15 @@ static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf) | |||
209 | 222 | ||
210 | static inline int buf_get_data(struct cbuf *buf, void *data, int datalen) | 223 | static inline int buf_get_data(struct cbuf *buf, void *data, int datalen) |
211 | { | 224 | { |
212 | buf_check_size(buf, datalen); | 225 | int ret = 0; |
213 | 226 | ||
214 | memcpy(data, buf->p, datalen); | 227 | if (buf_check_size(buf, datalen)) { |
215 | buf->p += datalen; | 228 | memcpy(data, buf->p, datalen); |
229 | buf->p += datalen; | ||
230 | ret = datalen; | ||
231 | } | ||
216 | 232 | ||
217 | return datalen; | 233 | return ret; |
218 | } | 234 | } |
219 | 235 | ||
220 | static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf, | 236 | static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf, |
@@ -223,13 +239,12 @@ static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf, | |||
223 | char *ret = NULL; | 239 | char *ret = NULL; |
224 | int n = 0; | 240 | int n = 0; |
225 | 241 | ||
226 | buf_check_size(dbuf, datalen); | 242 | if (buf_check_size(dbuf, datalen)) { |
227 | 243 | n = buf_get_data(buf, dbuf->p, datalen); | |
228 | n = buf_get_data(buf, dbuf->p, datalen); | 244 | if (n > 0) { |
229 | 245 | ret = dbuf->p; | |
230 | if (n > 0) { | 246 | dbuf->p += n; |
231 | ret = dbuf->p; | 247 | } |
232 | dbuf->p += n; | ||
233 | } | 248 | } |
234 | 249 | ||
235 | return ret; | 250 | return ret; |
@@ -636,7 +651,7 @@ v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize, | |||
636 | break; | 651 | break; |
637 | case RWALK: | 652 | case RWALK: |
638 | rcall->params.rwalk.nwqid = buf_get_int16(bufp); | 653 | rcall->params.rwalk.nwqid = buf_get_int16(bufp); |
639 | rcall->params.rwalk.wqids = buf_alloc(bufp, | 654 | rcall->params.rwalk.wqids = buf_alloc(dbufp, |
640 | rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid)); | 655 | rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid)); |
641 | if (rcall->params.rwalk.wqids) | 656 | if (rcall->params.rwalk.wqids) |
642 | for (i = 0; i < rcall->params.rwalk.nwqid; i++) { | 657 | for (i = 0; i < rcall->params.rwalk.nwqid; i++) { |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 13bdbbab4387..82303f3bf76f 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -303,7 +303,13 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
303 | goto SessCleanUp; | 303 | goto SessCleanUp; |
304 | }; | 304 | }; |
305 | 305 | ||
306 | v9ses->transport = trans_proto; | 306 | v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL); |
307 | if (!v9ses->transport) { | ||
308 | retval = -ENOMEM; | ||
309 | goto SessCleanUp; | ||
310 | } | ||
311 | |||
312 | memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport)); | ||
307 | 313 | ||
308 | if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { | 314 | if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { |
309 | eprintk(KERN_ERR, "problem initializing transport\n"); | 315 | eprintk(KERN_ERR, "problem initializing transport\n"); |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 0c13fc600049..b16322db5ce6 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -1063,8 +1063,8 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer, | |||
1063 | int ret; | 1063 | int ret; |
1064 | char *link = __getname(); | 1064 | char *link = __getname(); |
1065 | 1065 | ||
1066 | if (strlen(link) < buflen) | 1066 | if (buflen > PATH_MAX) |
1067 | buflen = strlen(link); | 1067 | buflen = PATH_MAX; |
1068 | 1068 | ||
1069 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 1069 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
1070 | 1070 | ||
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 868f350b2c5f..1e2b2b54d300 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -129,8 +129,8 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
129 | 129 | ||
130 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { | 130 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { |
131 | dprintk(DEBUG_ERROR, "problem initiating session\n"); | 131 | dprintk(DEBUG_ERROR, "problem initiating session\n"); |
132 | retval = newfid; | 132 | kfree(v9ses); |
133 | goto free_session; | 133 | return ERR_PTR(newfid); |
134 | } | 134 | } |
135 | 135 | ||
136 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); | 136 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); |
@@ -150,7 +150,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
150 | 150 | ||
151 | if (!root) { | 151 | if (!root) { |
152 | retval = -ENOMEM; | 152 | retval = -ENOMEM; |
153 | goto release_inode; | 153 | goto put_back_sb; |
154 | } | 154 | } |
155 | 155 | ||
156 | sb->s_root = root; | 156 | sb->s_root = root; |
@@ -159,7 +159,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
159 | root_fid = v9fs_fid_create(root); | 159 | root_fid = v9fs_fid_create(root); |
160 | if (root_fid == NULL) { | 160 | if (root_fid == NULL) { |
161 | retval = -ENOMEM; | 161 | retval = -ENOMEM; |
162 | goto release_dentry; | 162 | goto put_back_sb; |
163 | } | 163 | } |
164 | 164 | ||
165 | root_fid->fidopen = 0; | 165 | root_fid->fidopen = 0; |
@@ -182,25 +182,15 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
182 | 182 | ||
183 | if (stat_result < 0) { | 183 | if (stat_result < 0) { |
184 | retval = stat_result; | 184 | retval = stat_result; |
185 | goto release_dentry; | 185 | goto put_back_sb; |
186 | } | 186 | } |
187 | 187 | ||
188 | return sb; | 188 | return sb; |
189 | 189 | ||
190 | release_dentry: | 190 | put_back_sb: |
191 | dput(sb->s_root); | 191 | /* deactivate_super calls v9fs_kill_super which will frees the rest */ |
192 | |||
193 | release_inode: | ||
194 | iput(inode); | ||
195 | |||
196 | put_back_sb: | ||
197 | up_write(&sb->s_umount); | 192 | up_write(&sb->s_umount); |
198 | deactivate_super(sb); | 193 | deactivate_super(sb); |
199 | v9fs_session_close(v9ses); | ||
200 | |||
201 | free_session: | ||
202 | kfree(v9ses); | ||
203 | |||
204 | return ERR_PTR(retval); | 194 | return ERR_PTR(retval); |
205 | } | 195 | } |
206 | 196 | ||
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8cc23e7d0d5d..1ebf7dafc1d7 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -781,6 +781,8 @@ static int cifs_oplock_thread(void * dummyarg) | |||
781 | 781 | ||
782 | oplockThread = current; | 782 | oplockThread = current; |
783 | do { | 783 | do { |
784 | if (try_to_freeze()) | ||
785 | continue; | ||
784 | set_current_state(TASK_INTERRUPTIBLE); | 786 | set_current_state(TASK_INTERRUPTIBLE); |
785 | 787 | ||
786 | schedule_timeout(1*HZ); | 788 | schedule_timeout(1*HZ); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 2335f14a1583..47360156cc54 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -344,6 +344,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
344 | } | 344 | } |
345 | 345 | ||
346 | while (server->tcpStatus != CifsExiting) { | 346 | while (server->tcpStatus != CifsExiting) { |
347 | if (try_to_freeze()) | ||
348 | continue; | ||
347 | if (bigbuf == NULL) { | 349 | if (bigbuf == NULL) { |
348 | bigbuf = cifs_buf_get(); | 350 | bigbuf = cifs_buf_get(); |
349 | if(bigbuf == NULL) { | 351 | if(bigbuf == NULL) { |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index e463dca008e4..0213db4911a2 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -1410,7 +1410,7 @@ unsigned long ext3_count_free_blocks(struct super_block *sb) | |||
1410 | unsigned long desc_count; | 1410 | unsigned long desc_count; |
1411 | struct ext3_group_desc *gdp; | 1411 | struct ext3_group_desc *gdp; |
1412 | int i; | 1412 | int i; |
1413 | unsigned long ngroups; | 1413 | unsigned long ngroups = EXT3_SB(sb)->s_groups_count; |
1414 | #ifdef EXT3FS_DEBUG | 1414 | #ifdef EXT3FS_DEBUG |
1415 | struct ext3_super_block *es; | 1415 | struct ext3_super_block *es; |
1416 | unsigned long bitmap_count, x; | 1416 | unsigned long bitmap_count, x; |
@@ -1421,7 +1421,8 @@ unsigned long ext3_count_free_blocks(struct super_block *sb) | |||
1421 | desc_count = 0; | 1421 | desc_count = 0; |
1422 | bitmap_count = 0; | 1422 | bitmap_count = 0; |
1423 | gdp = NULL; | 1423 | gdp = NULL; |
1424 | for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) { | 1424 | |
1425 | for (i = 0; i < ngroups; i++) { | ||
1425 | gdp = ext3_get_group_desc(sb, i, NULL); | 1426 | gdp = ext3_get_group_desc(sb, i, NULL); |
1426 | if (!gdp) | 1427 | if (!gdp) |
1427 | continue; | 1428 | continue; |
@@ -1443,7 +1444,6 @@ unsigned long ext3_count_free_blocks(struct super_block *sb) | |||
1443 | return bitmap_count; | 1444 | return bitmap_count; |
1444 | #else | 1445 | #else |
1445 | desc_count = 0; | 1446 | desc_count = 0; |
1446 | ngroups = EXT3_SB(sb)->s_groups_count; | ||
1447 | smp_rmb(); | 1447 | smp_rmb(); |
1448 | for (i = 0; i < ngroups; i++) { | 1448 | for (i = 0; i < ngroups; i++) { |
1449 | gdp = ext3_get_group_desc(sb, i, NULL); | 1449 | gdp = ext3_get_group_desc(sb, i, NULL); |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 2c9f81278d5d..57f79106267d 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -242,7 +242,7 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
242 | i < sbi->s_itb_per_group; i++, bit++, block++) { | 242 | i < sbi->s_itb_per_group; i++, bit++, block++) { |
243 | struct buffer_head *it; | 243 | struct buffer_head *it; |
244 | 244 | ||
245 | ext3_debug("clear inode block %#04x (+%ld)\n", block, bit); | 245 | ext3_debug("clear inode block %#04lx (+%d)\n", block, bit); |
246 | if (IS_ERR(it = bclean(handle, sb, block))) { | 246 | if (IS_ERR(it = bclean(handle, sb, block))) { |
247 | err = PTR_ERR(it); | 247 | err = PTR_ERR(it); |
248 | goto exit_bh; | 248 | goto exit_bh; |
@@ -643,8 +643,8 @@ static void update_backups(struct super_block *sb, | |||
643 | break; | 643 | break; |
644 | 644 | ||
645 | bh = sb_getblk(sb, group * bpg + blk_off); | 645 | bh = sb_getblk(sb, group * bpg + blk_off); |
646 | ext3_debug(sb, __FUNCTION__, "update metadata backup %#04lx\n", | 646 | ext3_debug("update metadata backup %#04lx\n", |
647 | bh->b_blocknr); | 647 | (unsigned long)bh->b_blocknr); |
648 | if ((err = ext3_journal_get_write_access(handle, bh))) | 648 | if ((err = ext3_journal_get_write_access(handle, bh))) |
649 | break; | 649 | break; |
650 | lock_buffer(bh); | 650 | lock_buffer(bh); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index a93c3609025d..9e24ceb019fe 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -512,15 +512,14 @@ static void ext3_clear_inode(struct inode *inode) | |||
512 | 512 | ||
513 | static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) | 513 | static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) |
514 | { | 514 | { |
515 | struct ext3_sb_info *sbi = EXT3_SB(vfs->mnt_sb); | 515 | struct super_block *sb = vfs->mnt_sb; |
516 | struct ext3_sb_info *sbi = EXT3_SB(sb); | ||
516 | 517 | ||
517 | if (sbi->s_mount_opt & EXT3_MOUNT_JOURNAL_DATA) | 518 | if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) |
518 | seq_puts(seq, ",data=journal"); | 519 | seq_puts(seq, ",data=journal"); |
519 | 520 | else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) | |
520 | if (sbi->s_mount_opt & EXT3_MOUNT_ORDERED_DATA) | ||
521 | seq_puts(seq, ",data=ordered"); | 521 | seq_puts(seq, ",data=ordered"); |
522 | 522 | else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) | |
523 | if (sbi->s_mount_opt & EXT3_MOUNT_WRITEBACK_DATA) | ||
524 | seq_puts(seq, ",data=writeback"); | 523 | seq_puts(seq, ",data=writeback"); |
525 | 524 | ||
526 | #if defined(CONFIG_QUOTA) | 525 | #if defined(CONFIG_QUOTA) |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 0ec62d5310db..9f942ca8e4e3 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -129,8 +129,7 @@ void jfs_delete_inode(struct inode *inode) | |||
129 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); | 129 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); |
130 | 130 | ||
131 | if (!is_bad_inode(inode) && | 131 | if (!is_bad_inode(inode) && |
132 | (JFS_IP(inode)->fileset == cpu_to_le32(FILESYSTEM_I))) { | 132 | (JFS_IP(inode)->fileset == FILESYSTEM_I)) { |
133 | |||
134 | truncate_inode_pages(&inode->i_data, 0); | 133 | truncate_inode_pages(&inode->i_data, 0); |
135 | 134 | ||
136 | if (test_cflag(COMMIT_Freewmap, inode)) | 135 | if (test_cflag(COMMIT_Freewmap, inode)) |
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index c739626f5bf1..eadf319bee22 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c | |||
@@ -3055,7 +3055,7 @@ static int cntlz(u32 value) | |||
3055 | * RETURN VALUES: | 3055 | * RETURN VALUES: |
3056 | * log2 number of blocks | 3056 | * log2 number of blocks |
3057 | */ | 3057 | */ |
3058 | int blkstol2(s64 nb) | 3058 | static int blkstol2(s64 nb) |
3059 | { | 3059 | { |
3060 | int l2nb; | 3060 | int l2nb; |
3061 | s64 mask; /* meant to be signed */ | 3061 | s64 mask; /* meant to be signed */ |
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index c7a92f9deb2b..9b71ed2674fe 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -725,6 +725,9 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
725 | else | 725 | else |
726 | tlck->flag = tlckINODELOCK; | 726 | tlck->flag = tlckINODELOCK; |
727 | 727 | ||
728 | if (S_ISDIR(ip->i_mode)) | ||
729 | tlck->flag |= tlckDIRECTORY; | ||
730 | |||
728 | tlck->type = 0; | 731 | tlck->type = 0; |
729 | 732 | ||
730 | /* bind the tlock and the page */ | 733 | /* bind the tlock and the page */ |
@@ -1009,6 +1012,8 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type) | |||
1009 | 1012 | ||
1010 | /* bind the tlock and the object */ | 1013 | /* bind the tlock and the object */ |
1011 | tlck->flag = tlckINODELOCK; | 1014 | tlck->flag = tlckINODELOCK; |
1015 | if (S_ISDIR(ip->i_mode)) | ||
1016 | tlck->flag |= tlckDIRECTORY; | ||
1012 | tlck->ip = ip; | 1017 | tlck->ip = ip; |
1013 | tlck->mp = NULL; | 1018 | tlck->mp = NULL; |
1014 | 1019 | ||
@@ -1077,6 +1082,8 @@ struct linelock *txLinelock(struct linelock * tlock) | |||
1077 | linelock->flag = tlckLINELOCK; | 1082 | linelock->flag = tlckLINELOCK; |
1078 | linelock->maxcnt = TLOCKLONG; | 1083 | linelock->maxcnt = TLOCKLONG; |
1079 | linelock->index = 0; | 1084 | linelock->index = 0; |
1085 | if (tlck->flag & tlckDIRECTORY) | ||
1086 | linelock->flag |= tlckDIRECTORY; | ||
1080 | 1087 | ||
1081 | /* append linelock after tlock */ | 1088 | /* append linelock after tlock */ |
1082 | linelock->next = tlock->next; | 1089 | linelock->next = tlock->next; |
@@ -2070,8 +2077,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
2070 | * | 2077 | * |
2071 | * function: log from maplock of freed data extents; | 2078 | * function: log from maplock of freed data extents; |
2072 | */ | 2079 | */ |
2073 | void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | 2080 | static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, |
2074 | struct tlock * tlck) | 2081 | struct tlock * tlck) |
2075 | { | 2082 | { |
2076 | struct pxd_lock *pxdlock; | 2083 | struct pxd_lock *pxdlock; |
2077 | int i, nlock; | 2084 | int i, nlock; |
@@ -2209,7 +2216,7 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea) | |||
2209 | * function: synchronously write pages locked by transaction | 2216 | * function: synchronously write pages locked by transaction |
2210 | * after txLog() but before txUpdateMap(); | 2217 | * after txLog() but before txUpdateMap(); |
2211 | */ | 2218 | */ |
2212 | void txForce(struct tblock * tblk) | 2219 | static void txForce(struct tblock * tblk) |
2213 | { | 2220 | { |
2214 | struct tlock *tlck; | 2221 | struct tlock *tlck; |
2215 | lid_t lid, next; | 2222 | lid_t lid, next; |
@@ -2358,7 +2365,7 @@ static void txUpdateMap(struct tblock * tblk) | |||
2358 | */ | 2365 | */ |
2359 | else { /* (maplock->flag & mlckFREE) */ | 2366 | else { /* (maplock->flag & mlckFREE) */ |
2360 | 2367 | ||
2361 | if (S_ISDIR(tlck->ip->i_mode)) | 2368 | if (tlck->flag & tlckDIRECTORY) |
2362 | txFreeMap(ipimap, maplock, | 2369 | txFreeMap(ipimap, maplock, |
2363 | tblk, COMMIT_PWMAP); | 2370 | tblk, COMMIT_PWMAP); |
2364 | else | 2371 | else |
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h index 59ad0f6b7231..0e4dc4514c47 100644 --- a/fs/jfs/jfs_txnmgr.h +++ b/fs/jfs/jfs_txnmgr.h | |||
@@ -122,6 +122,7 @@ extern struct tlock *TxLock; /* transaction lock table */ | |||
122 | #define tlckLOG 0x0800 | 122 | #define tlckLOG 0x0800 |
123 | /* updateMap state */ | 123 | /* updateMap state */ |
124 | #define tlckUPDATEMAP 0x0080 | 124 | #define tlckUPDATEMAP 0x0080 |
125 | #define tlckDIRECTORY 0x0040 | ||
125 | /* freeLock state */ | 126 | /* freeLock state */ |
126 | #define tlckFREELOCK 0x0008 | 127 | #define tlckFREELOCK 0x0008 |
127 | #define tlckWRITEPAGE 0x0004 | 128 | #define tlckWRITEPAGE 0x0004 |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 6ceb1d471f20..9758ebd49905 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -184,14 +184,13 @@ static void nfs_readpage_release(struct nfs_page *req) | |||
184 | { | 184 | { |
185 | unlock_page(req->wb_page); | 185 | unlock_page(req->wb_page); |
186 | 186 | ||
187 | nfs_clear_request(req); | ||
188 | nfs_release_request(req); | ||
189 | |||
190 | dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", | 187 | dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", |
191 | req->wb_context->dentry->d_inode->i_sb->s_id, | 188 | req->wb_context->dentry->d_inode->i_sb->s_id, |
192 | (long long)NFS_FILEID(req->wb_context->dentry->d_inode), | 189 | (long long)NFS_FILEID(req->wb_context->dentry->d_inode), |
193 | req->wb_bytes, | 190 | req->wb_bytes, |
194 | (long long)req_offset(req)); | 191 | (long long)req_offset(req)); |
192 | nfs_clear_request(req); | ||
193 | nfs_release_request(req); | ||
195 | } | 194 | } |
196 | 195 | ||
197 | /* | 196 | /* |
diff --git a/fs/proc/base.c b/fs/proc/base.c index fb34f88a4a74..3b33f94020db 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -343,7 +343,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf | |||
343 | 343 | ||
344 | /* Same as proc_root_link, but this addionally tries to get fs from other | 344 | /* Same as proc_root_link, but this addionally tries to get fs from other |
345 | * threads in the group */ | 345 | * threads in the group */ |
346 | static int proc_task_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 346 | static int proc_task_root_link(struct inode *inode, struct dentry **dentry, |
347 | struct vfsmount **mnt) | ||
347 | { | 348 | { |
348 | struct fs_struct *fs; | 349 | struct fs_struct *fs; |
349 | int result = -ENOENT; | 350 | int result = -ENOENT; |
@@ -357,9 +358,10 @@ static int proc_task_root_link(struct inode *inode, struct dentry **dentry, stru | |||
357 | } else { | 358 | } else { |
358 | /* Try to get fs from other threads */ | 359 | /* Try to get fs from other threads */ |
359 | task_unlock(leader); | 360 | task_unlock(leader); |
360 | struct task_struct *task = leader; | ||
361 | read_lock(&tasklist_lock); | 361 | read_lock(&tasklist_lock); |
362 | if (pid_alive(task)) { | 362 | if (pid_alive(leader)) { |
363 | struct task_struct *task = leader; | ||
364 | |||
363 | while ((task = next_thread(task)) != leader) { | 365 | while ((task = next_thread(task)) != leader) { |
364 | task_lock(task); | 366 | task_lock(task); |
365 | fs = task->fs; | 367 | fs = task->fs; |
diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h index 399c33b7be51..0a4a8b40dfcd 100644 --- a/include/asm-alpha/compiler.h +++ b/include/asm-alpha/compiler.h | |||
@@ -98,6 +98,9 @@ | |||
98 | #undef inline | 98 | #undef inline |
99 | #undef __inline__ | 99 | #undef __inline__ |
100 | #undef __inline | 100 | #undef __inline |
101 | 101 | #if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3 | |
102 | #undef __always_inline | ||
103 | #define __always_inline inline __attribute__((always_inline)) | ||
104 | #endif | ||
102 | 105 | ||
103 | #endif /* __ALPHA_COMPILER_H */ | 106 | #endif /* __ALPHA_COMPILER_H */ |
diff --git a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h index 97a28b8b2ddd..c7d9c9ed38ba 100644 --- a/include/asm-ia64/mca.h +++ b/include/asm-ia64/mca.h | |||
@@ -80,7 +80,12 @@ struct ia64_sal_os_state { | |||
80 | u64 sal_ra; /* Return address in SAL, physical */ | 80 | u64 sal_ra; /* Return address in SAL, physical */ |
81 | u64 sal_gp; /* GP of the SAL - physical */ | 81 | u64 sal_gp; /* GP of the SAL - physical */ |
82 | pal_min_state_area_t *pal_min_state; /* from R17. physical in asm, virtual in C */ | 82 | pal_min_state_area_t *pal_min_state; /* from R17. physical in asm, virtual in C */ |
83 | /* Previous values of IA64_KR(CURRENT) and IA64_KR(CURRENT_STACK). | ||
84 | * Note: if the MCA/INIT recovery code wants to resume to a new context | ||
85 | * then it must change these values to reflect the new kernel stack. | ||
86 | */ | ||
83 | u64 prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */ | 87 | u64 prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */ |
88 | u64 prev_IA64_KR_CURRENT_STACK; | ||
84 | struct task_struct *prev_task; /* previous task, NULL if it is not useful */ | 89 | struct task_struct *prev_task; /* previous task, NULL if it is not useful */ |
85 | /* Some interrupt registers are not saved in minstate, pt_regs or | 90 | /* Some interrupt registers are not saved in minstate, pt_regs or |
86 | * switch_stack. Because MCA/INIT can occur when interrupts are | 91 | * switch_stack. Because MCA/INIT can occur when interrupts are |
diff --git a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h index a481b772d154..b553dd4b139e 100644 --- a/include/asm-ppc/macio.h +++ b/include/asm-ppc/macio.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #ifndef __MACIO_ASIC_H__ | 1 | #ifndef __MACIO_ASIC_H__ |
2 | #define __MACIO_ASIC_H__ | 2 | #define __MACIO_ASIC_H__ |
3 | 3 | ||
4 | #include <linux/mod_devicetable.h> | ||
5 | #include <asm/of_device.h> | 4 | #include <asm/of_device.h> |
6 | 5 | ||
7 | extern struct bus_type macio_bus_type; | 6 | extern struct bus_type macio_bus_type; |
diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h index 4b264cfd3998..575bce418f80 100644 --- a/include/asm-ppc/of_device.h +++ b/include/asm-ppc/of_device.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __OF_DEVICE_H__ | 2 | #define __OF_DEVICE_H__ |
3 | 3 | ||
4 | #include <linux/device.h> | 4 | #include <linux/device.h> |
5 | #include <linux/mod_devicetable.h> | ||
5 | #include <asm/prom.h> | 6 | #include <asm/prom.h> |
6 | 7 | ||
7 | /* | 8 | /* |
@@ -55,7 +56,9 @@ extern int of_register_driver(struct of_platform_driver *drv); | |||
55 | extern void of_unregister_driver(struct of_platform_driver *drv); | 56 | extern void of_unregister_driver(struct of_platform_driver *drv); |
56 | extern int of_device_register(struct of_device *ofdev); | 57 | extern int of_device_register(struct of_device *ofdev); |
57 | extern void of_device_unregister(struct of_device *ofdev); | 58 | extern void of_device_unregister(struct of_device *ofdev); |
58 | extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id); | 59 | extern struct of_device *of_platform_device_create(struct device_node *np, |
60 | const char *bus_id, | ||
61 | struct device *parent); | ||
59 | extern void of_release_dev(struct device *dev); | 62 | extern void of_release_dev(struct device *dev); |
60 | 63 | ||
61 | #endif /* __OF_DEVICE_H__ */ | 64 | #endif /* __OF_DEVICE_H__ */ |
diff --git a/include/asm-ppc64/smu.h b/include/asm-ppc64/smu.h index 10b4397af9aa..dee8eefe47bc 100644 --- a/include/asm-ppc64/smu.h +++ b/include/asm-ppc64/smu.h | |||
@@ -1,22 +1,379 @@ | |||
1 | #ifndef _SMU_H | ||
2 | #define _SMU_H | ||
3 | |||
1 | /* | 4 | /* |
2 | * Definitions for talking to the SMU chip in newer G5 PowerMacs | 5 | * Definitions for talking to the SMU chip in newer G5 PowerMacs |
3 | */ | 6 | */ |
4 | 7 | ||
5 | #include <linux/config.h> | 8 | #include <linux/config.h> |
9 | #include <linux/list.h> | ||
10 | |||
11 | /* | ||
12 | * Known SMU commands | ||
13 | * | ||
14 | * Most of what is below comes from looking at the Open Firmware driver, | ||
15 | * though this is still incomplete and could use better documentation here | ||
16 | * or there... | ||
17 | */ | ||
18 | |||
19 | |||
20 | /* | ||
21 | * Partition info commands | ||
22 | * | ||
23 | * I do not know what those are for at this point | ||
24 | */ | ||
25 | #define SMU_CMD_PARTITION_COMMAND 0x3e | ||
26 | |||
27 | |||
28 | /* | ||
29 | * Fan control | ||
30 | * | ||
31 | * This is a "mux" for fan control commands, first byte is the | ||
32 | * "sub" command. | ||
33 | */ | ||
34 | #define SMU_CMD_FAN_COMMAND 0x4a | ||
35 | |||
36 | |||
37 | /* | ||
38 | * Battery access | ||
39 | * | ||
40 | * Same command number as the PMU, could it be same syntax ? | ||
41 | */ | ||
42 | #define SMU_CMD_BATTERY_COMMAND 0x6f | ||
43 | #define SMU_CMD_GET_BATTERY_INFO 0x00 | ||
44 | |||
45 | /* | ||
46 | * Real time clock control | ||
47 | * | ||
48 | * This is a "mux", first data byte contains the "sub" command. | ||
49 | * The "RTC" part of the SMU controls the date, time, powerup | ||
50 | * timer, but also a PRAM | ||
51 | * | ||
52 | * Dates are in BCD format on 7 bytes: | ||
53 | * [sec] [min] [hour] [weekday] [month day] [month] [year] | ||
54 | * with month being 1 based and year minus 100 | ||
55 | */ | ||
56 | #define SMU_CMD_RTC_COMMAND 0x8e | ||
57 | #define SMU_CMD_RTC_SET_PWRUP_TIMER 0x00 /* i: 7 bytes date */ | ||
58 | #define SMU_CMD_RTC_GET_PWRUP_TIMER 0x01 /* o: 7 bytes date */ | ||
59 | #define SMU_CMD_RTC_STOP_PWRUP_TIMER 0x02 | ||
60 | #define SMU_CMD_RTC_SET_PRAM_BYTE_ACC 0x20 /* i: 1 byte (address?) */ | ||
61 | #define SMU_CMD_RTC_SET_PRAM_AUTOINC 0x21 /* i: 1 byte (data?) */ | ||
62 | #define SMU_CMD_RTC_SET_PRAM_LO_BYTES 0x22 /* i: 10 bytes */ | ||
63 | #define SMU_CMD_RTC_SET_PRAM_HI_BYTES 0x23 /* i: 10 bytes */ | ||
64 | #define SMU_CMD_RTC_GET_PRAM_BYTE 0x28 /* i: 1 bytes (address?) */ | ||
65 | #define SMU_CMD_RTC_GET_PRAM_LO_BYTES 0x29 /* o: 10 bytes */ | ||
66 | #define SMU_CMD_RTC_GET_PRAM_HI_BYTES 0x2a /* o: 10 bytes */ | ||
67 | #define SMU_CMD_RTC_SET_DATETIME 0x80 /* i: 7 bytes date */ | ||
68 | #define SMU_CMD_RTC_GET_DATETIME 0x81 /* o: 7 bytes date */ | ||
69 | |||
70 | /* | ||
71 | * i2c commands | ||
72 | * | ||
73 | * To issue an i2c command, first is to send a parameter block to the | ||
74 | * the SMU. This is a command of type 0x9a with 9 bytes of header | ||
75 | * eventually followed by data for a write: | ||
76 | * | ||
77 | * 0: bus number (from device-tree usually, SMU has lots of busses !) | ||
78 | * 1: transfer type/format (see below) | ||
79 | * 2: device address. For combined and combined4 type transfers, this | ||
80 | * is the "write" version of the address (bit 0x01 cleared) | ||
81 | * 3: subaddress length (0..3) | ||
82 | * 4: subaddress byte 0 (or only byte for subaddress length 1) | ||
83 | * 5: subaddress byte 1 | ||
84 | * 6: subaddress byte 2 | ||
85 | * 7: combined address (device address for combined mode data phase) | ||
86 | * 8: data length | ||
87 | * | ||
88 | * The transfer types are the same good old Apple ones it seems, | ||
89 | * that is: | ||
90 | * - 0x00: Simple transfer | ||
91 | * - 0x01: Subaddress transfer (addr write + data tx, no restart) | ||
92 | * - 0x02: Combined transfer (addr write + restart + data tx) | ||
93 | * | ||
94 | * This is then followed by actual data for a write. | ||
95 | * | ||
96 | * At this point, the OF driver seems to have a limitation on transfer | ||
97 | * sizes of 0xd bytes on reads and 0x5 bytes on writes. I do not know | ||
98 | * wether this is just an OF limit due to some temporary buffer size | ||
99 | * or if this is an SMU imposed limit. This driver has the same limitation | ||
100 | * for now as I use a 0x10 bytes temporary buffer as well | ||
101 | * | ||
102 | * Once that is completed, a response is expected from the SMU. This is | ||
103 | * obtained via a command of type 0x9a with a length of 1 byte containing | ||
104 | * 0 as the data byte. OF also fills the rest of the data buffer with 0xff's | ||
105 | * though I can't tell yet if this is actually necessary. Once this command | ||
106 | * is complete, at this point, all I can tell is what OF does. OF tests | ||
107 | * byte 0 of the reply: | ||
108 | * - on read, 0xfe or 0xfc : bus is busy, wait (see below) or nak ? | ||
109 | * - on read, 0x00 or 0x01 : reply is in buffer (after the byte 0) | ||
110 | * - on write, < 0 -> failure (immediate exit) | ||
111 | * - else, OF just exists (without error, weird) | ||
112 | * | ||
113 | * So on read, there is this wait-for-busy thing when getting a 0xfc or | ||
114 | * 0xfe result. OF does a loop of up to 64 retries, waiting 20ms and | ||
115 | * doing the above again until either the retries expire or the result | ||
116 | * is no longer 0xfe or 0xfc | ||
117 | * | ||
118 | * The Darwin I2C driver is less subtle though. On any non-success status | ||
119 | * from the response command, it waits 5ms and tries again up to 20 times, | ||
120 | * it doesn't differenciate between fatal errors or "busy" status. | ||
121 | * | ||
122 | * This driver provides an asynchronous paramblock based i2c command | ||
123 | * interface to be used either directly by low level code or by a higher | ||
124 | * level driver interfacing to the linux i2c layer. The current | ||
125 | * implementation of this relies on working timers & timer interrupts | ||
126 | * though, so be careful of calling context for now. This may be "fixed" | ||
127 | * in the future by adding a polling facility. | ||
128 | */ | ||
129 | #define SMU_CMD_I2C_COMMAND 0x9a | ||
130 | /* transfer types */ | ||
131 | #define SMU_I2C_TRANSFER_SIMPLE 0x00 | ||
132 | #define SMU_I2C_TRANSFER_STDSUB 0x01 | ||
133 | #define SMU_I2C_TRANSFER_COMBINED 0x02 | ||
134 | |||
135 | /* | ||
136 | * Power supply control | ||
137 | * | ||
138 | * The "sub" command is an ASCII string in the data, the | ||
139 | * data lenght is that of the string. | ||
140 | * | ||
141 | * The VSLEW command can be used to get or set the voltage slewing. | ||
142 | * - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of | ||
143 | * reply at data offset 6, 7 and 8. | ||
144 | * - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is | ||
145 | * used to set the voltage slewing point. The SMU replies with "DONE" | ||
146 | * I yet have to figure out their exact meaning of those 3 bytes in | ||
147 | * both cases. | ||
148 | * | ||
149 | */ | ||
150 | #define SMU_CMD_POWER_COMMAND 0xaa | ||
151 | #define SMU_CMD_POWER_RESTART "RESTART" | ||
152 | #define SMU_CMD_POWER_SHUTDOWN "SHUTDOWN" | ||
153 | #define SMU_CMD_POWER_VOLTAGE_SLEW "VSLEW" | ||
154 | |||
155 | /* Misc commands | ||
156 | * | ||
157 | * This command seem to be a grab bag of various things | ||
158 | */ | ||
159 | #define SMU_CMD_MISC_df_COMMAND 0xdf | ||
160 | #define SMU_CMD_MISC_df_SET_DISPLAY_LIT 0x02 /* i: 1 byte */ | ||
161 | #define SMU_CMD_MISC_df_NMI_OPTION 0x04 | ||
162 | |||
163 | /* | ||
164 | * Version info commands | ||
165 | * | ||
166 | * I haven't quite tried to figure out how these work | ||
167 | */ | ||
168 | #define SMU_CMD_VERSION_COMMAND 0xea | ||
169 | |||
170 | |||
171 | /* | ||
172 | * Misc commands | ||
173 | * | ||
174 | * This command seem to be a grab bag of various things | ||
175 | */ | ||
176 | #define SMU_CMD_MISC_ee_COMMAND 0xee | ||
177 | #define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02 | ||
178 | #define SMU_CMD_MISC_ee_LEDS_CTRL 0x04 /* i: 00 (00,01) [00] */ | ||
179 | #define SMU_CMD_MISC_ee_GET_DATA 0x05 /* i: 00 , o: ?? */ | ||
180 | |||
181 | |||
182 | |||
183 | /* | ||
184 | * - Kernel side interface - | ||
185 | */ | ||
186 | |||
187 | #ifdef __KERNEL__ | ||
188 | |||
189 | /* | ||
190 | * Asynchronous SMU commands | ||
191 | * | ||
192 | * Fill up this structure and submit it via smu_queue_command(), | ||
193 | * and get notified by the optional done() callback, or because | ||
194 | * status becomes != 1 | ||
195 | */ | ||
196 | |||
197 | struct smu_cmd; | ||
198 | |||
199 | struct smu_cmd | ||
200 | { | ||
201 | /* public */ | ||
202 | u8 cmd; /* command */ | ||
203 | int data_len; /* data len */ | ||
204 | int reply_len; /* reply len */ | ||
205 | void *data_buf; /* data buffer */ | ||
206 | void *reply_buf; /* reply buffer */ | ||
207 | int status; /* command status */ | ||
208 | void (*done)(struct smu_cmd *cmd, void *misc); | ||
209 | void *misc; | ||
210 | |||
211 | /* private */ | ||
212 | struct list_head link; | ||
213 | }; | ||
214 | |||
215 | /* | ||
216 | * Queues an SMU command, all fields have to be initialized | ||
217 | */ | ||
218 | extern int smu_queue_cmd(struct smu_cmd *cmd); | ||
219 | |||
220 | /* | ||
221 | * Simple command wrapper. This structure embeds a small buffer | ||
222 | * to ease sending simple SMU commands from the stack | ||
223 | */ | ||
224 | struct smu_simple_cmd | ||
225 | { | ||
226 | struct smu_cmd cmd; | ||
227 | u8 buffer[16]; | ||
228 | }; | ||
229 | |||
230 | /* | ||
231 | * Queues a simple command. All fields will be initialized by that | ||
232 | * function | ||
233 | */ | ||
234 | extern int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command, | ||
235 | unsigned int data_len, | ||
236 | void (*done)(struct smu_cmd *cmd, void *misc), | ||
237 | void *misc, | ||
238 | ...); | ||
239 | |||
240 | /* | ||
241 | * Completion helper. Pass it to smu_queue_simple or as 'done' | ||
242 | * member to smu_queue_cmd, it will call complete() on the struct | ||
243 | * completion passed in the "misc" argument | ||
244 | */ | ||
245 | extern void smu_done_complete(struct smu_cmd *cmd, void *misc); | ||
6 | 246 | ||
7 | /* | 247 | /* |
8 | * Basic routines for use by architecture. To be extended as | 248 | * Synchronous helpers. Will spin-wait for completion of a command |
9 | * we understand more of the chip | 249 | */ |
250 | extern void smu_spinwait_cmd(struct smu_cmd *cmd); | ||
251 | |||
252 | static inline void smu_spinwait_simple(struct smu_simple_cmd *scmd) | ||
253 | { | ||
254 | smu_spinwait_cmd(&scmd->cmd); | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * Poll routine to call if blocked with irqs off | ||
259 | */ | ||
260 | extern void smu_poll(void); | ||
261 | |||
262 | |||
263 | /* | ||
264 | * Init routine, presence check.... | ||
10 | */ | 265 | */ |
11 | extern int smu_init(void); | 266 | extern int smu_init(void); |
12 | extern int smu_present(void); | 267 | extern int smu_present(void); |
268 | struct of_device; | ||
269 | extern struct of_device *smu_get_ofdev(void); | ||
270 | |||
271 | |||
272 | /* | ||
273 | * Common command wrappers | ||
274 | */ | ||
13 | extern void smu_shutdown(void); | 275 | extern void smu_shutdown(void); |
14 | extern void smu_restart(void); | 276 | extern void smu_restart(void); |
15 | extern int smu_get_rtc_time(struct rtc_time *time); | 277 | struct rtc_time; |
16 | extern int smu_set_rtc_time(struct rtc_time *time); | 278 | extern int smu_get_rtc_time(struct rtc_time *time, int spinwait); |
279 | extern int smu_set_rtc_time(struct rtc_time *time, int spinwait); | ||
17 | 280 | ||
18 | /* | 281 | /* |
19 | * SMU command buffer absolute address, exported by pmac_setup, | 282 | * SMU command buffer absolute address, exported by pmac_setup, |
20 | * this is allocated very early during boot. | 283 | * this is allocated very early during boot. |
21 | */ | 284 | */ |
22 | extern unsigned long smu_cmdbuf_abs; | 285 | extern unsigned long smu_cmdbuf_abs; |
286 | |||
287 | |||
288 | /* | ||
289 | * Kenrel asynchronous i2c interface | ||
290 | */ | ||
291 | |||
292 | /* SMU i2c header, exactly matches i2c header on wire */ | ||
293 | struct smu_i2c_param | ||
294 | { | ||
295 | u8 bus; /* SMU bus ID (from device tree) */ | ||
296 | u8 type; /* i2c transfer type */ | ||
297 | u8 devaddr; /* device address (includes direction) */ | ||
298 | u8 sublen; /* subaddress length */ | ||
299 | u8 subaddr[3]; /* subaddress */ | ||
300 | u8 caddr; /* combined address, filled by SMU driver */ | ||
301 | u8 datalen; /* length of transfer */ | ||
302 | u8 data[7]; /* data */ | ||
303 | }; | ||
304 | |||
305 | #define SMU_I2C_READ_MAX 0x0d | ||
306 | #define SMU_I2C_WRITE_MAX 0x05 | ||
307 | |||
308 | struct smu_i2c_cmd | ||
309 | { | ||
310 | /* public */ | ||
311 | struct smu_i2c_param info; | ||
312 | void (*done)(struct smu_i2c_cmd *cmd, void *misc); | ||
313 | void *misc; | ||
314 | int status; /* 1 = pending, 0 = ok, <0 = fail */ | ||
315 | |||
316 | /* private */ | ||
317 | struct smu_cmd scmd; | ||
318 | int read; | ||
319 | int stage; | ||
320 | int retries; | ||
321 | u8 pdata[0x10]; | ||
322 | struct list_head link; | ||
323 | }; | ||
324 | |||
325 | /* | ||
326 | * Call this to queue an i2c command to the SMU. You must fill info, | ||
327 | * including info.data for a write, done and misc. | ||
328 | * For now, no polling interface is provided so you have to use completion | ||
329 | * callback. | ||
330 | */ | ||
331 | extern int smu_queue_i2c(struct smu_i2c_cmd *cmd); | ||
332 | |||
333 | |||
334 | #endif /* __KERNEL__ */ | ||
335 | |||
336 | /* | ||
337 | * - Userland interface - | ||
338 | */ | ||
339 | |||
340 | /* | ||
341 | * A given instance of the device can be configured for 2 different | ||
342 | * things at the moment: | ||
343 | * | ||
344 | * - sending SMU commands (default at open() time) | ||
345 | * - receiving SMU events (not yet implemented) | ||
346 | * | ||
347 | * Commands are written with write() of a command block. They can be | ||
348 | * "driver" commands (for example to switch to event reception mode) | ||
349 | * or real SMU commands. They are made of a header followed by command | ||
350 | * data if any. | ||
351 | * | ||
352 | * For SMU commands (not for driver commands), you can then read() back | ||
353 | * a reply. The reader will be blocked or not depending on how the device | ||
354 | * file is opened. poll() isn't implemented yet. The reply will consist | ||
355 | * of a header as well, followed by the reply data if any. You should | ||
356 | * always provide a buffer large enough for the maximum reply data, I | ||
357 | * recommand one page. | ||
358 | * | ||
359 | * It is illegal to send SMU commands through a file descriptor configured | ||
360 | * for events reception | ||
361 | * | ||
362 | */ | ||
363 | struct smu_user_cmd_hdr | ||
364 | { | ||
365 | __u32 cmdtype; | ||
366 | #define SMU_CMDTYPE_SMU 0 /* SMU command */ | ||
367 | #define SMU_CMDTYPE_WANTS_EVENTS 1 /* switch fd to events mode */ | ||
368 | |||
369 | __u8 cmd; /* SMU command byte */ | ||
370 | __u32 data_len; /* Lenght of data following */ | ||
371 | }; | ||
372 | |||
373 | struct smu_user_reply_hdr | ||
374 | { | ||
375 | __u32 status; /* Command status */ | ||
376 | __u32 reply_len; /* Lenght of data follwing */ | ||
377 | }; | ||
378 | |||
379 | #endif /* _SMU_H */ | ||
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h index ed06170e0edd..616d02b57ea9 100644 --- a/include/asm-um/pgtable.h +++ b/include/asm-um/pgtable.h | |||
@@ -346,7 +346,6 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval) | |||
346 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 346 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
347 | { | 347 | { |
348 | pte_set_val(pte, (pte_val(pte) & _PAGE_CHG_MASK), newprot); | 348 | pte_set_val(pte, (pte_val(pte) & _PAGE_CHG_MASK), newprot); |
349 | if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte)); | ||
350 | return pte; | 349 | return pte; |
351 | } | 350 | } |
352 | 351 | ||
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h index 24f86f0e43cf..12b5732dc6e5 100644 --- a/include/asm-xtensa/atomic.h +++ b/include/asm-xtensa/atomic.h | |||
@@ -22,7 +22,7 @@ typedef struct { volatile int counter; } atomic_t; | |||
22 | #include <asm/processor.h> | 22 | #include <asm/processor.h> |
23 | #include <asm/system.h> | 23 | #include <asm/system.h> |
24 | 24 | ||
25 | #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) | 25 | #define ATOMIC_INIT(i) { (i) } |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * This Xtensa implementation assumes that the right mechanism | 28 | * This Xtensa implementation assumes that the right mechanism |
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h index d395ef226c32..e76ee889e21d 100644 --- a/include/asm-xtensa/bitops.h +++ b/include/asm-xtensa/bitops.h | |||
@@ -174,7 +174,7 @@ static __inline__ int test_bit(int nr, const volatile void *addr) | |||
174 | return 1UL & (((const volatile unsigned int *)addr)[nr>>5] >> (nr&31)); | 174 | return 1UL & (((const volatile unsigned int *)addr)[nr>>5] >> (nr&31)); |
175 | } | 175 | } |
176 | 176 | ||
177 | #if XCHAL_HAVE_NSAU | 177 | #if XCHAL_HAVE_NSA |
178 | 178 | ||
179 | static __inline__ int __cntlz (unsigned long x) | 179 | static __inline__ int __cntlz (unsigned long x) |
180 | { | 180 | { |
diff --git a/include/asm-xtensa/hardirq.h b/include/asm-xtensa/hardirq.h index e07c76c36b95..aa9c1adf68d7 100644 --- a/include/asm-xtensa/hardirq.h +++ b/include/asm-xtensa/hardirq.h | |||
@@ -23,6 +23,7 @@ typedef struct { | |||
23 | unsigned int __nmi_count; /* arch dependent */ | 23 | unsigned int __nmi_count; /* arch dependent */ |
24 | } ____cacheline_aligned irq_cpustat_t; | 24 | } ____cacheline_aligned irq_cpustat_t; |
25 | 25 | ||
26 | void ack_bad_irq(unsigned int irq); | ||
26 | #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ | 27 | #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ |
27 | 28 | ||
28 | #endif /* _XTENSA_HARDIRQ_H */ | 29 | #endif /* _XTENSA_HARDIRQ_H */ |
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h index db740b8bc6f0..09e89ab3eb61 100644 --- a/include/asm-xtensa/semaphore.h +++ b/include/asm-xtensa/semaphore.h | |||
@@ -20,28 +20,19 @@ struct semaphore { | |||
20 | atomic_t count; | 20 | atomic_t count; |
21 | int sleepers; | 21 | int sleepers; |
22 | wait_queue_head_t wait; | 22 | wait_queue_head_t wait; |
23 | #if WAITQUEUE_DEBUG | ||
24 | long __magic; | ||
25 | #endif | ||
26 | }; | 23 | }; |
27 | 24 | ||
28 | #if WAITQUEUE_DEBUG | 25 | #define __SEMAPHORE_INITIALIZER(name,n) \ |
29 | # define __SEM_DEBUG_INIT(name) \ | 26 | { \ |
30 | , (int)&(name).__magic | 27 | .count = ATOMIC_INIT(n), \ |
31 | #else | 28 | .sleepers = 0, \ |
32 | # define __SEM_DEBUG_INIT(name) | 29 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ |
33 | #endif | 30 | } |
34 | |||
35 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
36 | { ATOMIC_INIT(count), \ | ||
37 | 0, \ | ||
38 | __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
39 | __SEM_DEBUG_INIT(name) } | ||
40 | 31 | ||
41 | #define __MUTEX_INITIALIZER(name) \ | 32 | #define __MUTEX_INITIALIZER(name) \ |
42 | __SEMAPHORE_INITIALIZER(name, 1) | 33 | __SEMAPHORE_INITIALIZER(name, 1) |
43 | 34 | ||
44 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | 35 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ |
45 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | 36 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) |
46 | 37 | ||
47 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | 38 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) |
@@ -49,17 +40,8 @@ struct semaphore { | |||
49 | 40 | ||
50 | static inline void sema_init (struct semaphore *sem, int val) | 41 | static inline void sema_init (struct semaphore *sem, int val) |
51 | { | 42 | { |
52 | /* | ||
53 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
54 | * | ||
55 | * i'd rather use the more flexible initialization above, but sadly | ||
56 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. | ||
57 | */ | ||
58 | atomic_set(&sem->count, val); | 43 | atomic_set(&sem->count, val); |
59 | init_waitqueue_head(&sem->wait); | 44 | init_waitqueue_head(&sem->wait); |
60 | #if WAITQUEUE_DEBUG | ||
61 | sem->__magic = (int)&sem->__magic; | ||
62 | #endif | ||
63 | } | 45 | } |
64 | 46 | ||
65 | static inline void init_MUTEX (struct semaphore *sem) | 47 | static inline void init_MUTEX (struct semaphore *sem) |
@@ -81,9 +63,7 @@ extern spinlock_t semaphore_wake_lock; | |||
81 | 63 | ||
82 | static inline void down(struct semaphore * sem) | 64 | static inline void down(struct semaphore * sem) |
83 | { | 65 | { |
84 | #if WAITQUEUE_DEBUG | 66 | might_sleep(); |
85 | CHECK_MAGIC(sem->__magic); | ||
86 | #endif | ||
87 | 67 | ||
88 | if (atomic_sub_return(1, &sem->count) < 0) | 68 | if (atomic_sub_return(1, &sem->count) < 0) |
89 | __down(sem); | 69 | __down(sem); |
@@ -92,9 +72,8 @@ static inline void down(struct semaphore * sem) | |||
92 | static inline int down_interruptible(struct semaphore * sem) | 72 | static inline int down_interruptible(struct semaphore * sem) |
93 | { | 73 | { |
94 | int ret = 0; | 74 | int ret = 0; |
95 | #if WAITQUEUE_DEBUG | 75 | |
96 | CHECK_MAGIC(sem->__magic); | 76 | might_sleep(); |
97 | #endif | ||
98 | 77 | ||
99 | if (atomic_sub_return(1, &sem->count) < 0) | 78 | if (atomic_sub_return(1, &sem->count) < 0) |
100 | ret = __down_interruptible(sem); | 79 | ret = __down_interruptible(sem); |
@@ -104,9 +83,6 @@ static inline int down_interruptible(struct semaphore * sem) | |||
104 | static inline int down_trylock(struct semaphore * sem) | 83 | static inline int down_trylock(struct semaphore * sem) |
105 | { | 84 | { |
106 | int ret = 0; | 85 | int ret = 0; |
107 | #if WAITQUEUE_DEBUG | ||
108 | CHECK_MAGIC(sem->__magic); | ||
109 | #endif | ||
110 | 86 | ||
111 | if (atomic_sub_return(1, &sem->count) < 0) | 87 | if (atomic_sub_return(1, &sem->count) < 0) |
112 | ret = __down_trylock(sem); | 88 | ret = __down_trylock(sem); |
@@ -119,9 +95,6 @@ static inline int down_trylock(struct semaphore * sem) | |||
119 | */ | 95 | */ |
120 | static inline void up(struct semaphore * sem) | 96 | static inline void up(struct semaphore * sem) |
121 | { | 97 | { |
122 | #if WAITQUEUE_DEBUG | ||
123 | CHECK_MAGIC(sem->__magic); | ||
124 | #endif | ||
125 | if (atomic_add_return(1, &sem->count) <= 0) | 98 | if (atomic_add_return(1, &sem->count) <= 0) |
126 | __up(sem); | 99 | __up(sem); |
127 | } | 100 | } |
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h index f09393232e5e..9284867f1cb9 100644 --- a/include/asm-xtensa/system.h +++ b/include/asm-xtensa/system.h | |||
@@ -189,20 +189,6 @@ static inline unsigned long xchg_u32(volatile int * m, unsigned long val) | |||
189 | 189 | ||
190 | #define tas(ptr) (xchg((ptr),1)) | 190 | #define tas(ptr) (xchg((ptr),1)) |
191 | 191 | ||
192 | #if ( __XCC__ == 1 ) | ||
193 | |||
194 | /* xt-xcc processes __inline__ differently than xt-gcc and decides to | ||
195 | * insert an out-of-line copy of function __xchg. This presents the | ||
196 | * unresolved symbol at link time of __xchg_called_with_bad_pointer, | ||
197 | * even though such a function would never be called at run-time. | ||
198 | * xt-gcc always inlines __xchg, and optimizes away the undefined | ||
199 | * bad_pointer function. | ||
200 | */ | ||
201 | |||
202 | #define xchg(ptr,x) xchg_u32(ptr,x) | ||
203 | |||
204 | #else /* assume xt-gcc */ | ||
205 | |||
206 | #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | 192 | #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) |
207 | 193 | ||
208 | /* | 194 | /* |
@@ -224,8 +210,6 @@ __xchg(unsigned long x, volatile void * ptr, int size) | |||
224 | return x; | 210 | return x; |
225 | } | 211 | } |
226 | 212 | ||
227 | #endif | ||
228 | |||
229 | extern void set_except_vector(int n, void *addr); | 213 | extern void set_except_vector(int n, void *addr); |
230 | 214 | ||
231 | static inline void spill_registers(void) | 215 | static inline void spill_registers(void) |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index bace72a76cc4..4ced38736813 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h | |||
@@ -332,11 +332,28 @@ extern void need_ip_conntrack(void); | |||
332 | extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, | 332 | extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, |
333 | const struct ip_conntrack_tuple *orig); | 333 | const struct ip_conntrack_tuple *orig); |
334 | 334 | ||
335 | extern void __ip_ct_refresh_acct(struct ip_conntrack *ct, | ||
336 | enum ip_conntrack_info ctinfo, | ||
337 | const struct sk_buff *skb, | ||
338 | unsigned long extra_jiffies, | ||
339 | int do_acct); | ||
340 | |||
341 | /* Refresh conntrack for this many jiffies and do accounting */ | ||
342 | static inline void ip_ct_refresh_acct(struct ip_conntrack *ct, | ||
343 | enum ip_conntrack_info ctinfo, | ||
344 | const struct sk_buff *skb, | ||
345 | unsigned long extra_jiffies) | ||
346 | { | ||
347 | __ip_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1); | ||
348 | } | ||
349 | |||
335 | /* Refresh conntrack for this many jiffies */ | 350 | /* Refresh conntrack for this many jiffies */ |
336 | extern void ip_ct_refresh_acct(struct ip_conntrack *ct, | 351 | static inline void ip_ct_refresh(struct ip_conntrack *ct, |
337 | enum ip_conntrack_info ctinfo, | 352 | const struct sk_buff *skb, |
338 | const struct sk_buff *skb, | 353 | unsigned long extra_jiffies) |
339 | unsigned long extra_jiffies); | 354 | { |
355 | __ip_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0); | ||
356 | } | ||
340 | 357 | ||
341 | /* These are for NAT. Icky. */ | 358 | /* These are for NAT. Icky. */ |
342 | /* Update TCP window tracking data when NAT mangles the packet */ | 359 | /* Update TCP window tracking data when NAT mangles the packet */ |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_pptp.h b/include/linux/netfilter_ipv4/ip_conntrack_pptp.h index 389e3851d52f..816144c75de0 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_pptp.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_pptp.h | |||
@@ -60,8 +60,8 @@ struct ip_ct_pptp_expect { | |||
60 | 60 | ||
61 | struct pptp_pkt_hdr { | 61 | struct pptp_pkt_hdr { |
62 | __u16 packetLength; | 62 | __u16 packetLength; |
63 | __u16 packetType; | 63 | __be16 packetType; |
64 | __u32 magicCookie; | 64 | __be32 magicCookie; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | /* PptpControlMessageType values */ | 67 | /* PptpControlMessageType values */ |
@@ -93,7 +93,7 @@ struct pptp_pkt_hdr { | |||
93 | #define PPTP_REMOVE_DEVICE_ERROR 6 | 93 | #define PPTP_REMOVE_DEVICE_ERROR 6 |
94 | 94 | ||
95 | struct PptpControlHeader { | 95 | struct PptpControlHeader { |
96 | __u16 messageType; | 96 | __be16 messageType; |
97 | __u16 reserved; | 97 | __u16 reserved; |
98 | }; | 98 | }; |
99 | 99 | ||
@@ -106,13 +106,13 @@ struct PptpControlHeader { | |||
106 | #define PPTP_BEARER_CAP_DIGITAL 0x2 | 106 | #define PPTP_BEARER_CAP_DIGITAL 0x2 |
107 | 107 | ||
108 | struct PptpStartSessionRequest { | 108 | struct PptpStartSessionRequest { |
109 | __u16 protocolVersion; | 109 | __be16 protocolVersion; |
110 | __u8 reserved1; | 110 | __u8 reserved1; |
111 | __u8 reserved2; | 111 | __u8 reserved2; |
112 | __u32 framingCapability; | 112 | __be32 framingCapability; |
113 | __u32 bearerCapability; | 113 | __be32 bearerCapability; |
114 | __u16 maxChannels; | 114 | __be16 maxChannels; |
115 | __u16 firmwareRevision; | 115 | __be16 firmwareRevision; |
116 | __u8 hostName[64]; | 116 | __u8 hostName[64]; |
117 | __u8 vendorString[64]; | 117 | __u8 vendorString[64]; |
118 | }; | 118 | }; |
@@ -125,13 +125,13 @@ struct PptpStartSessionRequest { | |||
125 | #define PPTP_START_UNKNOWN_PROTOCOL 5 | 125 | #define PPTP_START_UNKNOWN_PROTOCOL 5 |
126 | 126 | ||
127 | struct PptpStartSessionReply { | 127 | struct PptpStartSessionReply { |
128 | __u16 protocolVersion; | 128 | __be16 protocolVersion; |
129 | __u8 resultCode; | 129 | __u8 resultCode; |
130 | __u8 generalErrorCode; | 130 | __u8 generalErrorCode; |
131 | __u32 framingCapability; | 131 | __be32 framingCapability; |
132 | __u32 bearerCapability; | 132 | __be32 bearerCapability; |
133 | __u16 maxChannels; | 133 | __be16 maxChannels; |
134 | __u16 firmwareRevision; | 134 | __be16 firmwareRevision; |
135 | __u8 hostName[64]; | 135 | __u8 hostName[64]; |
136 | __u8 vendorString[64]; | 136 | __u8 vendorString[64]; |
137 | }; | 137 | }; |
@@ -155,7 +155,7 @@ struct PptpStopSessionReply { | |||
155 | }; | 155 | }; |
156 | 156 | ||
157 | struct PptpEchoRequest { | 157 | struct PptpEchoRequest { |
158 | __u32 identNumber; | 158 | __be32 identNumber; |
159 | }; | 159 | }; |
160 | 160 | ||
161 | /* PptpEchoReplyResultCode */ | 161 | /* PptpEchoReplyResultCode */ |
@@ -163,7 +163,7 @@ struct PptpEchoRequest { | |||
163 | #define PPTP_ECHO_GENERAL_ERROR 2 | 163 | #define PPTP_ECHO_GENERAL_ERROR 2 |
164 | 164 | ||
165 | struct PptpEchoReply { | 165 | struct PptpEchoReply { |
166 | __u32 identNumber; | 166 | __be32 identNumber; |
167 | __u8 resultCode; | 167 | __u8 resultCode; |
168 | __u8 generalErrorCode; | 168 | __u8 generalErrorCode; |
169 | __u16 reserved; | 169 | __u16 reserved; |
@@ -180,16 +180,16 @@ struct PptpEchoReply { | |||
180 | #define PPTP_DONT_CARE_BEARER_TYPE 3 | 180 | #define PPTP_DONT_CARE_BEARER_TYPE 3 |
181 | 181 | ||
182 | struct PptpOutCallRequest { | 182 | struct PptpOutCallRequest { |
183 | __u16 callID; | 183 | __be16 callID; |
184 | __u16 callSerialNumber; | 184 | __be16 callSerialNumber; |
185 | __u32 minBPS; | 185 | __be32 minBPS; |
186 | __u32 maxBPS; | 186 | __be32 maxBPS; |
187 | __u32 bearerType; | 187 | __be32 bearerType; |
188 | __u32 framingType; | 188 | __be32 framingType; |
189 | __u16 packetWindow; | 189 | __be16 packetWindow; |
190 | __u16 packetProcDelay; | 190 | __be16 packetProcDelay; |
191 | __u16 reserved1; | 191 | __u16 reserved1; |
192 | __u16 phoneNumberLength; | 192 | __be16 phoneNumberLength; |
193 | __u16 reserved2; | 193 | __u16 reserved2; |
194 | __u8 phoneNumber[64]; | 194 | __u8 phoneNumber[64]; |
195 | __u8 subAddress[64]; | 195 | __u8 subAddress[64]; |
@@ -205,24 +205,24 @@ struct PptpOutCallRequest { | |||
205 | #define PPTP_OUTCALL_DONT_ACCEPT 7 | 205 | #define PPTP_OUTCALL_DONT_ACCEPT 7 |
206 | 206 | ||
207 | struct PptpOutCallReply { | 207 | struct PptpOutCallReply { |
208 | __u16 callID; | 208 | __be16 callID; |
209 | __u16 peersCallID; | 209 | __be16 peersCallID; |
210 | __u8 resultCode; | 210 | __u8 resultCode; |
211 | __u8 generalErrorCode; | 211 | __u8 generalErrorCode; |
212 | __u16 causeCode; | 212 | __be16 causeCode; |
213 | __u32 connectSpeed; | 213 | __be32 connectSpeed; |
214 | __u16 packetWindow; | 214 | __be16 packetWindow; |
215 | __u16 packetProcDelay; | 215 | __be16 packetProcDelay; |
216 | __u32 physChannelID; | 216 | __be32 physChannelID; |
217 | }; | 217 | }; |
218 | 218 | ||
219 | struct PptpInCallRequest { | 219 | struct PptpInCallRequest { |
220 | __u16 callID; | 220 | __be16 callID; |
221 | __u16 callSerialNumber; | 221 | __be16 callSerialNumber; |
222 | __u32 callBearerType; | 222 | __be32 callBearerType; |
223 | __u32 physChannelID; | 223 | __be32 physChannelID; |
224 | __u16 dialedNumberLength; | 224 | __be16 dialedNumberLength; |
225 | __u16 dialingNumberLength; | 225 | __be16 dialingNumberLength; |
226 | __u8 dialedNumber[64]; | 226 | __u8 dialedNumber[64]; |
227 | __u8 dialingNumber[64]; | 227 | __u8 dialingNumber[64]; |
228 | __u8 subAddress[64]; | 228 | __u8 subAddress[64]; |
@@ -234,61 +234,54 @@ struct PptpInCallRequest { | |||
234 | #define PPTP_INCALL_DONT_ACCEPT 3 | 234 | #define PPTP_INCALL_DONT_ACCEPT 3 |
235 | 235 | ||
236 | struct PptpInCallReply { | 236 | struct PptpInCallReply { |
237 | __u16 callID; | 237 | __be16 callID; |
238 | __u16 peersCallID; | 238 | __be16 peersCallID; |
239 | __u8 resultCode; | 239 | __u8 resultCode; |
240 | __u8 generalErrorCode; | 240 | __u8 generalErrorCode; |
241 | __u16 packetWindow; | 241 | __be16 packetWindow; |
242 | __u16 packetProcDelay; | 242 | __be16 packetProcDelay; |
243 | __u16 reserved; | 243 | __u16 reserved; |
244 | }; | 244 | }; |
245 | 245 | ||
246 | struct PptpInCallConnected { | 246 | struct PptpInCallConnected { |
247 | __u16 peersCallID; | 247 | __be16 peersCallID; |
248 | __u16 reserved; | 248 | __u16 reserved; |
249 | __u32 connectSpeed; | 249 | __be32 connectSpeed; |
250 | __u16 packetWindow; | 250 | __be16 packetWindow; |
251 | __u16 packetProcDelay; | 251 | __be16 packetProcDelay; |
252 | __u32 callFramingType; | 252 | __be32 callFramingType; |
253 | }; | 253 | }; |
254 | 254 | ||
255 | struct PptpClearCallRequest { | 255 | struct PptpClearCallRequest { |
256 | __u16 callID; | 256 | __be16 callID; |
257 | __u16 reserved; | 257 | __u16 reserved; |
258 | }; | 258 | }; |
259 | 259 | ||
260 | struct PptpCallDisconnectNotify { | 260 | struct PptpCallDisconnectNotify { |
261 | __u16 callID; | 261 | __be16 callID; |
262 | __u8 resultCode; | 262 | __u8 resultCode; |
263 | __u8 generalErrorCode; | 263 | __u8 generalErrorCode; |
264 | __u16 causeCode; | 264 | __be16 causeCode; |
265 | __u16 reserved; | 265 | __u16 reserved; |
266 | __u8 callStatistics[128]; | 266 | __u8 callStatistics[128]; |
267 | }; | 267 | }; |
268 | 268 | ||
269 | struct PptpWanErrorNotify { | 269 | struct PptpWanErrorNotify { |
270 | __u16 peersCallID; | 270 | __be16 peersCallID; |
271 | __u16 reserved; | 271 | __u16 reserved; |
272 | __u32 crcErrors; | 272 | __be32 crcErrors; |
273 | __u32 framingErrors; | 273 | __be32 framingErrors; |
274 | __u32 hardwareOverRuns; | 274 | __be32 hardwareOverRuns; |
275 | __u32 bufferOverRuns; | 275 | __be32 bufferOverRuns; |
276 | __u32 timeoutErrors; | 276 | __be32 timeoutErrors; |
277 | __u32 alignmentErrors; | 277 | __be32 alignmentErrors; |
278 | }; | 278 | }; |
279 | 279 | ||
280 | struct PptpSetLinkInfo { | 280 | struct PptpSetLinkInfo { |
281 | __u16 peersCallID; | 281 | __be16 peersCallID; |
282 | __u16 reserved; | 282 | __u16 reserved; |
283 | __u32 sendAccm; | 283 | __be32 sendAccm; |
284 | __u32 recvAccm; | 284 | __be32 recvAccm; |
285 | }; | ||
286 | |||
287 | |||
288 | struct pptp_priv_data { | ||
289 | __u16 call_id; | ||
290 | __u16 mcall_id; | ||
291 | __u16 pcall_id; | ||
292 | }; | 285 | }; |
293 | 286 | ||
294 | union pptp_ctrl_union { | 287 | union pptp_ctrl_union { |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h index 14dc0f7b6556..20e43f018b7c 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h | |||
@@ -17,7 +17,7 @@ union ip_conntrack_manip_proto | |||
17 | u_int16_t all; | 17 | u_int16_t all; |
18 | 18 | ||
19 | struct { | 19 | struct { |
20 | u_int16_t port; | 20 | __be16 port; |
21 | } tcp; | 21 | } tcp; |
22 | struct { | 22 | struct { |
23 | u_int16_t port; | 23 | u_int16_t port; |
@@ -29,7 +29,7 @@ union ip_conntrack_manip_proto | |||
29 | u_int16_t port; | 29 | u_int16_t port; |
30 | } sctp; | 30 | } sctp; |
31 | struct { | 31 | struct { |
32 | u_int16_t key; /* key is 32bit, pptp only uses 16 */ | 32 | __be16 key; /* key is 32bit, pptp only uses 16 */ |
33 | } gre; | 33 | } gre; |
34 | }; | 34 | }; |
35 | 35 | ||
@@ -65,7 +65,7 @@ struct ip_conntrack_tuple | |||
65 | u_int16_t port; | 65 | u_int16_t port; |
66 | } sctp; | 66 | } sctp; |
67 | struct { | 67 | struct { |
68 | u_int16_t key; /* key is 32bit, | 68 | __be16 key; /* key is 32bit, |
69 | * pptp only uses 16 */ | 69 | * pptp only uses 16 */ |
70 | } gre; | 70 | } gre; |
71 | } u; | 71 | } u; |
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 3b3266ff1a95..7ab2cdb83ef0 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h | |||
@@ -59,6 +59,10 @@ extern void machine_crash_shutdown(struct pt_regs *); | |||
59 | * Architecture independent implemenations of sys_reboot commands. | 59 | * Architecture independent implemenations of sys_reboot commands. |
60 | */ | 60 | */ |
61 | 61 | ||
62 | extern void kernel_restart_prepare(char *cmd); | ||
63 | extern void kernel_halt_prepare(void); | ||
64 | extern void kernel_power_off_prepare(void); | ||
65 | |||
62 | extern void kernel_restart(char *cmd); | 66 | extern void kernel_restart(char *cmd); |
63 | extern void kernel_halt(void); | 67 | extern void kernel_halt(void); |
64 | extern void kernel_power_off(void); | 68 | extern void kernel_power_off(void); |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 396c7873e804..46a5e5acff97 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -29,7 +29,7 @@ config PM_DEBUG | |||
29 | 29 | ||
30 | config SOFTWARE_SUSPEND | 30 | config SOFTWARE_SUSPEND |
31 | bool "Software Suspend" | 31 | bool "Software Suspend" |
32 | depends on PM && SWAP && (X86 || ((FVR || PPC32) && !SMP)) | 32 | depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FVR || PPC32) && !SMP) |
33 | ---help--- | 33 | ---help--- |
34 | Enable the possibility of suspending the machine. | 34 | Enable the possibility of suspending the machine. |
35 | It doesn't need APM. | 35 | It doesn't need APM. |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 2d8bf054d036..761956e813f5 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -17,12 +17,12 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
20 | #include <linux/pm.h> | ||
20 | 21 | ||
21 | #include "power.h" | 22 | #include "power.h" |
22 | 23 | ||
23 | 24 | ||
24 | extern suspend_disk_method_t pm_disk_mode; | 25 | extern suspend_disk_method_t pm_disk_mode; |
25 | extern struct pm_ops * pm_ops; | ||
26 | 26 | ||
27 | extern int swsusp_suspend(void); | 27 | extern int swsusp_suspend(void); |
28 | extern int swsusp_write(void); | 28 | extern int swsusp_write(void); |
@@ -49,13 +49,11 @@ dev_t swsusp_resume_device; | |||
49 | 49 | ||
50 | static void power_down(suspend_disk_method_t mode) | 50 | static void power_down(suspend_disk_method_t mode) |
51 | { | 51 | { |
52 | unsigned long flags; | ||
53 | int error = 0; | 52 | int error = 0; |
54 | 53 | ||
55 | local_irq_save(flags); | ||
56 | switch(mode) { | 54 | switch(mode) { |
57 | case PM_DISK_PLATFORM: | 55 | case PM_DISK_PLATFORM: |
58 | device_shutdown(); | 56 | kernel_power_off_prepare(); |
59 | error = pm_ops->enter(PM_SUSPEND_DISK); | 57 | error = pm_ops->enter(PM_SUSPEND_DISK); |
60 | break; | 58 | break; |
61 | case PM_DISK_SHUTDOWN: | 59 | case PM_DISK_SHUTDOWN: |
diff --git a/kernel/power/power.h b/kernel/power/power.h index cd6a3493cc0d..9c9167d910dd 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #include <linux/suspend.h> | 1 | #include <linux/suspend.h> |
2 | #include <linux/utsname.h> | 2 | #include <linux/utsname.h> |
3 | 3 | ||
4 | /* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but | 4 | /* With SUSPEND_CONSOLE defined suspend looks *really* cool, but |
5 | we probably do not take enough locks for switching consoles, etc, | 5 | we probably do not take enough locks for switching consoles, etc, |
6 | so bad things might happen. | 6 | so bad things might happen. |
7 | */ | 7 | */ |
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index d967e875ee82..1cc9ff25e479 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
@@ -363,7 +363,7 @@ static void lock_swapdevices(void) | |||
363 | } | 363 | } |
364 | 364 | ||
365 | /** | 365 | /** |
366 | * write_swap_page - Write one page to a fresh swap location. | 366 | * write_page - Write one page to a fresh swap location. |
367 | * @addr: Address we're writing. | 367 | * @addr: Address we're writing. |
368 | * @loc: Place to store the entry we used. | 368 | * @loc: Place to store the entry we used. |
369 | * | 369 | * |
@@ -863,6 +863,9 @@ static int alloc_image_pages(void) | |||
863 | return 0; | 863 | return 0; |
864 | } | 864 | } |
865 | 865 | ||
866 | /* Free pages we allocated for suspend. Suspend pages are alocated | ||
867 | * before atomic copy, so we need to free them after resume. | ||
868 | */ | ||
866 | void swsusp_free(void) | 869 | void swsusp_free(void) |
867 | { | 870 | { |
868 | BUG_ON(PageNosave(virt_to_page(pagedir_save))); | 871 | BUG_ON(PageNosave(virt_to_page(pagedir_save))); |
@@ -918,6 +921,7 @@ static int swsusp_alloc(void) | |||
918 | 921 | ||
919 | pagedir_nosave = NULL; | 922 | pagedir_nosave = NULL; |
920 | nr_copy_pages = calc_nr(nr_copy_pages); | 923 | nr_copy_pages = calc_nr(nr_copy_pages); |
924 | nr_copy_pages_check = nr_copy_pages; | ||
921 | 925 | ||
922 | pr_debug("suspend: (pages needed: %d + %d free: %d)\n", | 926 | pr_debug("suspend: (pages needed: %d + %d free: %d)\n", |
923 | nr_copy_pages, PAGES_FOR_IO, nr_free_pages()); | 927 | nr_copy_pages, PAGES_FOR_IO, nr_free_pages()); |
@@ -940,7 +944,6 @@ static int swsusp_alloc(void) | |||
940 | return error; | 944 | return error; |
941 | } | 945 | } |
942 | 946 | ||
943 | nr_copy_pages_check = nr_copy_pages; | ||
944 | return 0; | 947 | return 0; |
945 | } | 948 | } |
946 | 949 | ||
@@ -1213,8 +1216,9 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist) | |||
1213 | free_pagedir(pblist); | 1216 | free_pagedir(pblist); |
1214 | free_eaten_memory(); | 1217 | free_eaten_memory(); |
1215 | pblist = NULL; | 1218 | pblist = NULL; |
1216 | } | 1219 | /* Is this even worth handling? It should never ever happen, and we |
1217 | else | 1220 | have just lost user's state, anyway... */ |
1221 | } else | ||
1218 | printk("swsusp: Relocated %d pages\n", rel); | 1222 | printk("swsusp: Relocated %d pages\n", rel); |
1219 | 1223 | ||
1220 | return pblist; | 1224 | return pblist; |
diff --git a/kernel/signal.c b/kernel/signal.c index b92c3c9f8b9a..5a274705ba19 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -936,34 +936,31 @@ force_sig_specific(int sig, struct task_struct *t) | |||
936 | * as soon as they're available, so putting the signal on the shared queue | 936 | * as soon as they're available, so putting the signal on the shared queue |
937 | * will be equivalent to sending it to one such thread. | 937 | * will be equivalent to sending it to one such thread. |
938 | */ | 938 | */ |
939 | #define wants_signal(sig, p, mask) \ | 939 | static inline int wants_signal(int sig, struct task_struct *p) |
940 | (!sigismember(&(p)->blocked, sig) \ | 940 | { |
941 | && !((p)->state & mask) \ | 941 | if (sigismember(&p->blocked, sig)) |
942 | && !((p)->flags & PF_EXITING) \ | 942 | return 0; |
943 | && (task_curr(p) || !signal_pending(p))) | 943 | if (p->flags & PF_EXITING) |
944 | 944 | return 0; | |
945 | if (sig == SIGKILL) | ||
946 | return 1; | ||
947 | if (p->state & (TASK_STOPPED | TASK_TRACED)) | ||
948 | return 0; | ||
949 | return task_curr(p) || !signal_pending(p); | ||
950 | } | ||
945 | 951 | ||
946 | static void | 952 | static void |
947 | __group_complete_signal(int sig, struct task_struct *p) | 953 | __group_complete_signal(int sig, struct task_struct *p) |
948 | { | 954 | { |
949 | unsigned int mask; | ||
950 | struct task_struct *t; | 955 | struct task_struct *t; |
951 | 956 | ||
952 | /* | 957 | /* |
953 | * Don't bother traced and stopped tasks (but | ||
954 | * SIGKILL will punch through that). | ||
955 | */ | ||
956 | mask = TASK_STOPPED | TASK_TRACED; | ||
957 | if (sig == SIGKILL) | ||
958 | mask = 0; | ||
959 | |||
960 | /* | ||
961 | * Now find a thread we can wake up to take the signal off the queue. | 958 | * Now find a thread we can wake up to take the signal off the queue. |
962 | * | 959 | * |
963 | * If the main thread wants the signal, it gets first crack. | 960 | * If the main thread wants the signal, it gets first crack. |
964 | * Probably the least surprising to the average bear. | 961 | * Probably the least surprising to the average bear. |
965 | */ | 962 | */ |
966 | if (wants_signal(sig, p, mask)) | 963 | if (wants_signal(sig, p)) |
967 | t = p; | 964 | t = p; |
968 | else if (thread_group_empty(p)) | 965 | else if (thread_group_empty(p)) |
969 | /* | 966 | /* |
@@ -981,7 +978,7 @@ __group_complete_signal(int sig, struct task_struct *p) | |||
981 | t = p->signal->curr_target = p; | 978 | t = p->signal->curr_target = p; |
982 | BUG_ON(t->tgid != p->tgid); | 979 | BUG_ON(t->tgid != p->tgid); |
983 | 980 | ||
984 | while (!wants_signal(sig, t, mask)) { | 981 | while (!wants_signal(sig, t)) { |
985 | t = next_thread(t); | 982 | t = next_thread(t); |
986 | if (t == p->signal->curr_target) | 983 | if (t == p->signal->curr_target) |
987 | /* | 984 | /* |
diff --git a/kernel/sys.c b/kernel/sys.c index f723522e6986..2fa1ed18123c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -361,17 +361,35 @@ out_unlock: | |||
361 | return retval; | 361 | return retval; |
362 | } | 362 | } |
363 | 363 | ||
364 | /** | ||
365 | * emergency_restart - reboot the system | ||
366 | * | ||
367 | * Without shutting down any hardware or taking any locks | ||
368 | * reboot the system. This is called when we know we are in | ||
369 | * trouble so this is our best effort to reboot. This is | ||
370 | * safe to call in interrupt context. | ||
371 | */ | ||
364 | void emergency_restart(void) | 372 | void emergency_restart(void) |
365 | { | 373 | { |
366 | machine_emergency_restart(); | 374 | machine_emergency_restart(); |
367 | } | 375 | } |
368 | EXPORT_SYMBOL_GPL(emergency_restart); | 376 | EXPORT_SYMBOL_GPL(emergency_restart); |
369 | 377 | ||
370 | void kernel_restart(char *cmd) | 378 | /** |
379 | * kernel_restart - reboot the system | ||
380 | * | ||
381 | * Shutdown everything and perform a clean reboot. | ||
382 | * This is not safe to call in interrupt context. | ||
383 | */ | ||
384 | void kernel_restart_prepare(char *cmd) | ||
371 | { | 385 | { |
372 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); | 386 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); |
373 | system_state = SYSTEM_RESTART; | 387 | system_state = SYSTEM_RESTART; |
374 | device_shutdown(); | 388 | device_shutdown(); |
389 | } | ||
390 | void kernel_restart(char *cmd) | ||
391 | { | ||
392 | kernel_restart_prepare(cmd); | ||
375 | if (!cmd) { | 393 | if (!cmd) { |
376 | printk(KERN_EMERG "Restarting system.\n"); | 394 | printk(KERN_EMERG "Restarting system.\n"); |
377 | } else { | 395 | } else { |
@@ -382,6 +400,12 @@ void kernel_restart(char *cmd) | |||
382 | } | 400 | } |
383 | EXPORT_SYMBOL_GPL(kernel_restart); | 401 | EXPORT_SYMBOL_GPL(kernel_restart); |
384 | 402 | ||
403 | /** | ||
404 | * kernel_kexec - reboot the system | ||
405 | * | ||
406 | * Move into place and start executing a preloaded standalone | ||
407 | * executable. If nothing was preloaded return an error. | ||
408 | */ | ||
385 | void kernel_kexec(void) | 409 | void kernel_kexec(void) |
386 | { | 410 | { |
387 | #ifdef CONFIG_KEXEC | 411 | #ifdef CONFIG_KEXEC |
@@ -390,9 +414,7 @@ void kernel_kexec(void) | |||
390 | if (!image) { | 414 | if (!image) { |
391 | return; | 415 | return; |
392 | } | 416 | } |
393 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); | 417 | kernel_restart_prepare(NULL); |
394 | system_state = SYSTEM_RESTART; | ||
395 | device_shutdown(); | ||
396 | printk(KERN_EMERG "Starting new kernel\n"); | 418 | printk(KERN_EMERG "Starting new kernel\n"); |
397 | machine_shutdown(); | 419 | machine_shutdown(); |
398 | machine_kexec(image); | 420 | machine_kexec(image); |
@@ -400,21 +422,39 @@ void kernel_kexec(void) | |||
400 | } | 422 | } |
401 | EXPORT_SYMBOL_GPL(kernel_kexec); | 423 | EXPORT_SYMBOL_GPL(kernel_kexec); |
402 | 424 | ||
403 | void kernel_halt(void) | 425 | /** |
426 | * kernel_halt - halt the system | ||
427 | * | ||
428 | * Shutdown everything and perform a clean system halt. | ||
429 | */ | ||
430 | void kernel_halt_prepare(void) | ||
404 | { | 431 | { |
405 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); | 432 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); |
406 | system_state = SYSTEM_HALT; | 433 | system_state = SYSTEM_HALT; |
407 | device_shutdown(); | 434 | device_shutdown(); |
435 | } | ||
436 | void kernel_halt(void) | ||
437 | { | ||
438 | kernel_halt_prepare(); | ||
408 | printk(KERN_EMERG "System halted.\n"); | 439 | printk(KERN_EMERG "System halted.\n"); |
409 | machine_halt(); | 440 | machine_halt(); |
410 | } | 441 | } |
411 | EXPORT_SYMBOL_GPL(kernel_halt); | 442 | EXPORT_SYMBOL_GPL(kernel_halt); |
412 | 443 | ||
413 | void kernel_power_off(void) | 444 | /** |
445 | * kernel_power_off - power_off the system | ||
446 | * | ||
447 | * Shutdown everything and perform a clean system power_off. | ||
448 | */ | ||
449 | void kernel_power_off_prepare(void) | ||
414 | { | 450 | { |
415 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); | 451 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); |
416 | system_state = SYSTEM_POWER_OFF; | 452 | system_state = SYSTEM_POWER_OFF; |
417 | device_shutdown(); | 453 | device_shutdown(); |
454 | } | ||
455 | void kernel_power_off(void) | ||
456 | { | ||
457 | kernel_power_off_prepare(); | ||
418 | printk(KERN_EMERG "Power down.\n"); | 458 | printk(KERN_EMERG "Power down.\n"); |
419 | machine_power_off(); | 459 | machine_power_off(); |
420 | } | 460 | } |
@@ -308,12 +308,12 @@ struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS]; | |||
308 | #define SIZE_L3 (1 + MAX_NUMNODES) | 308 | #define SIZE_L3 (1 + MAX_NUMNODES) |
309 | 309 | ||
310 | /* | 310 | /* |
311 | * This function may be completely optimized away if | 311 | * This function must be completely optimized away if |
312 | * a constant is passed to it. Mostly the same as | 312 | * a constant is passed to it. Mostly the same as |
313 | * what is in linux/slab.h except it returns an | 313 | * what is in linux/slab.h except it returns an |
314 | * index. | 314 | * index. |
315 | */ | 315 | */ |
316 | static inline int index_of(const size_t size) | 316 | static __always_inline int index_of(const size_t size) |
317 | { | 317 | { |
318 | if (__builtin_constant_p(size)) { | 318 | if (__builtin_constant_p(size)) { |
319 | int i = 0; | 319 | int i = 0; |
@@ -329,7 +329,8 @@ static inline int index_of(const size_t size) | |||
329 | extern void __bad_size(void); | 329 | extern void __bad_size(void); |
330 | __bad_size(); | 330 | __bad_size(); |
331 | } | 331 | } |
332 | } | 332 | } else |
333 | BUG(); | ||
333 | return 0; | 334 | return 0; |
334 | } | 335 | } |
335 | 336 | ||
@@ -639,7 +640,7 @@ static enum { | |||
639 | 640 | ||
640 | static DEFINE_PER_CPU(struct work_struct, reap_work); | 641 | static DEFINE_PER_CPU(struct work_struct, reap_work); |
641 | 642 | ||
642 | static void free_block(kmem_cache_t* cachep, void** objpp, int len); | 643 | static void free_block(kmem_cache_t* cachep, void** objpp, int len, int node); |
643 | static void enable_cpucache (kmem_cache_t *cachep); | 644 | static void enable_cpucache (kmem_cache_t *cachep); |
644 | static void cache_reap (void *unused); | 645 | static void cache_reap (void *unused); |
645 | static int __node_shrink(kmem_cache_t *cachep, int node); | 646 | static int __node_shrink(kmem_cache_t *cachep, int node); |
@@ -804,7 +805,7 @@ static inline void __drain_alien_cache(kmem_cache_t *cachep, struct array_cache | |||
804 | 805 | ||
805 | if (ac->avail) { | 806 | if (ac->avail) { |
806 | spin_lock(&rl3->list_lock); | 807 | spin_lock(&rl3->list_lock); |
807 | free_block(cachep, ac->entry, ac->avail); | 808 | free_block(cachep, ac->entry, ac->avail, node); |
808 | ac->avail = 0; | 809 | ac->avail = 0; |
809 | spin_unlock(&rl3->list_lock); | 810 | spin_unlock(&rl3->list_lock); |
810 | } | 811 | } |
@@ -925,7 +926,7 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
925 | /* Free limit for this kmem_list3 */ | 926 | /* Free limit for this kmem_list3 */ |
926 | l3->free_limit -= cachep->batchcount; | 927 | l3->free_limit -= cachep->batchcount; |
927 | if (nc) | 928 | if (nc) |
928 | free_block(cachep, nc->entry, nc->avail); | 929 | free_block(cachep, nc->entry, nc->avail, node); |
929 | 930 | ||
930 | if (!cpus_empty(mask)) { | 931 | if (!cpus_empty(mask)) { |
931 | spin_unlock(&l3->list_lock); | 932 | spin_unlock(&l3->list_lock); |
@@ -934,7 +935,7 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
934 | 935 | ||
935 | if (l3->shared) { | 936 | if (l3->shared) { |
936 | free_block(cachep, l3->shared->entry, | 937 | free_block(cachep, l3->shared->entry, |
937 | l3->shared->avail); | 938 | l3->shared->avail, node); |
938 | kfree(l3->shared); | 939 | kfree(l3->shared); |
939 | l3->shared = NULL; | 940 | l3->shared = NULL; |
940 | } | 941 | } |
@@ -1882,12 +1883,13 @@ static void do_drain(void *arg) | |||
1882 | { | 1883 | { |
1883 | kmem_cache_t *cachep = (kmem_cache_t*)arg; | 1884 | kmem_cache_t *cachep = (kmem_cache_t*)arg; |
1884 | struct array_cache *ac; | 1885 | struct array_cache *ac; |
1886 | int node = numa_node_id(); | ||
1885 | 1887 | ||
1886 | check_irq_off(); | 1888 | check_irq_off(); |
1887 | ac = ac_data(cachep); | 1889 | ac = ac_data(cachep); |
1888 | spin_lock(&cachep->nodelists[numa_node_id()]->list_lock); | 1890 | spin_lock(&cachep->nodelists[node]->list_lock); |
1889 | free_block(cachep, ac->entry, ac->avail); | 1891 | free_block(cachep, ac->entry, ac->avail, node); |
1890 | spin_unlock(&cachep->nodelists[numa_node_id()]->list_lock); | 1892 | spin_unlock(&cachep->nodelists[node]->list_lock); |
1891 | ac->avail = 0; | 1893 | ac->avail = 0; |
1892 | } | 1894 | } |
1893 | 1895 | ||
@@ -2608,7 +2610,7 @@ done: | |||
2608 | /* | 2610 | /* |
2609 | * Caller needs to acquire correct kmem_list's list_lock | 2611 | * Caller needs to acquire correct kmem_list's list_lock |
2610 | */ | 2612 | */ |
2611 | static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects) | 2613 | static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, int node) |
2612 | { | 2614 | { |
2613 | int i; | 2615 | int i; |
2614 | struct kmem_list3 *l3; | 2616 | struct kmem_list3 *l3; |
@@ -2617,14 +2619,12 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects) | |||
2617 | void *objp = objpp[i]; | 2619 | void *objp = objpp[i]; |
2618 | struct slab *slabp; | 2620 | struct slab *slabp; |
2619 | unsigned int objnr; | 2621 | unsigned int objnr; |
2620 | int nodeid = 0; | ||
2621 | 2622 | ||
2622 | slabp = GET_PAGE_SLAB(virt_to_page(objp)); | 2623 | slabp = GET_PAGE_SLAB(virt_to_page(objp)); |
2623 | nodeid = slabp->nodeid; | 2624 | l3 = cachep->nodelists[node]; |
2624 | l3 = cachep->nodelists[nodeid]; | ||
2625 | list_del(&slabp->list); | 2625 | list_del(&slabp->list); |
2626 | objnr = (objp - slabp->s_mem) / cachep->objsize; | 2626 | objnr = (objp - slabp->s_mem) / cachep->objsize; |
2627 | check_spinlock_acquired_node(cachep, nodeid); | 2627 | check_spinlock_acquired_node(cachep, node); |
2628 | check_slabp(cachep, slabp); | 2628 | check_slabp(cachep, slabp); |
2629 | 2629 | ||
2630 | 2630 | ||
@@ -2664,13 +2664,14 @@ static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac) | |||
2664 | { | 2664 | { |
2665 | int batchcount; | 2665 | int batchcount; |
2666 | struct kmem_list3 *l3; | 2666 | struct kmem_list3 *l3; |
2667 | int node = numa_node_id(); | ||
2667 | 2668 | ||
2668 | batchcount = ac->batchcount; | 2669 | batchcount = ac->batchcount; |
2669 | #if DEBUG | 2670 | #if DEBUG |
2670 | BUG_ON(!batchcount || batchcount > ac->avail); | 2671 | BUG_ON(!batchcount || batchcount > ac->avail); |
2671 | #endif | 2672 | #endif |
2672 | check_irq_off(); | 2673 | check_irq_off(); |
2673 | l3 = cachep->nodelists[numa_node_id()]; | 2674 | l3 = cachep->nodelists[node]; |
2674 | spin_lock(&l3->list_lock); | 2675 | spin_lock(&l3->list_lock); |
2675 | if (l3->shared) { | 2676 | if (l3->shared) { |
2676 | struct array_cache *shared_array = l3->shared; | 2677 | struct array_cache *shared_array = l3->shared; |
@@ -2686,7 +2687,7 @@ static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac) | |||
2686 | } | 2687 | } |
2687 | } | 2688 | } |
2688 | 2689 | ||
2689 | free_block(cachep, ac->entry, batchcount); | 2690 | free_block(cachep, ac->entry, batchcount, node); |
2690 | free_done: | 2691 | free_done: |
2691 | #if STATS | 2692 | #if STATS |
2692 | { | 2693 | { |
@@ -2751,7 +2752,7 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp) | |||
2751 | } else { | 2752 | } else { |
2752 | spin_lock(&(cachep->nodelists[nodeid])-> | 2753 | spin_lock(&(cachep->nodelists[nodeid])-> |
2753 | list_lock); | 2754 | list_lock); |
2754 | free_block(cachep, &objp, 1); | 2755 | free_block(cachep, &objp, 1, nodeid); |
2755 | spin_unlock(&(cachep->nodelists[nodeid])-> | 2756 | spin_unlock(&(cachep->nodelists[nodeid])-> |
2756 | list_lock); | 2757 | list_lock); |
2757 | } | 2758 | } |
@@ -2844,7 +2845,7 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, unsigned int __nocast flags, i | |||
2844 | unsigned long save_flags; | 2845 | unsigned long save_flags; |
2845 | void *ptr; | 2846 | void *ptr; |
2846 | 2847 | ||
2847 | if (nodeid == numa_node_id() || nodeid == -1) | 2848 | if (nodeid == -1) |
2848 | return __cache_alloc(cachep, flags); | 2849 | return __cache_alloc(cachep, flags); |
2849 | 2850 | ||
2850 | if (unlikely(!cachep->nodelists[nodeid])) { | 2851 | if (unlikely(!cachep->nodelists[nodeid])) { |
@@ -3079,7 +3080,7 @@ static int alloc_kmemlist(kmem_cache_t *cachep) | |||
3079 | 3080 | ||
3080 | if ((nc = cachep->nodelists[node]->shared)) | 3081 | if ((nc = cachep->nodelists[node]->shared)) |
3081 | free_block(cachep, nc->entry, | 3082 | free_block(cachep, nc->entry, |
3082 | nc->avail); | 3083 | nc->avail, node); |
3083 | 3084 | ||
3084 | l3->shared = new; | 3085 | l3->shared = new; |
3085 | if (!cachep->nodelists[node]->alien) { | 3086 | if (!cachep->nodelists[node]->alien) { |
@@ -3160,7 +3161,7 @@ static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount, | |||
3160 | if (!ccold) | 3161 | if (!ccold) |
3161 | continue; | 3162 | continue; |
3162 | spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); | 3163 | spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); |
3163 | free_block(cachep, ccold->entry, ccold->avail); | 3164 | free_block(cachep, ccold->entry, ccold->avail, cpu_to_node(i)); |
3164 | spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); | 3165 | spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); |
3165 | kfree(ccold); | 3166 | kfree(ccold); |
3166 | } | 3167 | } |
@@ -3240,7 +3241,7 @@ static void drain_array_locked(kmem_cache_t *cachep, | |||
3240 | if (tofree > ac->avail) { | 3241 | if (tofree > ac->avail) { |
3241 | tofree = (ac->avail+1)/2; | 3242 | tofree = (ac->avail+1)/2; |
3242 | } | 3243 | } |
3243 | free_block(cachep, ac->entry, tofree); | 3244 | free_block(cachep, ac->entry, tofree, node); |
3244 | ac->avail -= tofree; | 3245 | ac->avail -= tofree; |
3245 | memmove(ac->entry, &(ac->entry[tofree]), | 3246 | memmove(ac->entry, &(ac->entry[tofree]), |
3246 | sizeof(void*)*ac->avail); | 3247 | sizeof(void*)*ac->avail); |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 0184f510aace..1dcaeda039f4 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -1381,6 +1381,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) | |||
1381 | error = bd_claim(bdev, sys_swapon); | 1381 | error = bd_claim(bdev, sys_swapon); |
1382 | if (error < 0) { | 1382 | if (error < 0) { |
1383 | bdev = NULL; | 1383 | bdev = NULL; |
1384 | error = -EINVAL; | ||
1384 | goto bad_swap; | 1385 | goto bad_swap; |
1385 | } | 1386 | } |
1386 | p->old_block_size = block_size(bdev); | 1387 | p->old_block_size = block_size(bdev); |
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 069253f830c1..2d24fb400e0c 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
@@ -31,7 +31,8 @@ static inline int should_deliver(const struct net_bridge_port *p, | |||
31 | 31 | ||
32 | int br_dev_queue_push_xmit(struct sk_buff *skb) | 32 | int br_dev_queue_push_xmit(struct sk_buff *skb) |
33 | { | 33 | { |
34 | if (skb->len > skb->dev->mtu) | 34 | /* drop mtu oversized packets except tso */ |
35 | if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size) | ||
35 | kfree_skb(skb); | 36 | kfree_skb(skb); |
36 | else { | 37 | else { |
37 | #ifdef CONFIG_BRIDGE_NETFILTER | 38 | #ifdef CONFIG_BRIDGE_NETFILTER |
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index dc20881004bc..fa3f914117ec 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c | |||
@@ -65,7 +65,7 @@ static int help(struct sk_buff **pskb, | |||
65 | 65 | ||
66 | /* increase the UDP timeout of the master connection as replies from | 66 | /* increase the UDP timeout of the master connection as replies from |
67 | * Amanda clients to the server can be quite delayed */ | 67 | * Amanda clients to the server can be quite delayed */ |
68 | ip_ct_refresh_acct(ct, ctinfo, NULL, master_timeout * HZ); | 68 | ip_ct_refresh(ct, *pskb, master_timeout * HZ); |
69 | 69 | ||
70 | /* No data? */ | 70 | /* No data? */ |
71 | dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); | 71 | dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index c1f82e0c81cf..ea65dd3e517a 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -1112,45 +1112,46 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) | |||
1112 | synchronize_net(); | 1112 | synchronize_net(); |
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | static inline void ct_add_counters(struct ip_conntrack *ct, | 1115 | /* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */ |
1116 | enum ip_conntrack_info ctinfo, | 1116 | void __ip_ct_refresh_acct(struct ip_conntrack *ct, |
1117 | const struct sk_buff *skb) | ||
1118 | { | ||
1119 | #ifdef CONFIG_IP_NF_CT_ACCT | ||
1120 | if (skb) { | ||
1121 | ct->counters[CTINFO2DIR(ctinfo)].packets++; | ||
1122 | ct->counters[CTINFO2DIR(ctinfo)].bytes += | ||
1123 | ntohs(skb->nh.iph->tot_len); | ||
1124 | } | ||
1125 | #endif | ||
1126 | } | ||
1127 | |||
1128 | /* Refresh conntrack for this many jiffies and do accounting (if skb != NULL) */ | ||
1129 | void ip_ct_refresh_acct(struct ip_conntrack *ct, | ||
1130 | enum ip_conntrack_info ctinfo, | 1117 | enum ip_conntrack_info ctinfo, |
1131 | const struct sk_buff *skb, | 1118 | const struct sk_buff *skb, |
1132 | unsigned long extra_jiffies) | 1119 | unsigned long extra_jiffies, |
1120 | int do_acct) | ||
1133 | { | 1121 | { |
1122 | int do_event = 0; | ||
1123 | |||
1134 | IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); | 1124 | IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); |
1125 | IP_NF_ASSERT(skb); | ||
1126 | |||
1127 | write_lock_bh(&ip_conntrack_lock); | ||
1135 | 1128 | ||
1136 | /* If not in hash table, timer will not be active yet */ | 1129 | /* If not in hash table, timer will not be active yet */ |
1137 | if (!is_confirmed(ct)) { | 1130 | if (!is_confirmed(ct)) { |
1138 | ct->timeout.expires = extra_jiffies; | 1131 | ct->timeout.expires = extra_jiffies; |
1139 | ct_add_counters(ct, ctinfo, skb); | 1132 | do_event = 1; |
1140 | } else { | 1133 | } else { |
1141 | write_lock_bh(&ip_conntrack_lock); | ||
1142 | /* Need del_timer for race avoidance (may already be dying). */ | 1134 | /* Need del_timer for race avoidance (may already be dying). */ |
1143 | if (del_timer(&ct->timeout)) { | 1135 | if (del_timer(&ct->timeout)) { |
1144 | ct->timeout.expires = jiffies + extra_jiffies; | 1136 | ct->timeout.expires = jiffies + extra_jiffies; |
1145 | add_timer(&ct->timeout); | 1137 | add_timer(&ct->timeout); |
1146 | /* FIXME: We loose some REFRESH events if this function | 1138 | do_event = 1; |
1147 | * is called without an skb. I'll fix this later -HW */ | ||
1148 | if (skb) | ||
1149 | ip_conntrack_event_cache(IPCT_REFRESH, skb); | ||
1150 | } | 1139 | } |
1151 | ct_add_counters(ct, ctinfo, skb); | ||
1152 | write_unlock_bh(&ip_conntrack_lock); | ||
1153 | } | 1140 | } |
1141 | |||
1142 | #ifdef CONFIG_IP_NF_CT_ACCT | ||
1143 | if (do_acct) { | ||
1144 | ct->counters[CTINFO2DIR(ctinfo)].packets++; | ||
1145 | ct->counters[CTINFO2DIR(ctinfo)].bytes += | ||
1146 | ntohs(skb->nh.iph->tot_len); | ||
1147 | } | ||
1148 | #endif | ||
1149 | |||
1150 | write_unlock_bh(&ip_conntrack_lock); | ||
1151 | |||
1152 | /* must be unlocked when calling event cache */ | ||
1153 | if (do_event) | ||
1154 | ip_conntrack_event_cache(IPCT_REFRESH, skb); | ||
1154 | } | 1155 | } |
1155 | 1156 | ||
1156 | #if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ | 1157 | #if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c index 79db5b70d5f6..926a6684643d 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c | |||
@@ -172,7 +172,6 @@ static int destroy_sibling_or_exp(const struct ip_conntrack_tuple *t) | |||
172 | DEBUGP("setting timeout of conntrack %p to 0\n", sibling); | 172 | DEBUGP("setting timeout of conntrack %p to 0\n", sibling); |
173 | sibling->proto.gre.timeout = 0; | 173 | sibling->proto.gre.timeout = 0; |
174 | sibling->proto.gre.stream_timeout = 0; | 174 | sibling->proto.gre.stream_timeout = 0; |
175 | /* refresh_acct will not modify counters if skb == NULL */ | ||
176 | if (del_timer(&sibling->timeout)) | 175 | if (del_timer(&sibling->timeout)) |
177 | sibling->timeout.function((unsigned long)sibling); | 176 | sibling->timeout.function((unsigned long)sibling); |
178 | ip_conntrack_put(sibling); | 177 | ip_conntrack_put(sibling); |
@@ -223,8 +222,8 @@ static void pptp_destroy_siblings(struct ip_conntrack *ct) | |||
223 | static inline int | 222 | static inline int |
224 | exp_gre(struct ip_conntrack *master, | 223 | exp_gre(struct ip_conntrack *master, |
225 | u_int32_t seq, | 224 | u_int32_t seq, |
226 | u_int16_t callid, | 225 | __be16 callid, |
227 | u_int16_t peer_callid) | 226 | __be16 peer_callid) |
228 | { | 227 | { |
229 | struct ip_conntrack_tuple inv_tuple; | 228 | struct ip_conntrack_tuple inv_tuple; |
230 | struct ip_conntrack_tuple exp_tuples[] = { | 229 | struct ip_conntrack_tuple exp_tuples[] = { |
@@ -263,7 +262,7 @@ exp_gre(struct ip_conntrack *master, | |||
263 | exp_orig->mask.src.ip = 0xffffffff; | 262 | exp_orig->mask.src.ip = 0xffffffff; |
264 | exp_orig->mask.src.u.all = 0; | 263 | exp_orig->mask.src.u.all = 0; |
265 | exp_orig->mask.dst.u.all = 0; | 264 | exp_orig->mask.dst.u.all = 0; |
266 | exp_orig->mask.dst.u.gre.key = 0xffff; | 265 | exp_orig->mask.dst.u.gre.key = htons(0xffff); |
267 | exp_orig->mask.dst.ip = 0xffffffff; | 266 | exp_orig->mask.dst.ip = 0xffffffff; |
268 | exp_orig->mask.dst.protonum = 0xff; | 267 | exp_orig->mask.dst.protonum = 0xff; |
269 | 268 | ||
@@ -340,7 +339,8 @@ pptp_inbound_pkt(struct sk_buff **pskb, | |||
340 | unsigned int reqlen; | 339 | unsigned int reqlen; |
341 | union pptp_ctrl_union _pptpReq, *pptpReq; | 340 | union pptp_ctrl_union _pptpReq, *pptpReq; |
342 | struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; | 341 | struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; |
343 | u_int16_t msg, *cid, *pcid; | 342 | u_int16_t msg; |
343 | __be16 *cid, *pcid; | ||
344 | u_int32_t seq; | 344 | u_int32_t seq; |
345 | 345 | ||
346 | ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh); | 346 | ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh); |
@@ -485,7 +485,7 @@ pptp_inbound_pkt(struct sk_buff **pskb, | |||
485 | 485 | ||
486 | if (info->pns_call_id != ntohs(*pcid)) { | 486 | if (info->pns_call_id != ntohs(*pcid)) { |
487 | DEBUGP("%s for unknown CallID %u\n", | 487 | DEBUGP("%s for unknown CallID %u\n", |
488 | pptp_msg_name[msg], ntohs(*cid)); | 488 | pptp_msg_name[msg], ntohs(*pcid)); |
489 | break; | 489 | break; |
490 | } | 490 | } |
491 | 491 | ||
@@ -551,7 +551,8 @@ pptp_outbound_pkt(struct sk_buff **pskb, | |||
551 | unsigned int reqlen; | 551 | unsigned int reqlen; |
552 | union pptp_ctrl_union _pptpReq, *pptpReq; | 552 | union pptp_ctrl_union _pptpReq, *pptpReq; |
553 | struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; | 553 | struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; |
554 | u_int16_t msg, *cid, *pcid; | 554 | u_int16_t msg; |
555 | __be16 *cid, *pcid; | ||
555 | 556 | ||
556 | ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh); | 557 | ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh); |
557 | if (!ctlh) | 558 | if (!ctlh) |
@@ -755,7 +756,7 @@ static struct ip_conntrack_helper pptp = { | |||
755 | } | 756 | } |
756 | }, | 757 | }, |
757 | .mask = { .src = { .ip = 0, | 758 | .mask = { .src = { .ip = 0, |
758 | .u = { .tcp = { .port = 0xffff } } | 759 | .u = { .tcp = { .port = __constant_htons(0xffff) } } |
759 | }, | 760 | }, |
760 | .dst = { .ip = 0, | 761 | .dst = { .ip = 0, |
761 | .u = { .all = 0 }, | 762 | .u = { .all = 0 }, |
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c index 71ef19d126d0..577bac22dcc6 100644 --- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c +++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c | |||
@@ -91,7 +91,7 @@ static int help(struct sk_buff **pskb, | |||
91 | ip_conntrack_expect_related(exp); | 91 | ip_conntrack_expect_related(exp); |
92 | ip_conntrack_expect_put(exp); | 92 | ip_conntrack_expect_put(exp); |
93 | 93 | ||
94 | ip_ct_refresh_acct(ct, ctinfo, NULL, timeout * HZ); | 94 | ip_ct_refresh(ct, *pskb, timeout * HZ); |
95 | out: | 95 | out: |
96 | return NF_ACCEPT; | 96 | return NF_ACCEPT; |
97 | } | 97 | } |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index d3c7808010ec..dd476b191f4b 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -989,7 +989,7 @@ EXPORT_SYMBOL(need_ip_conntrack); | |||
989 | EXPORT_SYMBOL(ip_conntrack_helper_register); | 989 | EXPORT_SYMBOL(ip_conntrack_helper_register); |
990 | EXPORT_SYMBOL(ip_conntrack_helper_unregister); | 990 | EXPORT_SYMBOL(ip_conntrack_helper_unregister); |
991 | EXPORT_SYMBOL(ip_ct_iterate_cleanup); | 991 | EXPORT_SYMBOL(ip_ct_iterate_cleanup); |
992 | EXPORT_SYMBOL(ip_ct_refresh_acct); | 992 | EXPORT_SYMBOL(__ip_ct_refresh_acct); |
993 | 993 | ||
994 | EXPORT_SYMBOL(ip_conntrack_expect_alloc); | 994 | EXPORT_SYMBOL(ip_conntrack_expect_alloc); |
995 | EXPORT_SYMBOL(ip_conntrack_expect_put); | 995 | EXPORT_SYMBOL(ip_conntrack_expect_put); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5dd6dd7d091e..d6e3d269e906 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -509,7 +509,16 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss | |||
509 | tp->lost_out -= diff; | 509 | tp->lost_out -= diff; |
510 | tp->left_out -= diff; | 510 | tp->left_out -= diff; |
511 | } | 511 | } |
512 | |||
512 | if (diff > 0) { | 513 | if (diff > 0) { |
514 | /* Adjust Reno SACK estimate. */ | ||
515 | if (!tp->rx_opt.sack_ok) { | ||
516 | tp->sacked_out -= diff; | ||
517 | if ((int)tp->sacked_out < 0) | ||
518 | tp->sacked_out = 0; | ||
519 | tcp_sync_left_out(tp); | ||
520 | } | ||
521 | |||
513 | tp->fackets_out -= diff; | 522 | tp->fackets_out -= diff; |
514 | if ((int)tp->fackets_out < 0) | 523 | if ((int)tp->fackets_out < 0) |
515 | tp->fackets_out = 0; | 524 | tp->fackets_out = 0; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 86073df418f5..505c7de10c50 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -2414,6 +2414,17 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep, | |||
2414 | skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); | 2414 | skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); |
2415 | chunk->subh.shutdown_hdr = sdh; | 2415 | chunk->subh.shutdown_hdr = sdh; |
2416 | 2416 | ||
2417 | /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
2418 | * When a peer sends a SHUTDOWN, SCTP delivers this notification to | ||
2419 | * inform the application that it should cease sending data. | ||
2420 | */ | ||
2421 | ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC); | ||
2422 | if (!ev) { | ||
2423 | disposition = SCTP_DISPOSITION_NOMEM; | ||
2424 | goto out; | ||
2425 | } | ||
2426 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | ||
2427 | |||
2417 | /* Upon the reception of the SHUTDOWN, the peer endpoint shall | 2428 | /* Upon the reception of the SHUTDOWN, the peer endpoint shall |
2418 | * - enter the SHUTDOWN-RECEIVED state, | 2429 | * - enter the SHUTDOWN-RECEIVED state, |
2419 | * - stop accepting new data from its SCTP user | 2430 | * - stop accepting new data from its SCTP user |
@@ -2439,17 +2450,6 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep, | |||
2439 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN, | 2450 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN, |
2440 | SCTP_U32(chunk->subh.shutdown_hdr->cum_tsn_ack)); | 2451 | SCTP_U32(chunk->subh.shutdown_hdr->cum_tsn_ack)); |
2441 | 2452 | ||
2442 | /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
2443 | * When a peer sends a SHUTDOWN, SCTP delivers this notification to | ||
2444 | * inform the application that it should cease sending data. | ||
2445 | */ | ||
2446 | ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC); | ||
2447 | if (!ev) { | ||
2448 | disposition = SCTP_DISPOSITION_NOMEM; | ||
2449 | goto out; | ||
2450 | } | ||
2451 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | ||
2452 | |||
2453 | out: | 2453 | out: |
2454 | return disposition; | 2454 | return disposition; |
2455 | } | 2455 | } |
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c index 4491733c9e4e..2c2ae2ee01ac 100644 --- a/sound/oss/au1000.c +++ b/sound/oss/au1000.c | |||
@@ -1295,7 +1295,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma) | |||
1295 | unsigned long size; | 1295 | unsigned long size; |
1296 | int ret = 0; | 1296 | int ret = 0; |
1297 | 1297 | ||
1298 | dbg(__FUNCTION__); | 1298 | dbg("%s", __FUNCTION__); |
1299 | 1299 | ||
1300 | lock_kernel(); | 1300 | lock_kernel(); |
1301 | down(&s->sem); | 1301 | down(&s->sem); |
diff --git a/sound/oss/ite8172.c b/sound/oss/ite8172.c index 58f879fda975..26e5944b6ba8 100644 --- a/sound/oss/ite8172.c +++ b/sound/oss/ite8172.c | |||
@@ -1859,7 +1859,7 @@ static int it8172_release(struct inode *inode, struct file *file) | |||
1859 | struct it8172_state *s = (struct it8172_state *)file->private_data; | 1859 | struct it8172_state *s = (struct it8172_state *)file->private_data; |
1860 | 1860 | ||
1861 | #ifdef IT8172_VERBOSE_DEBUG | 1861 | #ifdef IT8172_VERBOSE_DEBUG |
1862 | dbg(__FUNCTION__); | 1862 | dbg("%s", __FUNCTION__); |
1863 | #endif | 1863 | #endif |
1864 | lock_kernel(); | 1864 | lock_kernel(); |
1865 | if (file->f_mode & FMODE_WRITE) | 1865 | if (file->f_mode & FMODE_WRITE) |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 8a59598167f9..c1a239a4dac6 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -405,7 +405,7 @@ static int snd_atiixp_acquire_codec(atiixp_t *chip) | |||
405 | 405 | ||
406 | while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) { | 406 | while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) { |
407 | if (! timeout--) { | 407 | if (! timeout--) { |
408 | snd_printk(KERN_WARNING "atiixp: codec acquire timeout\n"); | 408 | snd_printk(KERN_WARNING "atiixp-modem: codec acquire timeout\n"); |
409 | return -EBUSY; | 409 | return -EBUSY; |
410 | } | 410 | } |
411 | udelay(1); | 411 | udelay(1); |
@@ -436,7 +436,7 @@ static unsigned short snd_atiixp_codec_read(atiixp_t *chip, unsigned short codec | |||
436 | } while (--timeout); | 436 | } while (--timeout); |
437 | /* time out may happen during reset */ | 437 | /* time out may happen during reset */ |
438 | if (reg < 0x7c) | 438 | if (reg < 0x7c) |
439 | snd_printk(KERN_WARNING "atiixp: codec read timeout (reg %x)\n", reg); | 439 | snd_printk(KERN_WARNING "atiixp-modem: codec read timeout (reg %x)\n", reg); |
440 | return 0xffff; | 440 | return 0xffff; |
441 | } | 441 | } |
442 | 442 | ||
@@ -498,7 +498,7 @@ static int snd_atiixp_aclink_reset(atiixp_t *chip) | |||
498 | do_delay(); | 498 | do_delay(); |
499 | atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); | 499 | atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); |
500 | if (--timeout) { | 500 | if (--timeout) { |
501 | snd_printk(KERN_ERR "atiixp: codec reset timeout\n"); | 501 | snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n"); |
502 | break; | 502 | break; |
503 | } | 503 | } |
504 | } | 504 | } |
@@ -552,7 +552,7 @@ static int snd_atiixp_codec_detect(atiixp_t *chip) | |||
552 | atiixp_write(chip, IER, 0); /* disable irqs */ | 552 | atiixp_write(chip, IER, 0); /* disable irqs */ |
553 | 553 | ||
554 | if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) { | 554 | if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) { |
555 | snd_printk(KERN_ERR "atiixp: no codec detected!\n"); | 555 | snd_printk(KERN_ERR "atiixp-modem: no codec detected!\n"); |
556 | return -ENXIO; | 556 | return -ENXIO; |
557 | } | 557 | } |
558 | return 0; | 558 | return 0; |
@@ -635,7 +635,7 @@ static void snd_atiixp_xrun_dma(atiixp_t *chip, atiixp_dma_t *dma) | |||
635 | { | 635 | { |
636 | if (! dma->substream || ! dma->running) | 636 | if (! dma->substream || ! dma->running) |
637 | return; | 637 | return; |
638 | snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type); | 638 | snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type); |
639 | snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); | 639 | snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); |
640 | } | 640 | } |
641 | 641 | ||
@@ -1081,14 +1081,14 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock) | |||
1081 | ac97.scaps = AC97_SCAP_SKIP_AUDIO; | 1081 | ac97.scaps = AC97_SCAP_SKIP_AUDIO; |
1082 | if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { | 1082 | if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { |
1083 | chip->ac97[i] = NULL; /* to be sure */ | 1083 | chip->ac97[i] = NULL; /* to be sure */ |
1084 | snd_printdd("atiixp: codec %d not available for modem\n", i); | 1084 | snd_printdd("atiixp-modem: codec %d not available for modem\n", i); |
1085 | continue; | 1085 | continue; |
1086 | } | 1086 | } |
1087 | codec_count++; | 1087 | codec_count++; |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | if (! codec_count) { | 1090 | if (! codec_count) { |
1091 | snd_printk(KERN_ERR "atiixp: no codec available\n"); | 1091 | snd_printk(KERN_ERR "atiixp-modem: no codec available\n"); |
1092 | return -ENODEV; | 1092 | return -ENODEV; |
1093 | } | 1093 | } |
1094 | 1094 | ||
@@ -1159,7 +1159,7 @@ static void __devinit snd_atiixp_proc_init(atiixp_t *chip) | |||
1159 | { | 1159 | { |
1160 | snd_info_entry_t *entry; | 1160 | snd_info_entry_t *entry; |
1161 | 1161 | ||
1162 | if (! snd_card_proc_new(chip->card, "atiixp", &entry)) | 1162 | if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry)) |
1163 | snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read); | 1163 | snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read); |
1164 | } | 1164 | } |
1165 | 1165 | ||