diff options
author | Tony Luck <tony.luck@intel.com> | 2005-05-17 18:53:14 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-05-17 18:53:14 -0400 |
commit | 325a479c4c110db278ef3361460a48c4093252cc (patch) | |
tree | bcfbf4d0647d9442045639a5c19da59d55190e81 | |
parent | ebcc80c1b6629a445f7471cc1ddb48faf8a84e70 (diff) | |
parent | 7f9eaedf894dbaa08c157832e9a6c9c03ffed1ed (diff) |
Merge with temp tree to get David's gdb inferior calls patch
642 files changed, 10422 insertions, 7521 deletions
diff --git a/Documentation/Changes b/Documentation/Changes index caa6a5529b6b..57542bc25edd 100644 --- a/Documentation/Changes +++ b/Documentation/Changes | |||
@@ -357,14 +357,14 @@ Quota-tools | |||
357 | ---------- | 357 | ---------- |
358 | o <http://sourceforge.net/projects/linuxquota/> | 358 | o <http://sourceforge.net/projects/linuxquota/> |
359 | 359 | ||
360 | Jade | ||
361 | ---- | ||
362 | o <ftp://ftp.jclark.com/pub/jade/jade-1.2.1.tar.gz> | ||
363 | |||
364 | DocBook Stylesheets | 360 | DocBook Stylesheets |
365 | ------------------- | 361 | ------------------- |
366 | o <http://nwalsh.com/docbook/dsssl/> | 362 | o <http://nwalsh.com/docbook/dsssl/> |
367 | 363 | ||
364 | XMLTO XSLT Frontend | ||
365 | ------------------- | ||
366 | o <http://cyberelk.net/tim/xmlto/> | ||
367 | |||
368 | Intel P6 microcode | 368 | Intel P6 microcode |
369 | ------------------ | 369 | ------------------ |
370 | o <http://www.urbanmyth.org/microcode/> | 370 | o <http://www.urbanmyth.org/microcode/> |
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index a221039ee4c9..e69b3d2e7884 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile | |||
@@ -7,10 +7,9 @@ | |||
7 | # list of DOCBOOKS. | 7 | # list of DOCBOOKS. |
8 | 8 | ||
9 | DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ | 9 | DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ |
10 | kernel-hacking.xml kernel-locking.xml via-audio.xml \ | 10 | kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ |
11 | deviceiobook.xml procfs-guide.xml tulip-user.xml \ | 11 | procfs-guide.xml writing_usb_driver.xml scsidrivers.xml \ |
12 | writing_usb_driver.xml scsidrivers.xml sis900.xml \ | 12 | sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \ |
13 | kernel-api.xml journal-api.xml lsm.xml usb.xml \ | ||
14 | gadget.xml libata.xml mtdnand.xml librs.xml | 13 | gadget.xml libata.xml mtdnand.xml librs.xml |
15 | 14 | ||
16 | ### | 15 | ### |
@@ -42,14 +41,16 @@ MAN := $(patsubst %.xml, %.9, $(BOOKS)) | |||
42 | mandocs: $(MAN) | 41 | mandocs: $(MAN) |
43 | 42 | ||
44 | installmandocs: mandocs | 43 | installmandocs: mandocs |
45 | $(MAKEMAN) install Documentation/DocBook/man | 44 | mkdir -p /usr/local/man/man9/ |
45 | install Documentation/DocBook/man/*.9.gz /usr/local/man/man9/ | ||
46 | 46 | ||
47 | ### | 47 | ### |
48 | #External programs used | 48 | #External programs used |
49 | KERNELDOC = scripts/kernel-doc | 49 | KERNELDOC = scripts/kernel-doc |
50 | DOCPROC = scripts/basic/docproc | 50 | DOCPROC = scripts/basic/docproc |
51 | SPLITMAN = $(PERL) $(srctree)/scripts/split-man | 51 | |
52 | MAKEMAN = $(PERL) $(srctree)/scripts/makeman | 52 | XMLTOFLAGS = -m Documentation/DocBook/stylesheet.xsl |
53 | #XMLTOFLAGS += --skip-validation | ||
53 | 54 | ||
54 | ### | 55 | ### |
55 | # DOCPROC is used for two purposes: | 56 | # DOCPROC is used for two purposes: |
@@ -96,45 +97,44 @@ $(obj)/procfs-guide.xml: $(C-procfs-example2) | |||
96 | # Rules to generate postscript, PDF and HTML | 97 | # Rules to generate postscript, PDF and HTML |
97 | # db2html creates a directory. Generate a html file used for timestamp | 98 | # db2html creates a directory. Generate a html file used for timestamp |
98 | 99 | ||
99 | quiet_cmd_db2ps = DB2PS $@ | 100 | quiet_cmd_db2ps = XMLTO $@ |
100 | cmd_db2ps = db2ps -o $(dir $@) $< | 101 | cmd_db2ps = xmlto ps $(XMLTOFLAGS) -o $(dir $@) $< |
101 | %.ps : %.xml | 102 | %.ps : %.xml |
102 | @(which db2ps > /dev/null 2>&1) || \ | 103 | @(which xmlto > /dev/null 2>&1) || \ |
103 | (echo "*** You need to install DocBook stylesheets ***"; \ | 104 | (echo "*** You need to install xmlto ***"; \ |
104 | exit 1) | 105 | exit 1) |
105 | $(call cmd,db2ps) | 106 | $(call cmd,db2ps) |
106 | 107 | ||
107 | quiet_cmd_db2pdf = DB2PDF $@ | 108 | quiet_cmd_db2pdf = XMLTO $@ |
108 | cmd_db2pdf = db2pdf -o $(dir $@) $< | 109 | cmd_db2pdf = xmlto pdf $(XMLTOFLAGS) -o $(dir $@) $< |
109 | %.pdf : %.xml | 110 | %.pdf : %.xml |
110 | @(which db2pdf > /dev/null 2>&1) || \ | 111 | @(which xmlto > /dev/null 2>&1) || \ |
111 | (echo "*** You need to install DocBook stylesheets ***"; \ | 112 | (echo "*** You need to install xmlto ***"; \ |
112 | exit 1) | 113 | exit 1) |
113 | $(call cmd,db2pdf) | 114 | $(call cmd,db2pdf) |
114 | 115 | ||
115 | quiet_cmd_db2html = DB2HTML $@ | 116 | quiet_cmd_db2html = XMLTO $@ |
116 | cmd_db2html = db2html -o $(patsubst %.html,%,$@) $< && \ | 117 | cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \ |
117 | echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/book1.html"> \ | 118 | echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \ |
118 | Goto $(patsubst %.html,%,$(notdir $@))</a><p>' > $@ | 119 | Goto $(patsubst %.html,%,$(notdir $@))</a><p>' > $@ |
119 | 120 | ||
120 | %.html: %.xml | 121 | %.html: %.xml |
121 | @(which db2html > /dev/null 2>&1) || \ | 122 | @(which xmlto > /dev/null 2>&1) || \ |
122 | (echo "*** You need to install DocBook stylesheets ***"; \ | 123 | (echo "*** You need to install xmlto ***"; \ |
123 | exit 1) | 124 | exit 1) |
124 | @rm -rf $@ $(patsubst %.html,%,$@) | 125 | @rm -rf $@ $(patsubst %.html,%,$@) |
125 | $(call cmd,db2html) | 126 | $(call cmd,db2html) |
126 | @if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \ | 127 | @if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \ |
127 | cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi | 128 | cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi |
128 | 129 | ||
129 | ### | 130 | quiet_cmd_db2man = XMLTO $@ |
130 | # Rule to generate man files - output is placed in the man subdirectory | 131 | cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man $< ; gzip -f $(obj)/man/*.9; fi |
131 | 132 | %.9 : %.xml | |
132 | %.9: %.xml | 133 | @(which xmlto > /dev/null 2>&1) || \ |
133 | ifneq ($(KBUILD_SRC),) | 134 | (echo "*** You need to install xmlto ***"; \ |
134 | $(Q)mkdir -p $(objtree)/Documentation/DocBook/man | 135 | exit 1) |
135 | endif | 136 | $(call cmd,db2man) |
136 | $(SPLITMAN) $< $(objtree)/Documentation/DocBook/man "$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)" | 137 | @touch $@ |
137 | $(MAKEMAN) convert $(objtree)/Documentation/DocBook/man $< | ||
138 | 138 | ||
139 | ### | 139 | ### |
140 | # Rules to generate postscripts and PNG imgages from .fig format files | 140 | # Rules to generate postscripts and PNG imgages from .fig format files |
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 1bd20c860285..757cef8f8491 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl | |||
@@ -49,13 +49,33 @@ | |||
49 | !Iinclude/asm-i386/unaligned.h | 49 | !Iinclude/asm-i386/unaligned.h |
50 | </sect1> | 50 | </sect1> |
51 | 51 | ||
52 | <!-- FIXME: | ||
53 | kernel/sched.c has no docs, which stuffs up the sgml. Comment | ||
54 | out until somebody adds docs. KAO | ||
55 | <sect1><title>Delaying, scheduling, and timer routines</title> | 52 | <sect1><title>Delaying, scheduling, and timer routines</title> |
56 | X!Ekernel/sched.c | 53 | !Iinclude/linux/sched.h |
54 | !Ekernel/sched.c | ||
55 | !Ekernel/timer.c | ||
57 | </sect1> | 56 | </sect1> |
58 | KAO --> | 57 | <sect1><title>Internal Functions</title> |
58 | !Ikernel/exit.c | ||
59 | !Ikernel/signal.c | ||
60 | </sect1> | ||
61 | |||
62 | <sect1><title>Kernel objects manipulation</title> | ||
63 | <!-- | ||
64 | X!Iinclude/linux/kobject.h | ||
65 | --> | ||
66 | !Elib/kobject.c | ||
67 | </sect1> | ||
68 | |||
69 | <sect1><title>Kernel utility functions</title> | ||
70 | !Iinclude/linux/kernel.h | ||
71 | <!-- This needs to clean up to make kernel-doc happy | ||
72 | X!Ekernel/printk.c | ||
73 | --> | ||
74 | !Ekernel/panic.c | ||
75 | !Ekernel/sys.c | ||
76 | !Ekernel/rcupdate.c | ||
77 | </sect1> | ||
78 | |||
59 | </chapter> | 79 | </chapter> |
60 | 80 | ||
61 | <chapter id="adt"> | 81 | <chapter id="adt"> |
@@ -81,7 +101,9 @@ KAO --> | |||
81 | !Elib/vsprintf.c | 101 | !Elib/vsprintf.c |
82 | </sect1> | 102 | </sect1> |
83 | <sect1><title>String Manipulation</title> | 103 | <sect1><title>String Manipulation</title> |
84 | !Ilib/string.c | 104 | <!-- All functions are exported at now |
105 | X!Ilib/string.c | ||
106 | --> | ||
85 | !Elib/string.c | 107 | !Elib/string.c |
86 | </sect1> | 108 | </sect1> |
87 | <sect1><title>Bit Operations</title> | 109 | <sect1><title>Bit Operations</title> |
@@ -98,6 +120,25 @@ KAO --> | |||
98 | !Iinclude/asm-i386/uaccess.h | 120 | !Iinclude/asm-i386/uaccess.h |
99 | !Iarch/i386/lib/usercopy.c | 121 | !Iarch/i386/lib/usercopy.c |
100 | </sect1> | 122 | </sect1> |
123 | <sect1><title>More Memory Management Functions</title> | ||
124 | !Iinclude/linux/rmap.h | ||
125 | !Emm/readahead.c | ||
126 | !Emm/filemap.c | ||
127 | !Emm/memory.c | ||
128 | !Emm/vmalloc.c | ||
129 | !Emm/mempool.c | ||
130 | !Emm/page-writeback.c | ||
131 | !Emm/truncate.c | ||
132 | </sect1> | ||
133 | </chapter> | ||
134 | |||
135 | |||
136 | <chapter id="ipc"> | ||
137 | <title>Kernel IPC facilities</title> | ||
138 | |||
139 | <sect1><title>IPC utilities</title> | ||
140 | !Iipc/util.c | ||
141 | </sect1> | ||
101 | </chapter> | 142 | </chapter> |
102 | 143 | ||
103 | <chapter id="kfifo"> | 144 | <chapter id="kfifo"> |
@@ -114,6 +155,10 @@ KAO --> | |||
114 | <sect1><title>sysctl interface</title> | 155 | <sect1><title>sysctl interface</title> |
115 | !Ekernel/sysctl.c | 156 | !Ekernel/sysctl.c |
116 | </sect1> | 157 | </sect1> |
158 | |||
159 | <sect1><title>proc filesystem interface</title> | ||
160 | !Ifs/proc/base.c | ||
161 | </sect1> | ||
117 | </chapter> | 162 | </chapter> |
118 | 163 | ||
119 | <chapter id="debugfs"> | 164 | <chapter id="debugfs"> |
@@ -127,6 +172,10 @@ KAO --> | |||
127 | 172 | ||
128 | <chapter id="vfs"> | 173 | <chapter id="vfs"> |
129 | <title>The Linux VFS</title> | 174 | <title>The Linux VFS</title> |
175 | <sect1><title>The Filesystem types</title> | ||
176 | !Iinclude/linux/fs.h | ||
177 | !Einclude/linux/fs.h | ||
178 | </sect1> | ||
130 | <sect1><title>The Directory Cache</title> | 179 | <sect1><title>The Directory Cache</title> |
131 | !Efs/dcache.c | 180 | !Efs/dcache.c |
132 | !Iinclude/linux/dcache.h | 181 | !Iinclude/linux/dcache.h |
@@ -142,13 +191,31 @@ KAO --> | |||
142 | !Efs/locks.c | 191 | !Efs/locks.c |
143 | !Ifs/locks.c | 192 | !Ifs/locks.c |
144 | </sect1> | 193 | </sect1> |
194 | <sect1><title>Other Functions</title> | ||
195 | !Efs/mpage.c | ||
196 | !Efs/namei.c | ||
197 | !Efs/buffer.c | ||
198 | !Efs/bio.c | ||
199 | !Efs/seq_file.c | ||
200 | !Efs/filesystems.c | ||
201 | !Efs/fs-writeback.c | ||
202 | !Efs/block_dev.c | ||
203 | </sect1> | ||
145 | </chapter> | 204 | </chapter> |
146 | 205 | ||
147 | <chapter id="netcore"> | 206 | <chapter id="netcore"> |
148 | <title>Linux Networking</title> | 207 | <title>Linux Networking</title> |
208 | <sect1><title>Networking Base Types</title> | ||
209 | !Iinclude/linux/net.h | ||
210 | </sect1> | ||
149 | <sect1><title>Socket Buffer Functions</title> | 211 | <sect1><title>Socket Buffer Functions</title> |
150 | !Iinclude/linux/skbuff.h | 212 | !Iinclude/linux/skbuff.h |
213 | !Iinclude/net/sock.h | ||
214 | !Enet/socket.c | ||
151 | !Enet/core/skbuff.c | 215 | !Enet/core/skbuff.c |
216 | !Enet/core/sock.c | ||
217 | !Enet/core/datagram.c | ||
218 | !Enet/core/stream.c | ||
152 | </sect1> | 219 | </sect1> |
153 | <sect1><title>Socket Filter</title> | 220 | <sect1><title>Socket Filter</title> |
154 | !Enet/core/filter.c | 221 | !Enet/core/filter.c |
@@ -158,6 +225,14 @@ KAO --> | |||
158 | !Enet/core/gen_stats.c | 225 | !Enet/core/gen_stats.c |
159 | !Enet/core/gen_estimator.c | 226 | !Enet/core/gen_estimator.c |
160 | </sect1> | 227 | </sect1> |
228 | <sect1><title>SUN RPC subsystem</title> | ||
229 | <!-- The !D functionality is not perfect, garbage has to be protected by comments | ||
230 | !Dnet/sunrpc/sunrpc_syms.c | ||
231 | --> | ||
232 | !Enet/sunrpc/xdr.c | ||
233 | !Enet/sunrpc/svcsock.c | ||
234 | !Enet/sunrpc/sched.c | ||
235 | </sect1> | ||
161 | </chapter> | 236 | </chapter> |
162 | 237 | ||
163 | <chapter id="netdev"> | 238 | <chapter id="netdev"> |
@@ -194,11 +269,26 @@ X!Ekernel/module.c | |||
194 | !Iarch/i386/kernel/irq.c | 269 | !Iarch/i386/kernel/irq.c |
195 | </sect1> | 270 | </sect1> |
196 | 271 | ||
272 | <sect1><title>Resources Management</title> | ||
273 | !Ekernel/resource.c | ||
274 | </sect1> | ||
275 | |||
197 | <sect1><title>MTRR Handling</title> | 276 | <sect1><title>MTRR Handling</title> |
198 | !Earch/i386/kernel/cpu/mtrr/main.c | 277 | !Earch/i386/kernel/cpu/mtrr/main.c |
199 | </sect1> | 278 | </sect1> |
200 | <sect1><title>PCI Support Library</title> | 279 | <sect1><title>PCI Support Library</title> |
201 | !Edrivers/pci/pci.c | 280 | !Edrivers/pci/pci.c |
281 | !Edrivers/pci/pci-driver.c | ||
282 | !Edrivers/pci/remove.c | ||
283 | !Edrivers/pci/pci-acpi.c | ||
284 | <!-- kerneldoc does not understand to __devinit | ||
285 | X!Edrivers/pci/search.c | ||
286 | --> | ||
287 | !Edrivers/pci/msi.c | ||
288 | !Edrivers/pci/bus.c | ||
289 | !Edrivers/pci/hotplug.c | ||
290 | !Edrivers/pci/probe.c | ||
291 | !Edrivers/pci/rom.c | ||
202 | </sect1> | 292 | </sect1> |
203 | <sect1><title>PCI Hotplug Support Library</title> | 293 | <sect1><title>PCI Hotplug Support Library</title> |
204 | !Edrivers/pci/hotplug/pci_hotplug_core.c | 294 | !Edrivers/pci/hotplug/pci_hotplug_core.c |
@@ -223,6 +313,14 @@ X!Earch/i386/kernel/mca.c | |||
223 | !Efs/devfs/base.c | 313 | !Efs/devfs/base.c |
224 | </chapter> | 314 | </chapter> |
225 | 315 | ||
316 | <chapter id="sysfs"> | ||
317 | <title>The Filesystem for Exporting Kernel Objects</title> | ||
318 | !Efs/sysfs/file.c | ||
319 | !Efs/sysfs/dir.c | ||
320 | !Efs/sysfs/symlink.c | ||
321 | !Efs/sysfs/bin.c | ||
322 | </chapter> | ||
323 | |||
226 | <chapter id="security"> | 324 | <chapter id="security"> |
227 | <title>Security Framework</title> | 325 | <title>Security Framework</title> |
228 | !Esecurity/security.c | 326 | !Esecurity/security.c |
@@ -233,6 +331,61 @@ X!Earch/i386/kernel/mca.c | |||
233 | !Ekernel/power/pm.c | 331 | !Ekernel/power/pm.c |
234 | </chapter> | 332 | </chapter> |
235 | 333 | ||
334 | <chapter id="devdrivers"> | ||
335 | <title>Device drivers infrastructure</title> | ||
336 | <sect1><title>Device Drivers Base</title> | ||
337 | <!-- | ||
338 | X!Iinclude/linux/device.h | ||
339 | --> | ||
340 | !Edrivers/base/driver.c | ||
341 | !Edrivers/base/class_simple.c | ||
342 | !Edrivers/base/core.c | ||
343 | !Edrivers/base/firmware_class.c | ||
344 | !Edrivers/base/transport_class.c | ||
345 | !Edrivers/base/dmapool.c | ||
346 | <!-- Cannot be included, because | ||
347 | attribute_container_add_class_device_adapter | ||
348 | and attribute_container_classdev_to_container | ||
349 | exceed allowed 44 characters maximum | ||
350 | X!Edrivers/base/attribute_container.c | ||
351 | --> | ||
352 | !Edrivers/base/sys.c | ||
353 | <!-- | ||
354 | X!Edrivers/base/interface.c | ||
355 | --> | ||
356 | !Edrivers/base/platform.c | ||
357 | !Edrivers/base/bus.c | ||
358 | </sect1> | ||
359 | <sect1><title>Device Drivers Power Management</title> | ||
360 | !Edrivers/base/power/main.c | ||
361 | !Edrivers/base/power/resume.c | ||
362 | !Edrivers/base/power/suspend.c | ||
363 | </sect1> | ||
364 | <sect1><title>Device Drivers ACPI Support</title> | ||
365 | <!-- Internal functions only | ||
366 | X!Edrivers/acpi/sleep/main.c | ||
367 | X!Edrivers/acpi/sleep/wakeup.c | ||
368 | X!Edrivers/acpi/motherboard.c | ||
369 | X!Edrivers/acpi/bus.c | ||
370 | --> | ||
371 | !Edrivers/acpi/scan.c | ||
372 | <!-- No correct structured comments | ||
373 | X!Edrivers/acpi/pci_bind.c | ||
374 | --> | ||
375 | </sect1> | ||
376 | <sect1><title>Device drivers PnP support</title> | ||
377 | !Edrivers/pnp/core.c | ||
378 | <!-- No correct structured comments | ||
379 | X!Edrivers/pnp/system.c | ||
380 | --> | ||
381 | !Edrivers/pnp/card.c | ||
382 | !Edrivers/pnp/driver.c | ||
383 | !Edrivers/pnp/manager.c | ||
384 | !Edrivers/pnp/support.c | ||
385 | </sect1> | ||
386 | </chapter> | ||
387 | |||
388 | |||
236 | <chapter id="blkdev"> | 389 | <chapter id="blkdev"> |
237 | <title>Block Devices</title> | 390 | <title>Block Devices</title> |
238 | !Edrivers/block/ll_rw_blk.c | 391 | !Edrivers/block/ll_rw_blk.c |
@@ -250,7 +403,23 @@ X!Earch/i386/kernel/mca.c | |||
250 | 403 | ||
251 | <chapter id="snddev"> | 404 | <chapter id="snddev"> |
252 | <title>Sound Devices</title> | 405 | <title>Sound Devices</title> |
406 | !Iinclude/sound/core.h | ||
253 | !Esound/sound_core.c | 407 | !Esound/sound_core.c |
408 | !Iinclude/sound/pcm.h | ||
409 | !Esound/core/pcm.c | ||
410 | !Esound/core/device.c | ||
411 | !Esound/core/info.c | ||
412 | !Esound/core/rawmidi.c | ||
413 | !Esound/core/sound.c | ||
414 | !Esound/core/memory.c | ||
415 | !Esound/core/pcm_memory.c | ||
416 | !Esound/core/init.c | ||
417 | !Esound/core/isadma.c | ||
418 | !Esound/core/control.c | ||
419 | !Esound/core/pcm_lib.c | ||
420 | !Esound/core/hwdep.c | ||
421 | !Esound/core/pcm_native.c | ||
422 | !Esound/core/memalloc.c | ||
254 | <!-- FIXME: Removed for now since no structured comments in source | 423 | <!-- FIXME: Removed for now since no structured comments in source |
255 | X!Isound/sound_firmware.c | 424 | X!Isound/sound_firmware.c |
256 | --> | 425 | --> |
@@ -258,6 +427,7 @@ X!Isound/sound_firmware.c | |||
258 | 427 | ||
259 | <chapter id="uart16x50"> | 428 | <chapter id="uart16x50"> |
260 | <title>16x50 UART Driver</title> | 429 | <title>16x50 UART Driver</title> |
430 | !Iinclude/linux/serial_core.h | ||
261 | !Edrivers/serial/serial_core.c | 431 | !Edrivers/serial/serial_core.c |
262 | !Edrivers/serial/8250.c | 432 | !Edrivers/serial/8250.c |
263 | </chapter> | 433 | </chapter> |
@@ -310,9 +480,11 @@ X!Isound/sound_firmware.c | |||
310 | <sect1><title>Frame Buffer Memory</title> | 480 | <sect1><title>Frame Buffer Memory</title> |
311 | !Edrivers/video/fbmem.c | 481 | !Edrivers/video/fbmem.c |
312 | </sect1> | 482 | </sect1> |
483 | <!-- | ||
313 | <sect1><title>Frame Buffer Console</title> | 484 | <sect1><title>Frame Buffer Console</title> |
314 | !Edrivers/video/console/fbcon.c | 485 | X!Edrivers/video/console/fbcon.c |
315 | </sect1> | 486 | </sect1> |
487 | --> | ||
316 | <sect1><title>Frame Buffer Colormap</title> | 488 | <sect1><title>Frame Buffer Colormap</title> |
317 | !Edrivers/video/fbcmap.c | 489 | !Edrivers/video/fbcmap.c |
318 | </sect1> | 490 | </sect1> |
diff --git a/Documentation/DocBook/stylesheet.xsl b/Documentation/DocBook/stylesheet.xsl new file mode 100644 index 000000000000..e14c21dda403 --- /dev/null +++ b/Documentation/DocBook/stylesheet.xsl | |||
@@ -0,0 +1,5 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0"> | ||
3 | <param name="chunk.quietly">1</param> | ||
4 | <param name="funcsynopsis.style">ansi</param> | ||
5 | </stylesheet> | ||
diff --git a/Documentation/DocBook/tulip-user.tmpl b/Documentation/DocBook/tulip-user.tmpl deleted file mode 100644 index 6520d7a1b132..000000000000 --- a/Documentation/DocBook/tulip-user.tmpl +++ /dev/null | |||
@@ -1,327 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | ||
3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | ||
4 | |||
5 | <book id="TulipUserGuide"> | ||
6 | <bookinfo> | ||
7 | <title>Tulip Driver User's Guide</title> | ||
8 | |||
9 | <authorgroup> | ||
10 | <author> | ||
11 | <firstname>Jeff</firstname> | ||
12 | <surname>Garzik</surname> | ||
13 | <affiliation> | ||
14 | <address> | ||
15 | <email>jgarzik@pobox.com</email> | ||
16 | </address> | ||
17 | </affiliation> | ||
18 | </author> | ||
19 | </authorgroup> | ||
20 | |||
21 | <copyright> | ||
22 | <year>2001</year> | ||
23 | <holder>Jeff Garzik</holder> | ||
24 | </copyright> | ||
25 | |||
26 | <legalnotice> | ||
27 | <para> | ||
28 | This documentation is free software; you can redistribute | ||
29 | it and/or modify it under the terms of the GNU General Public | ||
30 | License as published by the Free Software Foundation; either | ||
31 | version 2 of the License, or (at your option) any later | ||
32 | version. | ||
33 | </para> | ||
34 | |||
35 | <para> | ||
36 | This program is distributed in the hope that it will be | ||
37 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
38 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
39 | See the GNU General Public License for more details. | ||
40 | </para> | ||
41 | |||
42 | <para> | ||
43 | You should have received a copy of the GNU General Public | ||
44 | License along with this program; if not, write to the Free | ||
45 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
46 | MA 02111-1307 USA | ||
47 | </para> | ||
48 | |||
49 | <para> | ||
50 | For more details see the file COPYING in the source | ||
51 | distribution of Linux. | ||
52 | </para> | ||
53 | </legalnotice> | ||
54 | </bookinfo> | ||
55 | |||
56 | <toc></toc> | ||
57 | |||
58 | <chapter id="intro"> | ||
59 | <title>Introduction</title> | ||
60 | <para> | ||
61 | The Tulip Ethernet Card Driver | ||
62 | is maintained by Jeff Garzik (<email>jgarzik@pobox.com</email>). | ||
63 | </para> | ||
64 | |||
65 | <para> | ||
66 | The Tulip driver was developed by Donald Becker and changed by | ||
67 | Jeff Garzik, Takashi Manabe and a cast of thousands. | ||
68 | </para> | ||
69 | |||
70 | <para> | ||
71 | For 2.4.x and later kernels, the Linux Tulip driver is available at | ||
72 | <ulink url="http://sourceforge.net/projects/tulip/">http://sourceforge.net/projects/tulip/</ulink> | ||
73 | </para> | ||
74 | |||
75 | <para> | ||
76 | This driver is for the Digital "Tulip" Ethernet adapter interface. | ||
77 | It should work with most DEC 21*4*-based chips/ethercards, as well as | ||
78 | with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and ASIX. | ||
79 | </para> | ||
80 | |||
81 | <para> | ||
82 | The original author may be reached as becker@scyld.com, or C/O | ||
83 | Scyld Computing Corporation, | ||
84 | 410 Severn Ave., Suite 210, | ||
85 | Annapolis MD 21403 | ||
86 | </para> | ||
87 | |||
88 | <para> | ||
89 | Additional information on Donald Becker's tulip.c | ||
90 | is available at <ulink url="http://www.scyld.com/network/tulip.html">http://www.scyld.com/network/tulip.html</ulink> | ||
91 | </para> | ||
92 | |||
93 | </chapter> | ||
94 | |||
95 | <chapter id="drvr-compat"> | ||
96 | <title>Driver Compatibility</title> | ||
97 | |||
98 | <para> | ||
99 | This device driver is designed for the DECchip "Tulip", Digital's | ||
100 | single-chip ethernet controllers for PCI (now owned by Intel). | ||
101 | Supported members of the family | ||
102 | are the 21040, 21041, 21140, 21140A, 21142, and 21143. Similar work-alike | ||
103 | chips from Lite-On, Macronics, ASIX, Compex and other listed below are also | ||
104 | supported. | ||
105 | </para> | ||
106 | |||
107 | <para> | ||
108 | These chips are used on at least 140 unique PCI board designs. The great | ||
109 | number of chips and board designs supported is the reason for the | ||
110 | driver size and complexity. Almost of the increasing complexity is in the | ||
111 | board configuration and media selection code. There is very little | ||
112 | increasing in the operational critical path length. | ||
113 | </para> | ||
114 | </chapter> | ||
115 | |||
116 | <chapter id="board-settings"> | ||
117 | <title>Board-specific Settings</title> | ||
118 | |||
119 | <para> | ||
120 | PCI bus devices are configured by the system at boot time, so no jumpers | ||
121 | need to be set on the board. The system BIOS preferably should assign the | ||
122 | PCI INTA signal to an otherwise unused system IRQ line. | ||
123 | </para> | ||
124 | |||
125 | <para> | ||
126 | Some boards have EEPROMs tables with default media entry. The factory default | ||
127 | is usually "autoselect". This should only be overridden when using | ||
128 | transceiver connections without link beat e.g. 10base2 or AUI, or (rarely!) | ||
129 | for forcing full-duplex when used with old link partners that do not do | ||
130 | autonegotiation. | ||
131 | </para> | ||
132 | </chapter> | ||
133 | |||
134 | <chapter id="driver-operation"> | ||
135 | <title>Driver Operation</title> | ||
136 | |||
137 | <sect1><title>Ring buffers</title> | ||
138 | |||
139 | <para> | ||
140 | The Tulip can use either ring buffers or lists of Tx and Rx descriptors. | ||
141 | This driver uses statically allocated rings of Rx and Tx descriptors, set at | ||
142 | compile time by RX/TX_RING_SIZE. This version of the driver allocates skbuffs | ||
143 | for the Rx ring buffers at open() time and passes the skb->data field to the | ||
144 | Tulip as receive data buffers. When an incoming frame is less than | ||
145 | RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is | ||
146 | copied to the new skbuff. When the incoming frame is larger, the skbuff is | ||
147 | passed directly up the protocol stack and replaced by a newly allocated | ||
148 | skbuff. | ||
149 | </para> | ||
150 | |||
151 | <para> | ||
152 | The RX_COPYBREAK value is chosen to trade-off the memory wasted by | ||
153 | using a full-sized skbuff for small frames vs. the copying costs of larger | ||
154 | frames. For small frames the copying cost is negligible (esp. considering | ||
155 | that we are pre-loading the cache with immediately useful header | ||
156 | information). For large frames the copying cost is non-trivial, and the | ||
157 | larger copy might flush the cache of useful data. A subtle aspect of this | ||
158 | choice is that the Tulip only receives into longword aligned buffers, thus | ||
159 | the IP header at offset 14 isn't longword aligned for further processing. | ||
160 | Copied frames are put into the new skbuff at an offset of "+2", thus copying | ||
161 | has the beneficial effect of aligning the IP header and preloading the | ||
162 | cache. | ||
163 | </para> | ||
164 | |||
165 | </sect1> | ||
166 | |||
167 | <sect1><title>Synchronization</title> | ||
168 | <para> | ||
169 | The driver runs as two independent, single-threaded flows of control. One | ||
170 | is the send-packet routine, which enforces single-threaded use by the | ||
171 | dev->tbusy flag. The other thread is the interrupt handler, which is single | ||
172 | threaded by the hardware and other software. | ||
173 | </para> | ||
174 | |||
175 | <para> | ||
176 | The send packet thread has partial control over the Tx ring and 'dev->tbusy' | ||
177 | flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next | ||
178 | queue slot is empty, it clears the tbusy flag when finished otherwise it sets | ||
179 | the 'tp->tx_full' flag. | ||
180 | </para> | ||
181 | |||
182 | <para> | ||
183 | The interrupt handler has exclusive control over the Rx ring and records stats | ||
184 | from the Tx ring. (The Tx-done interrupt can't be selectively turned off, so | ||
185 | we can't avoid the interrupt overhead by having the Tx routine reap the Tx | ||
186 | stats.) After reaping the stats, it marks the queue entry as empty by setting | ||
187 | the 'base' to zero. Iff the 'tp->tx_full' flag is set, it clears both the | ||
188 | tx_full and tbusy flags. | ||
189 | </para> | ||
190 | |||
191 | </sect1> | ||
192 | |||
193 | </chapter> | ||
194 | |||
195 | <chapter id="errata"> | ||
196 | <title>Errata</title> | ||
197 | |||
198 | <para> | ||
199 | The old DEC databooks were light on details. | ||
200 | The 21040 databook claims that CSR13, CSR14, and CSR15 should each be the last | ||
201 | register of the set CSR12-15 written. Hmmm, now how is that possible? | ||
202 | </para> | ||
203 | |||
204 | <para> | ||
205 | The DEC SROM format is very badly designed not precisely defined, leading to | ||
206 | part of the media selection junkheap below. Some boards do not have EEPROM | ||
207 | media tables and need to be patched up. Worse, other boards use the DEC | ||
208 | design kit media table when it isn't correct for their board. | ||
209 | </para> | ||
210 | |||
211 | <para> | ||
212 | We cannot use MII interrupts because there is no defined GPIO pin to attach | ||
213 | them. The MII transceiver status is polled using an kernel timer. | ||
214 | </para> | ||
215 | </chapter> | ||
216 | |||
217 | <chapter id="changelog"> | ||
218 | <title>Driver Change History</title> | ||
219 | |||
220 | <sect1><title>Version 0.9.14 (February 20, 2001)</title> | ||
221 | <itemizedlist> | ||
222 | <listitem><para>Fix PNIC problems (Manfred Spraul)</para></listitem> | ||
223 | <listitem><para>Add new PCI id for Accton comet</para></listitem> | ||
224 | <listitem><para>Support Davicom tulips</para></listitem> | ||
225 | <listitem><para>Fix oops in eeprom parsing</para></listitem> | ||
226 | <listitem><para>Enable workarounds for early PCI chipsets</para></listitem> | ||
227 | <listitem><para>IA64, hppa csr0 support</para></listitem> | ||
228 | <listitem><para>Support media types 5, 6</para></listitem> | ||
229 | <listitem><para>Interpret a bit more of the 21142 SROM extended media type 3</para></listitem> | ||
230 | <listitem><para>Add missing delay in eeprom reading</para></listitem> | ||
231 | </itemizedlist> | ||
232 | </sect1> | ||
233 | |||
234 | <sect1><title>Version 0.9.11 (November 3, 2000)</title> | ||
235 | <itemizedlist> | ||
236 | <listitem><para>Eliminate extra bus accesses when sharing interrupts (prumpf)</para></listitem> | ||
237 | <listitem><para>Barrier following ownership descriptor bit flip (prumpf)</para></listitem> | ||
238 | <listitem><para>Endianness fixes for >14 addresses in setup frames (prumpf)</para></listitem> | ||
239 | <listitem><para>Report link beat to kernel/userspace via netif_carrier_*. (kuznet)</para></listitem> | ||
240 | <listitem><para>Better spinlocking in set_rx_mode.</para></listitem> | ||
241 | <listitem><para>Fix I/O resource request failure error messages (DaveM catch)</para></listitem> | ||
242 | <listitem><para>Handle DMA allocation failure.</para></listitem> | ||
243 | </itemizedlist> | ||
244 | </sect1> | ||
245 | |||
246 | <sect1><title>Version 0.9.10 (September 6, 2000)</title> | ||
247 | <itemizedlist> | ||
248 | <listitem><para>Simple interrupt mitigation (via jamal)</para></listitem> | ||
249 | <listitem><para>More PCI ids</para></listitem> | ||
250 | </itemizedlist> | ||
251 | </sect1> | ||
252 | |||
253 | <sect1><title>Version 0.9.9 (August 11, 2000)</title> | ||
254 | <itemizedlist> | ||
255 | <listitem><para>More PCI ids</para></listitem> | ||
256 | </itemizedlist> | ||
257 | </sect1> | ||
258 | |||
259 | <sect1><title>Version 0.9.8 (July 13, 2000)</title> | ||
260 | <itemizedlist> | ||
261 | <listitem><para>Correct signed/unsigned comparison for dummy frame index</para></listitem> | ||
262 | <listitem><para>Remove outdated references to struct enet_statistics</para></listitem> | ||
263 | </itemizedlist> | ||
264 | </sect1> | ||
265 | |||
266 | <sect1><title>Version 0.9.7 (June 17, 2000)</title> | ||
267 | <itemizedlist> | ||
268 | <listitem><para>Timer cleanups (Andrew Morton)</para></listitem> | ||
269 | <listitem><para>Alpha compile fix (somebody?)</para></listitem> | ||
270 | </itemizedlist> | ||
271 | </sect1> | ||
272 | |||
273 | <sect1><title>Version 0.9.6 (May 31, 2000)</title> | ||
274 | <itemizedlist> | ||
275 | <listitem><para>Revert 21143-related support flag patch</para></listitem> | ||
276 | <listitem><para>Add HPPA/media-table debugging printk</para></listitem> | ||
277 | </itemizedlist> | ||
278 | </sect1> | ||
279 | |||
280 | <sect1><title>Version 0.9.5 (May 30, 2000)</title> | ||
281 | <itemizedlist> | ||
282 | <listitem><para>HPPA support (willy@puffingroup)</para></listitem> | ||
283 | <listitem><para>CSR6 bits and tulip.h cleanup (Chris Smith)</para></listitem> | ||
284 | <listitem><para>Improve debugging messages a bit</para></listitem> | ||
285 | <listitem><para>Add delay after CSR13 write in t21142_start_nway</para></listitem> | ||
286 | <listitem><para>Remove unused ETHER_STATS code</para></listitem> | ||
287 | <listitem><para>Convert 'extern inline' to 'static inline' in tulip.h (Chris Smith)</para></listitem> | ||
288 | <listitem><para>Update DS21143 support flags in tulip_chip_info[]</para></listitem> | ||
289 | <listitem><para>Use spin_lock_irq, not _irqsave/restore, in tulip_start_xmit()</para></listitem> | ||
290 | <listitem><para>Add locking to set_rx_mode()</para></listitem> | ||
291 | <listitem><para>Fix race with chip setting DescOwned bit (Hal Murray)</para></listitem> | ||
292 | <listitem><para>Request 100% of PIO and MMIO resource space assigned to card</para></listitem> | ||
293 | <listitem><para>Remove error message from pci_enable_device failure</para></listitem> | ||
294 | </itemizedlist> | ||
295 | </sect1> | ||
296 | |||
297 | <sect1><title>Version 0.9.4.3 (April 14, 2000)</title> | ||
298 | <itemizedlist> | ||
299 | <listitem><para>mod_timer fix (Hal Murray)</para></listitem> | ||
300 | <listitem><para>PNIC2 resuscitation (Chris Smith)</para></listitem> | ||
301 | </itemizedlist> | ||
302 | </sect1> | ||
303 | |||
304 | <sect1><title>Version 0.9.4.2 (March 21, 2000)</title> | ||
305 | <itemizedlist> | ||
306 | <listitem><para>Fix 21041 CSR7, CSR13/14/15 handling</para></listitem> | ||
307 | <listitem><para>Merge some PCI ids from tulip 0.91x</para></listitem> | ||
308 | <listitem><para>Merge some HAS_xxx flags and flag settings from tulip 0.91x</para></listitem> | ||
309 | <listitem><para>asm/io.h fix (submitted by many) and cleanup</para></listitem> | ||
310 | <listitem><para>s/HAS_NWAY143/HAS_NWAY/</para></listitem> | ||
311 | <listitem><para>Cleanup 21041 mode reporting</para></listitem> | ||
312 | <listitem><para>Small code cleanups</para></listitem> | ||
313 | </itemizedlist> | ||
314 | </sect1> | ||
315 | |||
316 | <sect1><title>Version 0.9.4.1 (March 18, 2000)</title> | ||
317 | <itemizedlist> | ||
318 | <listitem><para>Finish PCI DMA conversion (davem)</para></listitem> | ||
319 | <listitem><para>Do not netif_start_queue() at end of tulip_tx_timeout() (kuznet)</para></listitem> | ||
320 | <listitem><para>PCI DMA fix (kuznet)</para></listitem> | ||
321 | <listitem><para>eeprom.c code cleanup</para></listitem> | ||
322 | <listitem><para>Remove Xircom Tulip crud</para></listitem> | ||
323 | </itemizedlist> | ||
324 | </sect1> | ||
325 | </chapter> | ||
326 | |||
327 | </book> | ||
diff --git a/Documentation/DocBook/via-audio.tmpl b/Documentation/DocBook/via-audio.tmpl deleted file mode 100644 index 36e642147d6b..000000000000 --- a/Documentation/DocBook/via-audio.tmpl +++ /dev/null | |||
@@ -1,597 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | ||
3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | ||
4 | |||
5 | <book id="ViaAudioGuide"> | ||
6 | <bookinfo> | ||
7 | <title>Via 686 Audio Driver for Linux</title> | ||
8 | |||
9 | <authorgroup> | ||
10 | <author> | ||
11 | <firstname>Jeff</firstname> | ||
12 | <surname>Garzik</surname> | ||
13 | </author> | ||
14 | </authorgroup> | ||
15 | |||
16 | <copyright> | ||
17 | <year>1999-2001</year> | ||
18 | <holder>Jeff Garzik</holder> | ||
19 | </copyright> | ||
20 | |||
21 | <legalnotice> | ||
22 | <para> | ||
23 | This documentation is free software; you can redistribute | ||
24 | it and/or modify it under the terms of the GNU General Public | ||
25 | License as published by the Free Software Foundation; either | ||
26 | version 2 of the License, or (at your option) any later | ||
27 | version. | ||
28 | </para> | ||
29 | |||
30 | <para> | ||
31 | This program is distributed in the hope that it will be | ||
32 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
33 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
34 | See the GNU General Public License for more details. | ||
35 | </para> | ||
36 | |||
37 | <para> | ||
38 | You should have received a copy of the GNU General Public | ||
39 | License along with this program; if not, write to the Free | ||
40 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
41 | MA 02111-1307 USA | ||
42 | </para> | ||
43 | |||
44 | <para> | ||
45 | For more details see the file COPYING in the source | ||
46 | distribution of Linux. | ||
47 | </para> | ||
48 | </legalnotice> | ||
49 | </bookinfo> | ||
50 | |||
51 | <toc></toc> | ||
52 | |||
53 | <chapter id="intro"> | ||
54 | <title>Introduction</title> | ||
55 | <para> | ||
56 | The Via VT82C686A "super southbridge" chips contain | ||
57 | AC97-compatible audio logic which features dual 16-bit stereo | ||
58 | PCM sound channels (full duplex), plus a third PCM channel intended for use | ||
59 | in hardware-assisted FM synthesis. | ||
60 | </para> | ||
61 | <para> | ||
62 | The current Linux kernel audio driver for this family of chips | ||
63 | supports audio playback and recording, but hardware-assisted | ||
64 | FM features, and hardware buffer direct-access (mmap) | ||
65 | support are not yet available. | ||
66 | </para> | ||
67 | <para> | ||
68 | This driver supports any Linux kernel version after 2.4.10. | ||
69 | </para> | ||
70 | <para> | ||
71 | Please send bug reports to the mailing list <email>linux-via@gtf.org</email>. | ||
72 | To subscribe, e-mail <email>majordomo@gtf.org</email> with | ||
73 | </para> | ||
74 | <programlisting> | ||
75 | subscribe linux-via | ||
76 | </programlisting> | ||
77 | <para> | ||
78 | in the body of the message. | ||
79 | </para> | ||
80 | </chapter> | ||
81 | |||
82 | <chapter id="install"> | ||
83 | <title>Driver Installation</title> | ||
84 | <para> | ||
85 | To use this audio driver, select the | ||
86 | CONFIG_SOUND_VIA82CXXX option in the section Sound during kernel configuration. | ||
87 | Follow the usual kernel procedures for rebuilding the kernel, | ||
88 | or building and installing driver modules. | ||
89 | </para> | ||
90 | <para> | ||
91 | To make this driver the default audio driver, you can add the | ||
92 | following to your /etc/conf.modules file: | ||
93 | </para> | ||
94 | <programlisting> | ||
95 | alias sound via82cxxx_audio | ||
96 | </programlisting> | ||
97 | <para> | ||
98 | Note that soundcore and ac97_codec support modules | ||
99 | are also required for working audio, in addition to | ||
100 | the via82cxxx_audio module itself. | ||
101 | </para> | ||
102 | </chapter> | ||
103 | |||
104 | <chapter id="reportbug"> | ||
105 | <title>Submitting a bug report</title> | ||
106 | <sect1 id="bugrepdesc"><title>Description of problem</title> | ||
107 | <para> | ||
108 | Describe the application you were using to play/record sound, and how | ||
109 | to reproduce the problem. | ||
110 | </para> | ||
111 | </sect1> | ||
112 | <sect1 id="bugrepdiag"><title>Diagnostic output</title> | ||
113 | <para> | ||
114 | Obtain the via-audio-diag diagnostics program from | ||
115 | http://sf.net/projects/gkernel/ and provide a dump of the | ||
116 | audio chip's registers while the problem is occurring. Sample command line: | ||
117 | </para> | ||
118 | <programlisting> | ||
119 | ./via-audio-diag -aps > diag-output.txt | ||
120 | </programlisting> | ||
121 | </sect1> | ||
122 | <sect1 id="bugrepdebug"><title>Driver debug output</title> | ||
123 | <para> | ||
124 | Define <constant>VIA_DEBUG</constant> at the beginning of the driver, then capture and email | ||
125 | the kernel log output. This can be viewed in the system kernel log (if | ||
126 | enabled), or via the dmesg program. Sample command line: | ||
127 | </para> | ||
128 | <programlisting> | ||
129 | dmesg > /tmp/dmesg-output.txt | ||
130 | </programlisting> | ||
131 | </sect1> | ||
132 | <sect1 id="bugrepprintk"><title>Bigger kernel message buffer</title> | ||
133 | <para> | ||
134 | If you wish to increase the size of the buffer displayed by dmesg, then | ||
135 | change the <constant>LOG_BUF_LEN</constant> macro at the top of linux/kernel/printk.c, recompile | ||
136 | your kernel, and pass the <constant>LOG_BUF_LEN</constant> value to dmesg. Sample command line with | ||
137 | <constant>LOG_BUF_LEN</constant> == 32768: | ||
138 | </para> | ||
139 | <programlisting> | ||
140 | dmesg -s 32768 > /tmp/dmesg-output.txt | ||
141 | </programlisting> | ||
142 | </sect1> | ||
143 | </chapter> | ||
144 | |||
145 | <chapter id="bugs"> | ||
146 | <title>Known Bugs And Assumptions</title> | ||
147 | <para> | ||
148 | <variablelist> | ||
149 | <varlistentry><term>Low volume</term> | ||
150 | <listitem> | ||
151 | <para> | ||
152 | Volume too low on many systems. Workaround: use mixer program | ||
153 | such as xmixer to increase volume. | ||
154 | </para> | ||
155 | </listitem></varlistentry> | ||
156 | |||
157 | </variablelist> | ||
158 | |||
159 | </para> | ||
160 | </chapter> | ||
161 | |||
162 | <chapter id="thanks"> | ||
163 | <title>Thanks</title> | ||
164 | <para> | ||
165 | Via for providing e-mail support, specs, and NDA'd source code. | ||
166 | </para> | ||
167 | <para> | ||
168 | MandrakeSoft for providing hacking time. | ||
169 | </para> | ||
170 | <para> | ||
171 | AC97 mixer interface fixes and debugging by Ron Cemer <email>roncemer@gte.net</email>. | ||
172 | </para> | ||
173 | <para> | ||
174 | Rui Sousa <email>rui.sousa@conexant.com</email>, for bugfixing | ||
175 | MMAP support, and several other notable fixes that resulted from | ||
176 | his hard work and testing. | ||
177 | </para> | ||
178 | <para> | ||
179 | Adrian Cox <email>adrian@humboldt.co.uk</email>, for bugfixing | ||
180 | MMAP support, and several other notable fixes that resulted from | ||
181 | his hard work and testing. | ||
182 | </para> | ||
183 | <para> | ||
184 | Thomas Sailer for further bugfixes. | ||
185 | </para> | ||
186 | </chapter> | ||
187 | |||
188 | <chapter id="notes"> | ||
189 | <title>Random Notes</title> | ||
190 | <para> | ||
191 | Two /proc pseudo-files provide diagnostic information. This is generally | ||
192 | not useful to most users. Power users can disable CONFIG_SOUND_VIA82CXXX_PROCFS, | ||
193 | and remove the /proc support code. Once | ||
194 | version 2.0.0 is released, the /proc support code will be disabled by | ||
195 | default. Available /proc pseudo-files: | ||
196 | </para> | ||
197 | <programlisting> | ||
198 | /proc/driver/via/0/info | ||
199 | /proc/driver/via/0/ac97 | ||
200 | </programlisting> | ||
201 | <para> | ||
202 | This driver by default supports all PCI audio devices which report | ||
203 | a vendor id of 0x1106, and a device id of 0x3058. Subsystem vendor | ||
204 | and device ids are not examined. | ||
205 | </para> | ||
206 | <para> | ||
207 | GNU indent formatting options: | ||
208 | <programlisting> | ||
209 | -kr -i8 -ts8 -br -ce -bap -sob -l80 -pcs -cs -ss -bs -di1 -nbc -lp -psl | ||
210 | </programlisting> | ||
211 | </para> | ||
212 | <para> | ||
213 | Via has graciously donated e-mail support and source code to help further | ||
214 | the development of this driver. Their assistance has been invaluable | ||
215 | in the design and coding of the next major version of this driver. | ||
216 | </para> | ||
217 | <para> | ||
218 | The Via audio chip apparently provides a second PCM scatter-gather | ||
219 | DMA channel just for FM data, but does not have a full hardware MIDI | ||
220 | processor. I haven't put much thought towards a solution here, but it | ||
221 | might involve using SoftOSS midi wave table, or simply disabling MIDI | ||
222 | support altogether and using the FM PCM channel as a second (input? output?) | ||
223 | </para> | ||
224 | </chapter> | ||
225 | |||
226 | <chapter id="changelog"> | ||
227 | <title>Driver ChangeLog</title> | ||
228 | |||
229 | <sect1 id="version191"><title> | ||
230 | Version 1.9.1 | ||
231 | </title> | ||
232 | <itemizedlist spacing="compact"> | ||
233 | <listitem> | ||
234 | <para> | ||
235 | DSP read/write bugfixes from Thomas Sailer. | ||
236 | </para> | ||
237 | </listitem> | ||
238 | |||
239 | <listitem> | ||
240 | <para> | ||
241 | Add new PCI id for single-channel use of Via 8233. | ||
242 | </para> | ||
243 | </listitem> | ||
244 | |||
245 | <listitem> | ||
246 | <para> | ||
247 | Other bug fixes, tweaks, new ioctls. | ||
248 | </para> | ||
249 | </listitem> | ||
250 | |||
251 | </itemizedlist> | ||
252 | </sect1> | ||
253 | |||
254 | <sect1 id="version1115"><title> | ||
255 | Version 1.1.15 | ||
256 | </title> | ||
257 | <itemizedlist spacing="compact"> | ||
258 | <listitem> | ||
259 | <para> | ||
260 | Support for variable fragment size and variable fragment number (Rui | ||
261 | Sousa) | ||
262 | </para> | ||
263 | </listitem> | ||
264 | |||
265 | <listitem> | ||
266 | <para> | ||
267 | Fixes for the SPEED, STEREO, CHANNELS, FMT ioctls when in read & | ||
268 | write mode (Rui Sousa) | ||
269 | </para> | ||
270 | </listitem> | ||
271 | |||
272 | <listitem> | ||
273 | <para> | ||
274 | Mmaped sound is now fully functional. (Rui Sousa) | ||
275 | </para> | ||
276 | </listitem> | ||
277 | |||
278 | <listitem> | ||
279 | <para> | ||
280 | Make sure to enable PCI device before reading any of its PCI | ||
281 | config information. (fixes potential hotplug problems) | ||
282 | </para> | ||
283 | </listitem> | ||
284 | |||
285 | <listitem> | ||
286 | <para> | ||
287 | Clean up code a bit and add more internal function documentation. | ||
288 | </para> | ||
289 | </listitem> | ||
290 | |||
291 | <listitem> | ||
292 | <para> | ||
293 | AC97 codec access fixes (Adrian Cox) | ||
294 | </para> | ||
295 | </listitem> | ||
296 | |||
297 | <listitem> | ||
298 | <para> | ||
299 | Big endian fixes (Adrian Cox) | ||
300 | </para> | ||
301 | </listitem> | ||
302 | |||
303 | <listitem> | ||
304 | <para> | ||
305 | MIDI support (Adrian Cox) | ||
306 | </para> | ||
307 | </listitem> | ||
308 | |||
309 | <listitem> | ||
310 | <para> | ||
311 | Detect and report locked-rate AC97 codecs. If your hardware only | ||
312 | supports 48Khz (locked rate), then your recording/playback software | ||
313 | must upsample or downsample accordingly. The hardware cannot do it. | ||
314 | </para> | ||
315 | </listitem> | ||
316 | |||
317 | <listitem> | ||
318 | <para> | ||
319 | Use new pci_request_regions and pci_disable_device functions in | ||
320 | kernel 2.4.6. | ||
321 | </para> | ||
322 | </listitem> | ||
323 | |||
324 | </itemizedlist> | ||
325 | </sect1> | ||
326 | |||
327 | <sect1 id="version1114"><title> | ||
328 | Version 1.1.14 | ||
329 | </title> | ||
330 | <itemizedlist spacing="compact"> | ||
331 | <listitem> | ||
332 | <para> | ||
333 | Use VM_RESERVE when available, to eliminate unnecessary page faults. | ||
334 | </para> | ||
335 | </listitem> | ||
336 | </itemizedlist> | ||
337 | </sect1> | ||
338 | |||
339 | <sect1 id="version1112"><title> | ||
340 | Version 1.1.12 | ||
341 | </title> | ||
342 | <itemizedlist spacing="compact"> | ||
343 | <listitem> | ||
344 | <para> | ||
345 | mmap bug fixes from Linus. | ||
346 | </para> | ||
347 | </listitem> | ||
348 | </itemizedlist> | ||
349 | </sect1> | ||
350 | |||
351 | <sect1 id="version1111"><title> | ||
352 | Version 1.1.11 | ||
353 | </title> | ||
354 | <itemizedlist spacing="compact"> | ||
355 | <listitem> | ||
356 | <para> | ||
357 | Many more bug fixes. mmap enabled by default, but may still be buggy. | ||
358 | </para> | ||
359 | </listitem> | ||
360 | |||
361 | <listitem> | ||
362 | <para> | ||
363 | Uses new and spiffy method of mmap'ing the DMA buffer, based | ||
364 | on a suggestion from Linus. | ||
365 | </para> | ||
366 | </listitem> | ||
367 | </itemizedlist> | ||
368 | </sect1> | ||
369 | |||
370 | <sect1 id="version1110"><title> | ||
371 | Version 1.1.10 | ||
372 | </title> | ||
373 | <itemizedlist spacing="compact"> | ||
374 | <listitem> | ||
375 | <para> | ||
376 | Many bug fixes. mmap enabled by default, but may still be buggy. | ||
377 | </para> | ||
378 | </listitem> | ||
379 | </itemizedlist> | ||
380 | </sect1> | ||
381 | |||
382 | <sect1 id="version119"><title> | ||
383 | Version 1.1.9 | ||
384 | </title> | ||
385 | <itemizedlist spacing="compact"> | ||
386 | <listitem> | ||
387 | <para> | ||
388 | Redesign and rewrite audio playback implementation. (faster and smaller, hopefully) | ||
389 | </para> | ||
390 | </listitem> | ||
391 | |||
392 | <listitem> | ||
393 | <para> | ||
394 | Implement recording and full duplex (DSP_CAP_DUPLEX) support. | ||
395 | </para> | ||
396 | </listitem> | ||
397 | |||
398 | <listitem> | ||
399 | <para> | ||
400 | Make procfs support optional. | ||
401 | </para> | ||
402 | </listitem> | ||
403 | |||
404 | <listitem> | ||
405 | <para> | ||
406 | Quick interrupt status check, to lessen overhead in interrupt | ||
407 | sharing situations. | ||
408 | </para> | ||
409 | </listitem> | ||
410 | |||
411 | <listitem> | ||
412 | <para> | ||
413 | Add mmap(2) support. Disabled for now, it is still buggy and experimental. | ||
414 | </para> | ||
415 | </listitem> | ||
416 | |||
417 | <listitem> | ||
418 | <para> | ||
419 | Surround all syscalls with a semaphore for cheap and easy SMP protection. | ||
420 | </para> | ||
421 | </listitem> | ||
422 | |||
423 | <listitem> | ||
424 | <para> | ||
425 | Fix bug in channel shutdown (hardware channel reset) code. | ||
426 | </para> | ||
427 | </listitem> | ||
428 | |||
429 | <listitem> | ||
430 | <para> | ||
431 | Remove unnecessary spinlocks (better performance). | ||
432 | </para> | ||
433 | </listitem> | ||
434 | |||
435 | <listitem> | ||
436 | <para> | ||
437 | Eliminate "unknown AFMT" message by using a different method | ||
438 | of selecting the best AFMT_xxx sound sample format for use. | ||
439 | </para> | ||
440 | </listitem> | ||
441 | |||
442 | <listitem> | ||
443 | <para> | ||
444 | Support for realtime hardware pointer position reporting | ||
445 | (DSP_CAP_REALTIME, SNDCTL_DSP_GETxPTR ioctls) | ||
446 | </para> | ||
447 | </listitem> | ||
448 | |||
449 | <listitem> | ||
450 | <para> | ||
451 | Support for capture/playback triggering | ||
452 | (DSP_CAP_TRIGGER, SNDCTL_DSP_SETTRIGGER ioctls) | ||
453 | </para> | ||
454 | </listitem> | ||
455 | |||
456 | <listitem> | ||
457 | <para> | ||
458 | SNDCTL_DSP_SETDUPLEX and SNDCTL_DSP_POST ioctls now handled. | ||
459 | </para> | ||
460 | </listitem> | ||
461 | |||
462 | <listitem> | ||
463 | <para> | ||
464 | Rewrite open(2) and close(2) logic to allow only one user at | ||
465 | a time. All other open(2) attempts will sleep until they succeed. | ||
466 | FIXME: open(O_RDONLY) and open(O_WRONLY) should be allowed to succeed. | ||
467 | </para> | ||
468 | </listitem> | ||
469 | |||
470 | <listitem> | ||
471 | <para> | ||
472 | Reviewed code to ensure that SMP and multiple audio devices | ||
473 | are fully supported. | ||
474 | </para> | ||
475 | </listitem> | ||
476 | |||
477 | </itemizedlist> | ||
478 | </sect1> | ||
479 | |||
480 | <sect1 id="version118"><title> | ||
481 | Version 1.1.8 | ||
482 | </title> | ||
483 | <itemizedlist spacing="compact"> | ||
484 | <listitem> | ||
485 | <para> | ||
486 | Clean up interrupt handler output. Fixes the following kernel error message: | ||
487 | </para> | ||
488 | <programlisting> | ||
489 | unhandled interrupt ... | ||
490 | </programlisting> | ||
491 | </listitem> | ||
492 | |||
493 | <listitem> | ||
494 | <para> | ||
495 | Convert documentation to DocBook, so that PDF, HTML and PostScript (.ps) output is readily | ||
496 | available. | ||
497 | </para> | ||
498 | </listitem> | ||
499 | |||
500 | </itemizedlist> | ||
501 | </sect1> | ||
502 | |||
503 | <sect1 id="version117"><title> | ||
504 | Version 1.1.7 | ||
505 | </title> | ||
506 | <itemizedlist spacing="compact"> | ||
507 | <listitem> | ||
508 | <para> | ||
509 | Fix module unload bug where mixer device left registered | ||
510 | after driver exit | ||
511 | </para> | ||
512 | </listitem> | ||
513 | </itemizedlist> | ||
514 | </sect1> | ||
515 | |||
516 | <sect1 id="version116"><title> | ||
517 | Version 1.1.6 | ||
518 | </title> | ||
519 | <itemizedlist spacing="compact"> | ||
520 | <listitem> | ||
521 | <para> | ||
522 | Rewrite via_set_rate to mimic ALSA basic AC97 rate setting | ||
523 | </para> | ||
524 | </listitem> | ||
525 | <listitem> | ||
526 | <para> | ||
527 | Remove much dead code | ||
528 | </para> | ||
529 | </listitem> | ||
530 | <listitem> | ||
531 | <para> | ||
532 | Complete spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl | ||
533 | </para> | ||
534 | </listitem> | ||
535 | <listitem> | ||
536 | <para> | ||
537 | Fix build problem in via_dsp_ioctl | ||
538 | </para> | ||
539 | </listitem> | ||
540 | <listitem> | ||
541 | <para> | ||
542 | Optimize included headers to eliminate headers found in linux/sound | ||
543 | </para> | ||
544 | </listitem> | ||
545 | </itemizedlist> | ||
546 | </sect1> | ||
547 | |||
548 | <sect1 id="version115"><title> | ||
549 | Version 1.1.5 | ||
550 | </title> | ||
551 | <itemizedlist spacing="compact"> | ||
552 | <listitem> | ||
553 | <para> | ||
554 | Disable some overly-verbose debugging code | ||
555 | </para> | ||
556 | </listitem> | ||
557 | <listitem> | ||
558 | <para> | ||
559 | Remove unnecessary sound locks | ||
560 | </para> | ||
561 | </listitem> | ||
562 | <listitem> | ||
563 | <para> | ||
564 | Fix some ioctls for better time resolution | ||
565 | </para> | ||
566 | </listitem> | ||
567 | <listitem> | ||
568 | <para> | ||
569 | Begin spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl | ||
570 | </para> | ||
571 | </listitem> | ||
572 | </itemizedlist> | ||
573 | </sect1> | ||
574 | |||
575 | <sect1 id="version114"><title> | ||
576 | Version 1.1.4 | ||
577 | </title> | ||
578 | <itemizedlist spacing="compact"> | ||
579 | <listitem> | ||
580 | <para> | ||
581 | Completed rewrite of driver. Eliminated SoundBlaster compatibility | ||
582 | completely, and now uses the much-faster scatter-gather DMA engine. | ||
583 | </para> | ||
584 | </listitem> | ||
585 | </itemizedlist> | ||
586 | </sect1> | ||
587 | |||
588 | </chapter> | ||
589 | |||
590 | <chapter id="intfunctions"> | ||
591 | <title>Internal Functions</title> | ||
592 | !Isound/oss/via82cxxx_audio.c | ||
593 | </chapter> | ||
594 | |||
595 | </book> | ||
596 | |||
597 | |||
diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt index 12250b342e1f..9c6d450138ea 100644 --- a/Documentation/RCU/RTFP.txt +++ b/Documentation/RCU/RTFP.txt | |||
@@ -108,8 +108,9 @@ year saw a paper describing an RCU implementation of System V IPC | |||
108 | 2004 has seen a Linux-Journal article on use of RCU in dcache | 108 | 2004 has seen a Linux-Journal article on use of RCU in dcache |
109 | [McKenney04a], a performance comparison of locking to RCU on several | 109 | [McKenney04a], a performance comparison of locking to RCU on several |
110 | different CPUs [McKenney04b], a dissertation describing use of RCU in a | 110 | different CPUs [McKenney04b], a dissertation describing use of RCU in a |
111 | number of operating-system kernels [PaulEdwardMcKenneyPhD], and a paper | 111 | number of operating-system kernels [PaulEdwardMcKenneyPhD], a paper |
112 | describing how to make RCU safe for soft-realtime applications [Sarma04c]. | 112 | describing how to make RCU safe for soft-realtime applications [Sarma04c], |
113 | and a paper describing SELinux performance with RCU [JamesMorris04b]. | ||
113 | 114 | ||
114 | 115 | ||
115 | Bibtex Entries | 116 | Bibtex Entries |
@@ -341,6 +342,17 @@ Dipankar Sarma" | |||
341 | ,pages="18-26" | 342 | ,pages="18-26" |
342 | } | 343 | } |
343 | 344 | ||
345 | @techreport{Friedberg03a | ||
346 | ,author="Stuart A. Friedberg" | ||
347 | ,title="Lock-Free Wild Card Search Data Structure and Method" | ||
348 | ,institution="US Patent and Trademark Office" | ||
349 | ,address="Washington, DC" | ||
350 | ,year="2003" | ||
351 | ,number="US Patent 6,662,184 (contributed under GPL)" | ||
352 | ,month="December" | ||
353 | ,pages="112" | ||
354 | } | ||
355 | |||
344 | @article{McKenney04a | 356 | @article{McKenney04a |
345 | ,author="Paul E. McKenney and Dipankar Sarma and Maneesh Soni" | 357 | ,author="Paul E. McKenney and Dipankar Sarma and Maneesh Soni" |
346 | ,title="Scaling dcache with {RCU}" | 358 | ,title="Scaling dcache with {RCU}" |
@@ -373,6 +385,9 @@ in Operating System Kernels" | |||
373 | ,school="OGI School of Science and Engineering at | 385 | ,school="OGI School of Science and Engineering at |
374 | Oregon Health and Sciences University" | 386 | Oregon Health and Sciences University" |
375 | ,year="2004" | 387 | ,year="2004" |
388 | ,note="Available: | ||
389 | \url{http://www.rdrop.com/users/paulmck/RCU/RCUdissertation.2004.07.14e1.pdf} | ||
390 | [Viewed October 15, 2004]" | ||
376 | } | 391 | } |
377 | 392 | ||
378 | @Conference{Sarma04c | 393 | @Conference{Sarma04c |
@@ -385,3 +400,13 @@ Oregon Health and Sciences University" | |||
385 | ,month="June" | 400 | ,month="June" |
386 | ,pages="182-191" | 401 | ,pages="182-191" |
387 | } | 402 | } |
403 | |||
404 | @unpublished{JamesMorris04b | ||
405 | ,Author="James Morris" | ||
406 | ,Title="Recent Developments in {SELinux} Kernel Performance" | ||
407 | ,month="December" | ||
408 | ,year="2004" | ||
409 | ,note="Available: | ||
410 | \url{http://www.livejournal.com/users/james_morris/2153.html} | ||
411 | [Viewed December 10, 2004]" | ||
412 | } | ||
diff --git a/Documentation/RCU/UP.txt b/Documentation/RCU/UP.txt index 551a803d82a8..3bfb84b3b7db 100644 --- a/Documentation/RCU/UP.txt +++ b/Documentation/RCU/UP.txt | |||
@@ -2,11 +2,11 @@ RCU on Uniprocessor Systems | |||
2 | 2 | ||
3 | 3 | ||
4 | A common misconception is that, on UP systems, the call_rcu() primitive | 4 | A common misconception is that, on UP systems, the call_rcu() primitive |
5 | may immediately invoke its function, and that the synchronize_kernel | 5 | may immediately invoke its function, and that the synchronize_rcu() |
6 | primitive may return immediately. The basis of this misconception | 6 | primitive may return immediately. The basis of this misconception |
7 | is that since there is only one CPU, it should not be necessary to | 7 | is that since there is only one CPU, it should not be necessary to |
8 | wait for anything else to get done, since there are no other CPUs for | 8 | wait for anything else to get done, since there are no other CPUs for |
9 | anything else to be happening on. Although this approach will sort of | 9 | anything else to be happening on. Although this approach will -sort- -of- |
10 | work a surprising amount of the time, it is a very bad idea in general. | 10 | work a surprising amount of the time, it is a very bad idea in general. |
11 | This document presents two examples that demonstrate exactly how bad an | 11 | This document presents two examples that demonstrate exactly how bad an |
12 | idea this is. | 12 | idea this is. |
@@ -44,14 +44,14 @@ its arguments would cause it to fail to make the fundamental guarantee | |||
44 | underlying RCU, namely that call_rcu() defers invoking its arguments until | 44 | underlying RCU, namely that call_rcu() defers invoking its arguments until |
45 | all RCU read-side critical sections currently executing have completed. | 45 | all RCU read-side critical sections currently executing have completed. |
46 | 46 | ||
47 | Quick Quiz: why is it -not- legal to invoke synchronize_kernel() in | 47 | Quick Quiz: why is it -not- legal to invoke synchronize_rcu() in |
48 | this case? | 48 | this case? |
49 | 49 | ||
50 | 50 | ||
51 | Summary | 51 | Summary |
52 | 52 | ||
53 | Permitting call_rcu() to immediately invoke its arguments or permitting | 53 | Permitting call_rcu() to immediately invoke its arguments or permitting |
54 | synchronize_kernel() to immediately return breaks RCU, even on a UP system. | 54 | synchronize_rcu() to immediately return breaks RCU, even on a UP system. |
55 | So do not do it! Even on a UP system, the RCU infrastructure -must- | 55 | So do not do it! Even on a UP system, the RCU infrastructure -must- |
56 | respect grace periods. | 56 | respect grace periods. |
57 | 57 | ||
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index b3a568abe6b1..8f3fb77c9cd3 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt | |||
@@ -32,7 +32,10 @@ over a rather long period of time, but improvements are always welcome! | |||
32 | them -- even x86 allows reads to be reordered), and be prepared | 32 | them -- even x86 allows reads to be reordered), and be prepared |
33 | to explain why this added complexity is worthwhile. If you | 33 | to explain why this added complexity is worthwhile. If you |
34 | choose #c, be prepared to explain how this single task does not | 34 | choose #c, be prepared to explain how this single task does not |
35 | become a major bottleneck on big multiprocessor machines. | 35 | become a major bottleneck on big multiprocessor machines (for |
36 | example, if the task is updating information relating to itself | ||
37 | that other tasks can read, there by definition can be no | ||
38 | bottleneck). | ||
36 | 39 | ||
37 | 2. Do the RCU read-side critical sections make proper use of | 40 | 2. Do the RCU read-side critical sections make proper use of |
38 | rcu_read_lock() and friends? These primitives are needed | 41 | rcu_read_lock() and friends? These primitives are needed |
@@ -89,27 +92,34 @@ over a rather long period of time, but improvements are always welcome! | |||
89 | "_rcu()" list-traversal primitives, such as the | 92 | "_rcu()" list-traversal primitives, such as the |
90 | list_for_each_entry_rcu(). | 93 | list_for_each_entry_rcu(). |
91 | 94 | ||
92 | b. If the list macros are being used, the list_del_rcu(), | 95 | b. If the list macros are being used, the list_add_tail_rcu() |
93 | list_add_tail_rcu(), and list_del_rcu() primitives must | 96 | and list_add_rcu() primitives must be used in order |
94 | be used in order to prevent weakly ordered machines from | 97 | to prevent weakly ordered machines from misordering |
95 | misordering structure initialization and pointer planting. | 98 | structure initialization and pointer planting. |
96 | Similarly, if the hlist macros are being used, the | 99 | Similarly, if the hlist macros are being used, the |
97 | hlist_del_rcu() and hlist_add_head_rcu() primitives | 100 | hlist_add_head_rcu() primitive is required. |
98 | are required. | ||
99 | 101 | ||
100 | c. Updates must ensure that initialization of a given | 102 | c. If the list macros are being used, the list_del_rcu() |
103 | primitive must be used to keep list_del()'s pointer | ||
104 | poisoning from inflicting toxic effects on concurrent | ||
105 | readers. Similarly, if the hlist macros are being used, | ||
106 | the hlist_del_rcu() primitive is required. | ||
107 | |||
108 | The list_replace_rcu() primitive may be used to | ||
109 | replace an old structure with a new one in an | ||
110 | RCU-protected list. | ||
111 | |||
112 | d. Updates must ensure that initialization of a given | ||
101 | structure happens before pointers to that structure are | 113 | structure happens before pointers to that structure are |
102 | publicized. Use the rcu_assign_pointer() primitive | 114 | publicized. Use the rcu_assign_pointer() primitive |
103 | when publicizing a pointer to a structure that can | 115 | when publicizing a pointer to a structure that can |
104 | be traversed by an RCU read-side critical section. | 116 | be traversed by an RCU read-side critical section. |
105 | 117 | ||
106 | [The rcu_assign_pointer() primitive is in process.] | ||
107 | |||
108 | 5. If call_rcu(), or a related primitive such as call_rcu_bh(), | 118 | 5. If call_rcu(), or a related primitive such as call_rcu_bh(), |
109 | is used, the callback function must be written to be called | 119 | is used, the callback function must be written to be called |
110 | from softirq context. In particular, it cannot block. | 120 | from softirq context. In particular, it cannot block. |
111 | 121 | ||
112 | 6. Since synchronize_kernel() blocks, it cannot be called from | 122 | 6. Since synchronize_rcu() can block, it cannot be called from |
113 | any sort of irq context. | 123 | any sort of irq context. |
114 | 124 | ||
115 | 7. If the updater uses call_rcu(), then the corresponding readers | 125 | 7. If the updater uses call_rcu(), then the corresponding readers |
@@ -125,9 +135,9 @@ over a rather long period of time, but improvements are always welcome! | |||
125 | such cases is a must, of course! And the jury is still out on | 135 | such cases is a must, of course! And the jury is still out on |
126 | whether the increased speed is worth it. | 136 | whether the increased speed is worth it. |
127 | 137 | ||
128 | 8. Although synchronize_kernel() is a bit slower than is call_rcu(), | 138 | 8. Although synchronize_rcu() is a bit slower than is call_rcu(), |
129 | it usually results in simpler code. So, unless update performance | 139 | it usually results in simpler code. So, unless update performance |
130 | is important or the updaters cannot block, synchronize_kernel() | 140 | is important or the updaters cannot block, synchronize_rcu() |
131 | should be used in preference to call_rcu(). | 141 | should be used in preference to call_rcu(). |
132 | 142 | ||
133 | 9. All RCU list-traversal primitives, which include | 143 | 9. All RCU list-traversal primitives, which include |
@@ -155,3 +165,14 @@ over a rather long period of time, but improvements are always welcome! | |||
155 | you -must- use the "_rcu()" variants of the list macros. | 165 | you -must- use the "_rcu()" variants of the list macros. |
156 | Failing to do so will break Alpha and confuse people reading | 166 | Failing to do so will break Alpha and confuse people reading |
157 | your code. | 167 | your code. |
168 | |||
169 | 11. Note that synchronize_rcu() -only- guarantees to wait until | ||
170 | all currently executing rcu_read_lock()-protected RCU read-side | ||
171 | critical sections complete. It does -not- necessarily guarantee | ||
172 | that all currently running interrupts, NMIs, preempt_disable() | ||
173 | code, or idle loops will complete. Therefore, if you do not have | ||
174 | rcu_read_lock()-protected read-side critical sections, do -not- | ||
175 | use synchronize_rcu(). | ||
176 | |||
177 | If you want to wait for some of these other things, you might | ||
178 | instead need to use synchronize_irq() or synchronize_sched(). | ||
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt index bda6ead69bd0..f8a54fa0d8ab 100644 --- a/Documentation/RCU/listRCU.txt +++ b/Documentation/RCU/listRCU.txt | |||
@@ -32,6 +32,7 @@ implementation of audit_filter_task() might be as follows: | |||
32 | enum audit_state state; | 32 | enum audit_state state; |
33 | 33 | ||
34 | read_lock(&auditsc_lock); | 34 | read_lock(&auditsc_lock); |
35 | /* Note: audit_netlink_sem held by caller. */ | ||
35 | list_for_each_entry(e, &audit_tsklist, list) { | 36 | list_for_each_entry(e, &audit_tsklist, list) { |
36 | if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { | 37 | if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { |
37 | read_unlock(&auditsc_lock); | 38 | read_unlock(&auditsc_lock); |
@@ -55,6 +56,7 @@ This means that RCU can be easily applied to the read side, as follows: | |||
55 | enum audit_state state; | 56 | enum audit_state state; |
56 | 57 | ||
57 | rcu_read_lock(); | 58 | rcu_read_lock(); |
59 | /* Note: audit_netlink_sem held by caller. */ | ||
58 | list_for_each_entry_rcu(e, &audit_tsklist, list) { | 60 | list_for_each_entry_rcu(e, &audit_tsklist, list) { |
59 | if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { | 61 | if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { |
60 | rcu_read_unlock(); | 62 | rcu_read_unlock(); |
@@ -139,12 +141,15 @@ Normally, the write_lock() and write_unlock() would be replaced by | |||
139 | a spin_lock() and a spin_unlock(), but in this case, all callers hold | 141 | a spin_lock() and a spin_unlock(), but in this case, all callers hold |
140 | audit_netlink_sem, so no additional locking is required. The auditsc_lock | 142 | audit_netlink_sem, so no additional locking is required. The auditsc_lock |
141 | can therefore be eliminated, since use of RCU eliminates the need for | 143 | can therefore be eliminated, since use of RCU eliminates the need for |
142 | writers to exclude readers. | 144 | writers to exclude readers. Normally, the write_lock() calls would |
145 | be converted into spin_lock() calls. | ||
143 | 146 | ||
144 | The list_del(), list_add(), and list_add_tail() primitives have been | 147 | The list_del(), list_add(), and list_add_tail() primitives have been |
145 | replaced by list_del_rcu(), list_add_rcu(), and list_add_tail_rcu(). | 148 | replaced by list_del_rcu(), list_add_rcu(), and list_add_tail_rcu(). |
146 | The _rcu() list-manipulation primitives add memory barriers that are | 149 | The _rcu() list-manipulation primitives add memory barriers that are |
147 | needed on weakly ordered CPUs (most of them!). | 150 | needed on weakly ordered CPUs (most of them!). The list_del_rcu() |
151 | primitive omits the pointer poisoning debug-assist code that would | ||
152 | otherwise cause concurrent readers to fail spectacularly. | ||
148 | 153 | ||
149 | So, when readers can tolerate stale data and when entries are either added | 154 | So, when readers can tolerate stale data and when entries are either added |
150 | or deleted, without in-place modification, it is very easy to use RCU! | 155 | or deleted, without in-place modification, it is very easy to use RCU! |
@@ -166,6 +171,7 @@ otherwise, the added fields would need to be filled in): | |||
166 | struct audit_newentry *ne; | 171 | struct audit_newentry *ne; |
167 | 172 | ||
168 | write_lock(&auditsc_lock); | 173 | write_lock(&auditsc_lock); |
174 | /* Note: audit_netlink_sem held by caller. */ | ||
169 | list_for_each_entry(e, list, list) { | 175 | list_for_each_entry(e, list, list) { |
170 | if (!audit_compare_rule(rule, &e->rule)) { | 176 | if (!audit_compare_rule(rule, &e->rule)) { |
171 | e->rule.action = newaction; | 177 | e->rule.action = newaction; |
@@ -199,8 +205,7 @@ RCU ("read-copy update") its name. The RCU code is as follows: | |||
199 | audit_copy_rule(&ne->rule, &e->rule); | 205 | audit_copy_rule(&ne->rule, &e->rule); |
200 | ne->rule.action = newaction; | 206 | ne->rule.action = newaction; |
201 | ne->rule.file_count = newfield_count; | 207 | ne->rule.file_count = newfield_count; |
202 | list_add_rcu(ne, e); | 208 | list_replace_rcu(e, ne); |
203 | list_del(e); | ||
204 | call_rcu(&e->rcu, audit_free_rule, e); | 209 | call_rcu(&e->rcu, audit_free_rule, e); |
205 | return 0; | 210 | return 0; |
206 | } | 211 | } |
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt index 7e0c2ab6f2bd..eb444006683e 100644 --- a/Documentation/RCU/rcu.txt +++ b/Documentation/RCU/rcu.txt | |||
@@ -43,7 +43,9 @@ o If I am running on a uniprocessor kernel, which can only do one | |||
43 | 43 | ||
44 | o How can I see where RCU is currently used in the Linux kernel? | 44 | o How can I see where RCU is currently used in the Linux kernel? |
45 | 45 | ||
46 | Search for "rcu_read_lock", "call_rcu", and "synchronize_kernel". | 46 | Search for "rcu_read_lock", "rcu_read_unlock", "call_rcu", |
47 | "rcu_read_lock_bh", "rcu_read_unlock_bh", "call_rcu_bh", | ||
48 | "synchronize_rcu", and "synchronize_net". | ||
47 | 49 | ||
48 | o What guidelines should I follow when writing code that uses RCU? | 50 | o What guidelines should I follow when writing code that uses RCU? |
49 | 51 | ||
diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 734fcc87db25..7c2496426ab9 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff | |||
@@ -1,137 +1,137 @@ | |||
1 | .* | 1 | *.a |
2 | *.aux | ||
3 | *.bin | ||
4 | *.cpio | ||
5 | *.css | ||
6 | *.dvi | ||
7 | *.eps | ||
8 | *.gif | ||
9 | *.grep | ||
10 | *.grp | ||
11 | *.gz | ||
12 | *.html | ||
13 | *.jpeg | ||
14 | *.ko | ||
15 | *.log | ||
16 | *.lst | ||
17 | *.mod.c | ||
18 | *.o | ||
19 | *.orig | ||
20 | *.out | ||
21 | |||
22 | *.png | ||
23 | *.ps | ||
24 | *.rej | ||
25 | *.s | ||
26 | *.sgml | ||
27 | *.so | ||
28 | *.tex | ||
29 | *.ver | ||
30 | *_MODULES | ||
31 | *_vga16.c | ||
32 | *cscope* | ||
2 | *~ | 33 | *~ |
34 | .* | ||
35 | .cscope | ||
36 | 53c700_d.h | ||
3 | 53c8xx_d.h* | 37 | 53c8xx_d.h* |
4 | *.a | 38 | BitKeeper |
39 | COPYING | ||
40 | CREDITS | ||
41 | CVS | ||
42 | ChangeSet | ||
43 | Kerntypes | ||
44 | MODS.txt | ||
45 | Module.symvers | ||
46 | PENDING | ||
47 | SCCS | ||
48 | System.map* | ||
49 | TAGS | ||
5 | aic7*reg.h* | 50 | aic7*reg.h* |
6 | aic7*seq.h* | ||
7 | aic7*reg_print.c* | 51 | aic7*reg_print.c* |
8 | 53c700_d.h | 52 | aic7*seq.h* |
9 | aicasm | 53 | aicasm |
10 | aicdb.h* | 54 | aicdb.h* |
11 | asm | 55 | asm |
12 | asm_offsets.* | 56 | asm_offsets.* |
13 | autoconf.h* | 57 | autoconf.h* |
14 | *.aux | ||
15 | bbootsect | 58 | bbootsect |
16 | *.bin | ||
17 | bin2c | 59 | bin2c |
18 | binkernel.spec | 60 | binkernel.spec |
19 | BitKeeper | ||
20 | bootsect | 61 | bootsect |
21 | bsetup | 62 | bsetup |
22 | btfixupprep | 63 | btfixupprep |
23 | build | 64 | build |
24 | bvmlinux | 65 | bvmlinux |
25 | bzImage* | 66 | bzImage* |
26 | ChangeSet | ||
27 | classlist.h* | 67 | classlist.h* |
28 | compile.h* | ||
29 | comp*.log | 68 | comp*.log |
69 | compile.h* | ||
30 | config | 70 | config |
31 | config-* | 71 | config-* |
32 | config_data.h* | 72 | config_data.h* |
33 | conmakehash | 73 | conmakehash |
34 | consolemap_deftbl.c* | 74 | consolemap_deftbl.c* |
35 | COPYING | 75 | crc32table.h* |
36 | CREDITS | ||
37 | .cscope | ||
38 | *cscope* | ||
39 | cscope.* | 76 | cscope.* |
40 | *.out | ||
41 | *.css | ||
42 | CVS | ||
43 | defkeymap.c* | 77 | defkeymap.c* |
44 | devlist.h* | 78 | devlist.h* |
45 | docproc | 79 | docproc |
46 | dummy_sym.c* | 80 | dummy_sym.c* |
47 | *.dvi | 81 | elfconfig.h* |
48 | *.eps | ||
49 | filelist | 82 | filelist |
50 | fixdep | 83 | fixdep |
51 | fore200e_mkfirm | 84 | fore200e_mkfirm |
52 | fore200e_pca_fw.c* | 85 | fore200e_pca_fw.c* |
53 | gen-devlist | 86 | gen-devlist |
54 | gen_init_cpio | ||
55 | gen_crc32table | ||
56 | crc32table.h* | ||
57 | *.cpio | ||
58 | gen-kdb_cmds.c* | 87 | gen-kdb_cmds.c* |
59 | gentbl | 88 | gen_crc32table |
89 | gen_init_cpio | ||
60 | genksyms | 90 | genksyms |
61 | *.gif | 91 | gentbl |
62 | *.gz | ||
63 | *.html | ||
64 | ikconfig.h* | 92 | ikconfig.h* |
65 | initramfs_list | 93 | initramfs_list |
66 | *.jpeg | 94 | kallsyms |
67 | kconfig | 95 | kconfig |
68 | kconfig.tk | 96 | kconfig.tk |
69 | Kerntypes | ||
70 | keywords.c* | 97 | keywords.c* |
71 | ksym.c* | 98 | ksym.c* |
72 | ksym.h* | 99 | ksym.h* |
73 | kallsyms | ||
74 | mk_elfconfig | ||
75 | elfconfig.h* | ||
76 | modpost | ||
77 | pnmtologo | ||
78 | logo_*.c | ||
79 | *.log | ||
80 | lex.c* | 100 | lex.c* |
101 | logo_*.c | ||
81 | logo_*_clut224.c | 102 | logo_*_clut224.c |
82 | logo_*_mono.c | 103 | logo_*_mono.c |
83 | lxdialog | 104 | lxdialog |
84 | make_times_h | 105 | make_times_h |
85 | map | 106 | map |
107 | maui_boot.h | ||
108 | mk_elfconfig | ||
86 | mkdep | 109 | mkdep |
87 | *_MODULES | 110 | mktables |
88 | MODS.txt | 111 | modpost |
89 | modversions.h* | 112 | modversions.h* |
90 | Module.symvers | ||
91 | *.mod.c | ||
92 | *.o | ||
93 | *.ko | ||
94 | *.orig | ||
95 | *.lst | ||
96 | *.grp | ||
97 | *.grep | ||
98 | oui.c* | 113 | oui.c* |
99 | mktables | ||
100 | raid6tables.c | ||
101 | raid6int*.c | ||
102 | raid6altivec*.c | ||
103 | wanxlfw.inc | ||
104 | maui_boot.h | ||
105 | pss_boot.h | ||
106 | trix_boot.h | ||
107 | |||
108 | parse.c* | 114 | parse.c* |
109 | parse.h* | 115 | parse.h* |
110 | PENDING | 116 | pnmtologo |
111 | ppc_defs.h* | 117 | ppc_defs.h* |
112 | promcon_tbl.c* | 118 | promcon_tbl.c* |
113 | *.png | 119 | pss_boot.h |
114 | *.ps | 120 | raid6altivec*.c |
115 | *.rej | 121 | raid6int*.c |
116 | SCCS | 122 | raid6tables.c |
117 | setup | 123 | setup |
118 | *.s | ||
119 | *.so | ||
120 | *.sgml | ||
121 | sim710_d.h* | 124 | sim710_d.h* |
122 | sm_tbl* | 125 | sm_tbl* |
123 | split-include | 126 | split-include |
124 | System.map* | ||
125 | tags | 127 | tags |
126 | TAGS | ||
127 | *.tex | ||
128 | times.h* | 128 | times.h* |
129 | tkparse | 129 | tkparse |
130 | *.ver | 130 | trix_boot.h |
131 | version.h* | 131 | version.h* |
132 | *_vga16.c | ||
133 | vmlinux | 132 | vmlinux |
134 | vmlinux.lds | ||
135 | vmlinux-* | 133 | vmlinux-* |
134 | vmlinux.lds | ||
136 | vsyscall.lds | 135 | vsyscall.lds |
136 | wanxlfw.inc | ||
137 | zImage | 137 | zImage |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 56627c1546de..d3c52dd24a2a 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -48,3 +48,18 @@ When: April 2005 | |||
48 | Why: Replaced by ->compat_ioctl in file_operations and other method | 48 | Why: Replaced by ->compat_ioctl in file_operations and other method |
49 | vecors. | 49 | vecors. |
50 | Who: Andi Kleen <ak@muc.de>, Christoph Hellwig <hch@lst.de> | 50 | Who: Andi Kleen <ak@muc.de>, Christoph Hellwig <hch@lst.de> |
51 | |||
52 | --------------------------- | ||
53 | |||
54 | What: RCU API moves to EXPORT_SYMBOL_GPL | ||
55 | When: April 2006 | ||
56 | Files: include/linux/rcupdate.h, kernel/rcupdate.c | ||
57 | Why: Outside of Linux, the only implementations of anything even | ||
58 | vaguely resembling RCU that I am aware of are in DYNIX/ptx, | ||
59 | VM/XA, Tornado, and K42. I do not expect anyone to port binary | ||
60 | drivers or kernel modules from any of these, since the first two | ||
61 | are owned by IBM and the last two are open-source research OSes. | ||
62 | So these will move to GPL after a grace period to allow | ||
63 | people, who might be using implementations that I am not aware | ||
64 | of, to adjust to this upcoming change. | ||
65 | Who: Paul E. McKenney <paulmck@us.ibm.com> | ||
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index a934baeeb33a..1045da582b9b 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -219,8 +219,12 @@ This may also be done to avoid internal deadlocks, but rarely. | |||
219 | If the filesytem is called for sync then it must wait on any | 219 | If the filesytem is called for sync then it must wait on any |
220 | in-progress I/O and then start new I/O. | 220 | in-progress I/O and then start new I/O. |
221 | 221 | ||
222 | The filesystem should unlock the page synchronously, before returning | 222 | The filesystem should unlock the page synchronously, before returning to the |
223 | to the caller. | 223 | caller, unless ->writepage() returns special WRITEPAGE_ACTIVATE |
224 | value. WRITEPAGE_ACTIVATE means that page cannot really be written out | ||
225 | currently, and VM should stop calling ->writepage() on this page for some | ||
226 | time. VM does this by moving page to the head of the active list, hence the | ||
227 | name. | ||
224 | 228 | ||
225 | Unless the filesystem is going to redirty_page_for_writepage(), unlock the page | 229 | Unless the filesystem is going to redirty_page_for_writepage(), unlock the page |
226 | and return zero, writepage *must* run set_page_writeback() against the page, | 230 | and return zero, writepage *must* run set_page_writeback() against the page, |
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index cbe85c17176b..6c98f2bd421e 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -909,16 +909,6 @@ nr_free_inodes | |||
909 | Represents the number of free inodes. Ie. The number of inuse inodes is | 909 | Represents the number of free inodes. Ie. The number of inuse inodes is |
910 | (nr_inodes - nr_free_inodes). | 910 | (nr_inodes - nr_free_inodes). |
911 | 911 | ||
912 | super-nr and super-max | ||
913 | ---------------------- | ||
914 | |||
915 | Again, super block structures are allocated by the kernel, but not freed. The | ||
916 | file super-max contains the maximum number of super block handlers, where | ||
917 | super-nr shows the number of currently allocated ones. | ||
918 | |||
919 | Every mounted file system needs a super block, so if you plan to mount lots of | ||
920 | file systems, you may want to increase these numbers. | ||
921 | |||
922 | aio-nr and aio-max-nr | 912 | aio-nr and aio-max-nr |
923 | --------------------- | 913 | --------------------- |
924 | 914 | ||
diff --git a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt index 67c053a099ed..df28c7416781 100644 --- a/Documentation/i386/zero-page.txt +++ b/Documentation/i386/zero-page.txt | |||
@@ -79,6 +79,6 @@ Offset Type Description | |||
79 | 0x22c unsigned long ramdisk_max | 79 | 0x22c unsigned long ramdisk_max |
80 | 0x230 16 bytes trampoline | 80 | 0x230 16 bytes trampoline |
81 | 0x290 - 0x2cf EDD_MBR_SIG_BUFFER (edd.S) | 81 | 0x290 - 0x2cf EDD_MBR_SIG_BUFFER (edd.S) |
82 | 0x2d0 - 0x600 E820MAP | 82 | 0x2d0 - 0xd00 E820MAP |
83 | 0x600 - 0x7ff EDDBUF (edd.S) for disk signature read sector | 83 | 0xd00 - 0xeff EDDBUF (edd.S) for disk signature read sector |
84 | 0x600 - 0x7eb EDDBUF (edd.S) for edd data | 84 | 0xd00 - 0xeeb EDDBUF (edd.S) for edd data |
diff --git a/Documentation/s390/cds.txt b/Documentation/s390/cds.txt index d9397170fb36..f0be389c7116 100644 --- a/Documentation/s390/cds.txt +++ b/Documentation/s390/cds.txt | |||
@@ -56,12 +56,16 @@ read_dev_chars() | |||
56 | read device characteristics | 56 | read device characteristics |
57 | 57 | ||
58 | read_conf_data() | 58 | read_conf_data() |
59 | read_conf_data_lpm() | ||
59 | read configuration data. | 60 | read configuration data. |
60 | 61 | ||
61 | ccw_device_get_ciw() | 62 | ccw_device_get_ciw() |
62 | get commands from extended sense data. | 63 | get commands from extended sense data. |
63 | 64 | ||
64 | ccw_device_start() | 65 | ccw_device_start() |
66 | ccw_device_start_timeout() | ||
67 | ccw_device_start_key() | ||
68 | ccw_device_start_key_timeout() | ||
65 | initiate an I/O request. | 69 | initiate an I/O request. |
66 | 70 | ||
67 | ccw_device_resume() | 71 | ccw_device_resume() |
@@ -197,19 +201,21 @@ The read_dev_chars() function returns : | |||
197 | operational. | 201 | operational. |
198 | 202 | ||
199 | 203 | ||
200 | read_conf_data() - Read Configuration Data | 204 | read_conf_data(), read_conf_data_lpm() - Read Configuration Data |
201 | 205 | ||
202 | Retrieve the device dependent configuration data. Please have a look at your | 206 | Retrieve the device dependent configuration data. Please have a look at your |
203 | device dependent I/O commands for the device specific layout of the node | 207 | device dependent I/O commands for the device specific layout of the node |
204 | descriptor elements. | 208 | descriptor elements. read_conf_data_lpm() will retrieve the configuration data |
209 | for a specific path. | ||
205 | 210 | ||
206 | The function is meant to be called with an irq handler in place; that is, | 211 | The function is meant to be called with the device already enabled; that is, |
207 | at earliest during set_online() processing. | 212 | at earliest during set_online() processing. |
208 | 213 | ||
209 | The function may be called enabled or disabled, but the device must not be | 214 | The function may be called enabled or disabled, but the device must not be |
210 | locked | 215 | locked |
211 | 216 | ||
212 | int read_conf_data(struct ccw_device, void **buffer, int *length, __u8 lpm); | 217 | int read_conf_data(struct ccw_device, void **buffer, int *length); |
218 | int read_conf_data_lpm(struct ccw_device, void **buffer, int *length, __u8 lpm); | ||
213 | 219 | ||
214 | cdev - the ccw_device the data is requested for. | 220 | cdev - the ccw_device the data is requested for. |
215 | buffer - Pointer to a buffer pointer. The read_conf_data() routine | 221 | buffer - Pointer to a buffer pointer. The read_conf_data() routine |
@@ -263,6 +269,25 @@ int ccw_device_start(struct ccw_device *cdev, | |||
263 | unsigned long intparm, | 269 | unsigned long intparm, |
264 | __u8 lpm, | 270 | __u8 lpm, |
265 | unsigned long flags); | 271 | unsigned long flags); |
272 | int ccw_device_start_timeout(struct ccw_device *cdev, | ||
273 | struct ccw1 *cpa, | ||
274 | unsigned long intparm, | ||
275 | __u8 lpm, | ||
276 | unsigned long flags, | ||
277 | int expires); | ||
278 | int ccw_device_start_key(struct ccw_device *cdev, | ||
279 | struct ccw1 *cpa, | ||
280 | unsigned long intparm, | ||
281 | __u8 lpm, | ||
282 | __u8 key, | ||
283 | unsigned long flags); | ||
284 | int ccw_device_start_key_timeout(struct ccw_device *cdev, | ||
285 | struct ccw1 *cpa, | ||
286 | unsigned long intparm, | ||
287 | __u8 lpm, | ||
288 | __u8 key, | ||
289 | unsigned long flags, | ||
290 | int expires); | ||
266 | 291 | ||
267 | cdev : ccw_device the I/O is destined for | 292 | cdev : ccw_device the I/O is destined for |
268 | cpa : logical start address of channel program | 293 | cpa : logical start address of channel program |
@@ -272,7 +297,12 @@ user_intparm : user specific interrupt information; will be presented | |||
272 | particular I/O request. | 297 | particular I/O request. |
273 | lpm : defines the channel path to be used for a specific I/O | 298 | lpm : defines the channel path to be used for a specific I/O |
274 | request. A value of 0 will make cio use the opm. | 299 | request. A value of 0 will make cio use the opm. |
300 | key : the storage key to use for the I/O (useful for operating on a | ||
301 | storage with a storage key != default key) | ||
275 | flag : defines the action to be performed for I/O processing | 302 | flag : defines the action to be performed for I/O processing |
303 | expires : timeout value in jiffies. The common I/O layer will terminate | ||
304 | the running program after this and call the interrupt handler | ||
305 | with ERR_PTR(-ETIMEDOUT) as irb. | ||
276 | 306 | ||
277 | Possible flag values are : | 307 | Possible flag values are : |
278 | 308 | ||
@@ -327,6 +357,13 @@ current (last) I/O request. In case of a delayed status notification no special | |||
327 | interrupt will be presented to indicate I/O completion as the I/O request was | 357 | interrupt will be presented to indicate I/O completion as the I/O request was |
328 | never started, even though ccw_device_start() returned with successful completion. | 358 | never started, even though ccw_device_start() returned with successful completion. |
329 | 359 | ||
360 | The irb may contain an error value, and the device driver should check for this | ||
361 | first: | ||
362 | |||
363 | -ETIMEDOUT: the common I/O layer terminated the request after the specified | ||
364 | timeout value | ||
365 | -EIO: the common I/O layer terminated the request due to an error state | ||
366 | |||
330 | If the concurrent sense flag in the extended status word in the irb is set, the | 367 | If the concurrent sense flag in the extended status word in the irb is set, the |
331 | field irb->scsw.count describes the numer of device specific sense bytes | 368 | field irb->scsw.count describes the numer of device specific sense bytes |
332 | available in the extended control word irb->scsw.ecw[0]. No device sensing by | 369 | available in the extended control word irb->scsw.ecw[0]. No device sensing by |
diff --git a/MAINTAINERS b/MAINTAINERS index 4333b69e56bd..f384a9758fc0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2113,6 +2113,13 @@ M: perex@suse.cz | |||
2113 | L: alsa-devel@alsa-project.org | 2113 | L: alsa-devel@alsa-project.org |
2114 | S: Maintained | 2114 | S: Maintained |
2115 | 2115 | ||
2116 | TPM DEVICE DRIVER | ||
2117 | P: Kylene Hall | ||
2118 | M: kjhall@us.ibm.com | ||
2119 | W: http://tpmdd.sourceforge.net | ||
2120 | L: tpmdd-devel@lists.sourceforge.net | ||
2121 | S: Maintained | ||
2122 | |||
2116 | UltraSPARC (sparc64): | 2123 | UltraSPARC (sparc64): |
2117 | P: David S. Miller | 2124 | P: David S. Miller |
2118 | M: davem@davemloft.net | 2125 | M: davem@davemloft.net |
@@ -332,9 +332,7 @@ KALLSYMS = scripts/kallsyms | |||
332 | PERL = perl | 332 | PERL = perl |
333 | CHECK = sparse | 333 | CHECK = sparse |
334 | 334 | ||
335 | NOSTDINC_FLAGS = -nostdinc -isystem $(shell $(CC) -print-file-name=include) | ||
336 | CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ | 335 | CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ |
337 | CHECKFLAGS += $(NOSTDINC_FLAGS) | ||
338 | MODFLAGS = -DMODULE | 336 | MODFLAGS = -DMODULE |
339 | CFLAGS_MODULE = $(MODFLAGS) | 337 | CFLAGS_MODULE = $(MODFLAGS) |
340 | AFLAGS_MODULE = $(MODFLAGS) | 338 | AFLAGS_MODULE = $(MODFLAGS) |
@@ -531,6 +529,10 @@ endif | |||
531 | 529 | ||
532 | include $(srctree)/arch/$(ARCH)/Makefile | 530 | include $(srctree)/arch/$(ARCH)/Makefile |
533 | 531 | ||
532 | # arch Makefile may override CC so keep this after arch Makefile is included | ||
533 | NOSTDINC_FLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include) | ||
534 | CHECKFLAGS += $(NOSTDINC_FLAGS) | ||
535 | |||
534 | # warn about C99 declaration after statement | 536 | # warn about C99 declaration after statement |
535 | CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) | 537 | CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) |
536 | 538 | ||
@@ -1188,8 +1190,8 @@ cmd_TAGS = $(all-sources) | etags - | |||
1188 | quiet_cmd_tags = MAKE $@ | 1190 | quiet_cmd_tags = MAKE $@ |
1189 | define cmd_tags | 1191 | define cmd_tags |
1190 | rm -f $@; \ | 1192 | rm -f $@; \ |
1191 | CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL"`; \ | 1193 | CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \ |
1192 | $(all-sources) | xargs ctags $$CTAGSF -a --extra=+f | 1194 | $(all-sources) | xargs ctags $$CTAGSF -a |
1193 | endef | 1195 | endef |
1194 | 1196 | ||
1195 | TAGS: FORCE | 1197 | TAGS: FORCE |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index b5d0fd2bb10a..64e450dddb49 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -457,22 +457,6 @@ osf_getdomainname(char __user *name, int namelen) | |||
457 | return 0; | 457 | return 0; |
458 | } | 458 | } |
459 | 459 | ||
460 | asmlinkage long | ||
461 | osf_shmat(int shmid, void __user *shmaddr, int shmflg) | ||
462 | { | ||
463 | unsigned long raddr; | ||
464 | long err; | ||
465 | |||
466 | err = do_shmat(shmid, shmaddr, shmflg, &raddr); | ||
467 | |||
468 | /* | ||
469 | * This works because all user-level addresses are | ||
470 | * non-negative longs! | ||
471 | */ | ||
472 | return err ? err : (long)raddr; | ||
473 | } | ||
474 | |||
475 | |||
476 | /* | 460 | /* |
477 | * The following stuff should move into a header file should it ever | 461 | * The following stuff should move into a header file should it ever |
478 | * be labeled "officially supported." Right now, there is just enough | 462 | * be labeled "officially supported." Right now, there is just enough |
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index d00583161574..bbd37536d14e 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/user.h> | 14 | #include <linux/user.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/security.h> | 16 | #include <linux/security.h> |
17 | #include <linux/signal.h> | ||
17 | 18 | ||
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
19 | #include <asm/pgtable.h> | 20 | #include <asm/pgtable.h> |
@@ -335,7 +336,7 @@ do_sys_ptrace(long request, long pid, long addr, long data, | |||
335 | /* continue and stop at next (return from) syscall */ | 336 | /* continue and stop at next (return from) syscall */ |
336 | case PTRACE_CONT: /* restart after signal. */ | 337 | case PTRACE_CONT: /* restart after signal. */ |
337 | ret = -EIO; | 338 | ret = -EIO; |
338 | if ((unsigned long) data > _NSIG) | 339 | if (!valid_signal(data)) |
339 | break; | 340 | break; |
340 | if (request == PTRACE_SYSCALL) | 341 | if (request == PTRACE_SYSCALL) |
341 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 342 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -365,7 +366,7 @@ do_sys_ptrace(long request, long pid, long addr, long data, | |||
365 | 366 | ||
366 | case PTRACE_SINGLESTEP: /* execute single instruction. */ | 367 | case PTRACE_SINGLESTEP: /* execute single instruction. */ |
367 | ret = -EIO; | 368 | ret = -EIO; |
368 | if ((unsigned long) data > _NSIG) | 369 | if (!valid_signal(data)) |
369 | break; | 370 | break; |
370 | /* Mark single stepping. */ | 371 | /* Mark single stepping. */ |
371 | child->thread_info->bpt_nsaved = -1; | 372 | child->thread_info->bpt_nsaved = -1; |
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 3864b33562ee..052120882876 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
@@ -227,7 +227,7 @@ sys_call_table: | |||
227 | .quad sys_semop | 227 | .quad sys_semop |
228 | .quad osf_utsname | 228 | .quad osf_utsname |
229 | .quad sys_lchown | 229 | .quad sys_lchown |
230 | .quad osf_shmat | 230 | .quad sys_shmat |
231 | .quad sys_shmctl /* 210 */ | 231 | .quad sys_shmctl /* 210 */ |
232 | .quad sys_shmdt | 232 | .quad sys_shmdt |
233 | .quad sys_shmget | 233 | .quad sys_shmget |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index c0e7aff3dec2..7c7f475e213e 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -18,48 +18,30 @@ | |||
18 | * Please select one of the following when turning on debugging. | 18 | * Please select one of the following when turning on debugging. |
19 | */ | 19 | */ |
20 | #ifdef DEBUG | 20 | #ifdef DEBUG |
21 | #if defined(CONFIG_DEBUG_DC21285_PORT) | 21 | |
22 | .macro loadsp, rb | 22 | #include <asm/arch/debug-macro.S> |
23 | mov \rb, #0x42000000 | 23 | |
24 | .endm | 24 | #if defined(CONFIG_DEBUG_ICEDCC) |
25 | .macro writeb, rb | ||
26 | str \rb, [r3, #0x160] | ||
27 | .endm | ||
28 | #elif defined(CONFIG_DEBUG_ICEDCC) | ||
29 | .macro loadsp, rb | 25 | .macro loadsp, rb |
30 | .endm | 26 | .endm |
31 | .macro writeb, rb | 27 | .macro writeb, ch, rb |
32 | mcr p14, 0, \rb, c0, c1, 0 | 28 | mcr p14, 0, \ch, c0, c1, 0 |
33 | .endm | ||
34 | #elif defined(CONFIG_FOOTBRIDGE) | ||
35 | .macro loadsp, rb | ||
36 | mov \rb, #0x7c000000 | ||
37 | .endm | 29 | .endm |
38 | .macro writeb, rb | 30 | #else |
39 | strb \rb, [r3, #0x3f8] | 31 | .macro writeb, ch, rb |
32 | senduart \ch, \rb | ||
40 | .endm | 33 | .endm |
41 | #elif defined(CONFIG_ARCH_RPC) | 34 | |
35 | #if defined(CONFIG_FOOTBRIDGE) || \ | ||
36 | defined(CONFIG_ARCH_RPC) || \ | ||
37 | defined(CONFIG_ARCH_INTEGRATOR) || \ | ||
38 | defined(CONFIG_ARCH_PXA) || \ | ||
39 | defined(CONFIG_ARCH_IXP4XX) || \ | ||
40 | defined(CONFIG_ARCH_IXP2000) || \ | ||
41 | defined(CONFIG_ARCH_LH7A40X) || \ | ||
42 | defined(CONFIG_ARCH_OMAP) | ||
42 | .macro loadsp, rb | 43 | .macro loadsp, rb |
43 | mov \rb, #0x03000000 | 44 | addruart \rb |
44 | orr \rb, \rb, #0x00010000 | ||
45 | .endm | ||
46 | .macro writeb, rb | ||
47 | strb \rb, [r3, #0x3f8 << 2] | ||
48 | .endm | ||
49 | #elif defined(CONFIG_ARCH_INTEGRATOR) | ||
50 | .macro loadsp, rb | ||
51 | mov \rb, #0x16000000 | ||
52 | .endm | ||
53 | .macro writeb, rb | ||
54 | strb \rb, [r3, #0] | ||
55 | .endm | ||
56 | #elif defined(CONFIG_ARCH_PXA) /* Xscale-type */ | ||
57 | .macro loadsp, rb | ||
58 | mov \rb, #0x40000000 | ||
59 | orr \rb, \rb, #0x00100000 | ||
60 | .endm | ||
61 | .macro writeb, rb | ||
62 | strb \rb, [r3, #0] | ||
63 | .endm | 45 | .endm |
64 | #elif defined(CONFIG_ARCH_SA1100) | 46 | #elif defined(CONFIG_ARCH_SA1100) |
65 | .macro loadsp, rb | 47 | .macro loadsp, rb |
@@ -70,65 +52,22 @@ | |||
70 | add \rb, \rb, #0x00010000 @ Ser1 | 52 | add \rb, \rb, #0x00010000 @ Ser1 |
71 | # endif | 53 | # endif |
72 | .endm | 54 | .endm |
73 | .macro writeb, rb | ||
74 | str \rb, [r3, #0x14] @ UTDR | ||
75 | .endm | ||
76 | #elif defined(CONFIG_ARCH_IXP4XX) | ||
77 | .macro loadsp, rb | ||
78 | mov \rb, #0xc8000000 | ||
79 | .endm | ||
80 | .macro writeb, rb | ||
81 | str \rb, [r3, #0] | ||
82 | #elif defined(CONFIG_ARCH_IXP2000) | ||
83 | .macro loadsp, rb | ||
84 | mov \rb, #0xc0000000 | ||
85 | orr \rb, \rb, #0x00030000 | ||
86 | .endm | ||
87 | .macro writeb, rb | ||
88 | str \rb, [r3, #0] | ||
89 | .endm | ||
90 | #elif defined(CONFIG_ARCH_LH7A40X) | ||
91 | .macro loadsp, rb | ||
92 | ldr \rb, =0x80000700 @ UART2 UARTBASE | ||
93 | .endm | ||
94 | .macro writeb, rb | ||
95 | strb \rb, [r3, #0] | ||
96 | .endm | ||
97 | #elif defined(CONFIG_ARCH_OMAP) | ||
98 | .macro loadsp, rb | ||
99 | mov \rb, #0xff000000 @ physical base address | ||
100 | add \rb, \rb, #0x00fb0000 | ||
101 | #if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3) | ||
102 | add \rb, \rb, #0x00000800 | ||
103 | #endif | ||
104 | #ifdef CONFIG_OMAP_LL_DEBUG_UART3 | ||
105 | add \rb, \rb, #0x00009000 | ||
106 | #endif | ||
107 | .endm | ||
108 | .macro writeb, rb | ||
109 | strb \rb, [r3] | ||
110 | .endm | ||
111 | #elif defined(CONFIG_ARCH_IOP331) | 55 | #elif defined(CONFIG_ARCH_IOP331) |
112 | .macro loadsp, rb | 56 | .macro loadsp, rb |
113 | mov \rb, #0xff000000 | 57 | mov \rb, #0xff000000 |
114 | orr \rb, \rb, #0x00ff0000 | 58 | orr \rb, \rb, #0x00ff0000 |
115 | orr \rb, \rb, #0x0000f700 @ location of the UART | 59 | orr \rb, \rb, #0x0000f700 @ location of the UART |
116 | .endm | 60 | .endm |
117 | .macro writeb, rb | ||
118 | str \rb, [r3, #0] | ||
119 | .endm | ||
120 | #elif defined(CONFIG_ARCH_S3C2410) | 61 | #elif defined(CONFIG_ARCH_S3C2410) |
121 | .macro loadsp, rb | 62 | .macro loadsp, rb |
122 | mov \rb, #0x50000000 | 63 | mov \rb, #0x50000000 |
123 | add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT | 64 | add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT |
124 | .endm | 65 | .endm |
125 | .macro writeb, rb | ||
126 | strb \rb, [r3, #0x20] | ||
127 | .endm | ||
128 | #else | 66 | #else |
129 | #error no serial architecture defined | 67 | #error no serial architecture defined |
130 | #endif | 68 | #endif |
131 | #endif | 69 | #endif |
70 | #endif | ||
132 | 71 | ||
133 | .macro kputc,val | 72 | .macro kputc,val |
134 | mov r0, \val | 73 | mov r0, \val |
@@ -734,7 +673,7 @@ puts: loadsp r3 | |||
734 | 1: ldrb r2, [r0], #1 | 673 | 1: ldrb r2, [r0], #1 |
735 | teq r2, #0 | 674 | teq r2, #0 |
736 | moveq pc, lr | 675 | moveq pc, lr |
737 | 2: writeb r2 | 676 | 2: writeb r2, r3 |
738 | mov r1, #0x00020000 | 677 | mov r1, #0x00020000 |
739 | 3: subs r1, r1, #1 | 678 | 3: subs r1, r1, #1 |
740 | bne 3b | 679 | bne 3b |
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c index c397e71f938d..72b03f201eb9 100644 --- a/arch/arm/common/rtctime.c +++ b/arch/arm/common/rtctime.c | |||
@@ -141,10 +141,10 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc | |||
141 | next->tm_sec = alrm->tm_sec; | 141 | next->tm_sec = alrm->tm_sec; |
142 | } | 142 | } |
143 | 143 | ||
144 | static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) | 144 | static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) |
145 | { | 145 | { |
146 | memset(tm, 0, sizeof(struct rtc_time)); | 146 | memset(tm, 0, sizeof(struct rtc_time)); |
147 | ops->read_time(tm); | 147 | return ops->read_time(tm); |
148 | } | 148 | } |
149 | 149 | ||
150 | static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) | 150 | static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) |
@@ -163,8 +163,7 @@ static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) | |||
163 | int ret = -EINVAL; | 163 | int ret = -EINVAL; |
164 | if (ops->read_alarm) { | 164 | if (ops->read_alarm) { |
165 | memset(alrm, 0, sizeof(struct rtc_wkalrm)); | 165 | memset(alrm, 0, sizeof(struct rtc_wkalrm)); |
166 | ops->read_alarm(alrm); | 166 | ret = ops->read_alarm(alrm); |
167 | ret = 0; | ||
168 | } | 167 | } |
169 | return ret; | 168 | return ret; |
170 | } | 169 | } |
@@ -283,7 +282,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
283 | break; | 282 | break; |
284 | 283 | ||
285 | case RTC_RD_TIME: | 284 | case RTC_RD_TIME: |
286 | rtc_read_time(ops, &tm); | 285 | ret = rtc_read_time(ops, &tm); |
286 | if (ret) | ||
287 | break; | ||
287 | ret = copy_to_user(uarg, &tm, sizeof(tm)); | 288 | ret = copy_to_user(uarg, &tm, sizeof(tm)); |
288 | if (ret) | 289 | if (ret) |
289 | ret = -EFAULT; | 290 | ret = -EFAULT; |
@@ -424,15 +425,15 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo | |||
424 | struct rtc_time tm; | 425 | struct rtc_time tm; |
425 | char *p = page; | 426 | char *p = page; |
426 | 427 | ||
427 | rtc_read_time(ops, &tm); | 428 | if (rtc_read_time(ops, &tm) == 0) { |
428 | 429 | p += sprintf(p, | |
429 | p += sprintf(p, | 430 | "rtc_time\t: %02d:%02d:%02d\n" |
430 | "rtc_time\t: %02d:%02d:%02d\n" | 431 | "rtc_date\t: %04d-%02d-%02d\n" |
431 | "rtc_date\t: %04d-%02d-%02d\n" | 432 | "rtc_epoch\t: %04lu\n", |
432 | "rtc_epoch\t: %04lu\n", | 433 | tm.tm_hour, tm.tm_min, tm.tm_sec, |
433 | tm.tm_hour, tm.tm_min, tm.tm_sec, | 434 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, |
434 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, | 435 | rtc_epoch); |
435 | rtc_epoch); | 436 | } |
436 | 437 | ||
437 | if (rtc_read_alarm(ops, &alrm) == 0) { | 438 | if (rtc_read_alarm(ops, &alrm) == 0) { |
438 | p += sprintf(p, "alrm_time\t: "); | 439 | p += sprintf(p, "alrm_time\t: "); |
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig index d36f99192962..7be3521f91fc 100644 --- a/arch/arm/configs/ixdp2800_defconfig +++ b/arch/arm/configs/ixdp2800_defconfig | |||
@@ -133,7 +133,7 @@ CONFIG_ALIGNMENT_TRAP=y | |||
133 | # | 133 | # |
134 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 134 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
135 | CONFIG_ZBOOT_ROM_BSS=0x0 | 135 | CONFIG_ZBOOT_ROM_BSS=0x0 |
136 | CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" | 136 | CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0" |
137 | # CONFIG_XIP_KERNEL is not set | 137 | # CONFIG_XIP_KERNEL is not set |
138 | 138 | ||
139 | # | 139 | # |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 2a5c3fe09a95..080df907f242 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -269,6 +269,12 @@ __pabt_svc: | |||
269 | add r5, sp, #S_PC | 269 | add r5, sp, #S_PC |
270 | ldmia r7, {r2 - r4} @ Get USR pc, cpsr | 270 | ldmia r7, {r2 - r4} @ Get USR pc, cpsr |
271 | 271 | ||
272 | #if __LINUX_ARM_ARCH__ < 6 | ||
273 | @ make sure our user space atomic helper is aborted | ||
274 | cmp r2, #VIRT_OFFSET | ||
275 | bichs r3, r3, #PSR_Z_BIT | ||
276 | #endif | ||
277 | |||
272 | @ | 278 | @ |
273 | @ We are now ready to fill in the remaining blanks on the stack: | 279 | @ We are now ready to fill in the remaining blanks on the stack: |
274 | @ | 280 | @ |
@@ -499,8 +505,12 @@ ENTRY(__switch_to) | |||
499 | mra r4, r5, acc0 | 505 | mra r4, r5, acc0 |
500 | stmia ip, {r4, r5} | 506 | stmia ip, {r4, r5} |
501 | #endif | 507 | #endif |
508 | #ifdef CONFIG_HAS_TLS_REG | ||
509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register | ||
510 | #else | ||
502 | mov r4, #0xffff0fff | 511 | mov r4, #0xffff0fff |
503 | str r3, [r4, #-3] @ Set TLS ptr | 512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 |
513 | #endif | ||
504 | mcr p15, 0, r6, c3, c0, 0 @ Set domain register | 514 | mcr p15, 0, r6, c3, c0, 0 @ Set domain register |
505 | #ifdef CONFIG_VFP | 515 | #ifdef CONFIG_VFP |
506 | @ Always disable VFP so we can lazily save/restore the old | 516 | @ Always disable VFP so we can lazily save/restore the old |
@@ -519,6 +529,207 @@ ENTRY(__switch_to) | |||
519 | ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously | 529 | ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously |
520 | 530 | ||
521 | __INIT | 531 | __INIT |
532 | |||
533 | /* | ||
534 | * User helpers. | ||
535 | * | ||
536 | * These are segment of kernel provided user code reachable from user space | ||
537 | * at a fixed address in kernel memory. This is used to provide user space | ||
538 | * with some operations which require kernel help because of unimplemented | ||
539 | * native feature and/or instructions in many ARM CPUs. The idea is for | ||
540 | * this code to be executed directly in user mode for best efficiency but | ||
541 | * which is too intimate with the kernel counter part to be left to user | ||
542 | * libraries. In fact this code might even differ from one CPU to another | ||
543 | * depending on the available instruction set and restrictions like on | ||
544 | * SMP systems. In other words, the kernel reserves the right to change | ||
545 | * this code as needed without warning. Only the entry points and their | ||
546 | * results are guaranteed to be stable. | ||
547 | * | ||
548 | * Each segment is 32-byte aligned and will be moved to the top of the high | ||
549 | * vector page. New segments (if ever needed) must be added in front of | ||
550 | * existing ones. This mechanism should be used only for things that are | ||
551 | * really small and justified, and not be abused freely. | ||
552 | * | ||
553 | * User space is expected to implement those things inline when optimizing | ||
554 | * for a processor that has the necessary native support, but only if such | ||
555 | * resulting binaries are already to be incompatible with earlier ARM | ||
556 | * processors due to the use of unsupported instructions other than what | ||
557 | * is provided here. In other words don't make binaries unable to run on | ||
558 | * earlier processors just for the sake of not using these kernel helpers | ||
559 | * if your compiled code is not going to use the new instructions for other | ||
560 | * purpose. | ||
561 | */ | ||
562 | |||
563 | .align 5 | ||
564 | .globl __kuser_helper_start | ||
565 | __kuser_helper_start: | ||
566 | |||
567 | /* | ||
568 | * Reference prototype: | ||
569 | * | ||
570 | * int __kernel_cmpxchg(int oldval, int newval, int *ptr) | ||
571 | * | ||
572 | * Input: | ||
573 | * | ||
574 | * r0 = oldval | ||
575 | * r1 = newval | ||
576 | * r2 = ptr | ||
577 | * lr = return address | ||
578 | * | ||
579 | * Output: | ||
580 | * | ||
581 | * r0 = returned value (zero or non-zero) | ||
582 | * C flag = set if r0 == 0, clear if r0 != 0 | ||
583 | * | ||
584 | * Clobbered: | ||
585 | * | ||
586 | * r3, ip, flags | ||
587 | * | ||
588 | * Definition and user space usage example: | ||
589 | * | ||
590 | * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); | ||
591 | * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) | ||
592 | * | ||
593 | * Atomically store newval in *ptr if *ptr is equal to oldval for user space. | ||
594 | * Return zero if *ptr was changed or non-zero if no exchange happened. | ||
595 | * The C flag is also set if *ptr was changed to allow for assembly | ||
596 | * optimization in the calling code. | ||
597 | * | ||
598 | * For example, a user space atomic_add implementation could look like this: | ||
599 | * | ||
600 | * #define atomic_add(ptr, val) \ | ||
601 | * ({ register unsigned int *__ptr asm("r2") = (ptr); \ | ||
602 | * register unsigned int __result asm("r1"); \ | ||
603 | * asm volatile ( \ | ||
604 | * "1: @ atomic_add\n\t" \ | ||
605 | * "ldr r0, [r2]\n\t" \ | ||
606 | * "mov r3, #0xffff0fff\n\t" \ | ||
607 | * "add lr, pc, #4\n\t" \ | ||
608 | * "add r1, r0, %2\n\t" \ | ||
609 | * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \ | ||
610 | * "bcc 1b" \ | ||
611 | * : "=&r" (__result) \ | ||
612 | * : "r" (__ptr), "rIL" (val) \ | ||
613 | * : "r0","r3","ip","lr","cc","memory" ); \ | ||
614 | * __result; }) | ||
615 | */ | ||
616 | |||
617 | __kuser_cmpxchg: @ 0xffff0fc0 | ||
618 | |||
619 | #if __LINUX_ARM_ARCH__ < 6 | ||
620 | |||
621 | #ifdef CONFIG_SMP /* sanity check */ | ||
622 | #error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?" | ||
623 | #endif | ||
624 | |||
625 | /* | ||
626 | * Theory of operation: | ||
627 | * | ||
628 | * We set the Z flag before loading oldval. If ever an exception | ||
629 | * occurs we can not be sure the loaded value will still be the same | ||
630 | * when the exception returns, therefore the user exception handler | ||
631 | * will clear the Z flag whenever the interrupted user code was | ||
632 | * actually from the kernel address space (see the usr_entry macro). | ||
633 | * | ||
634 | * The post-increment on the str is used to prevent a race with an | ||
635 | * exception happening just after the str instruction which would | ||
636 | * clear the Z flag although the exchange was done. | ||
637 | */ | ||
638 | teq ip, ip @ set Z flag | ||
639 | ldr ip, [r2] @ load current val | ||
640 | add r3, r2, #1 @ prepare store ptr | ||
641 | teqeq ip, r0 @ compare with oldval if still allowed | ||
642 | streq r1, [r3, #-1]! @ store newval if still allowed | ||
643 | subs r0, r2, r3 @ if r2 == r3 the str occured | ||
644 | mov pc, lr | ||
645 | |||
646 | #else | ||
647 | |||
648 | ldrex r3, [r2] | ||
649 | subs r3, r3, r0 | ||
650 | strexeq r3, r1, [r2] | ||
651 | rsbs r0, r3, #0 | ||
652 | mov pc, lr | ||
653 | |||
654 | #endif | ||
655 | |||
656 | .align 5 | ||
657 | |||
658 | /* | ||
659 | * Reference prototype: | ||
660 | * | ||
661 | * int __kernel_get_tls(void) | ||
662 | * | ||
663 | * Input: | ||
664 | * | ||
665 | * lr = return address | ||
666 | * | ||
667 | * Output: | ||
668 | * | ||
669 | * r0 = TLS value | ||
670 | * | ||
671 | * Clobbered: | ||
672 | * | ||
673 | * the Z flag might be lost | ||
674 | * | ||
675 | * Definition and user space usage example: | ||
676 | * | ||
677 | * typedef int (__kernel_get_tls_t)(void); | ||
678 | * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0) | ||
679 | * | ||
680 | * Get the TLS value as previously set via the __ARM_NR_set_tls syscall. | ||
681 | * | ||
682 | * This could be used as follows: | ||
683 | * | ||
684 | * #define __kernel_get_tls() \ | ||
685 | * ({ register unsigned int __val asm("r0"); \ | ||
686 | * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \ | ||
687 | * : "=r" (__val) : : "lr","cc" ); \ | ||
688 | * __val; }) | ||
689 | */ | ||
690 | |||
691 | __kuser_get_tls: @ 0xffff0fe0 | ||
692 | |||
693 | #ifndef CONFIG_HAS_TLS_REG | ||
694 | |||
695 | #ifdef CONFIG_SMP /* sanity check */ | ||
696 | #error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong" | ||
697 | #endif | ||
698 | |||
699 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 | ||
700 | mov pc, lr | ||
701 | |||
702 | #else | ||
703 | |||
704 | mrc p15, 0, r0, c13, c0, 3 @ read TLS register | ||
705 | mov pc, lr | ||
706 | |||
707 | #endif | ||
708 | |||
709 | .rep 5 | ||
710 | .word 0 @ pad up to __kuser_helper_version | ||
711 | .endr | ||
712 | |||
713 | /* | ||
714 | * Reference declaration: | ||
715 | * | ||
716 | * extern unsigned int __kernel_helper_version; | ||
717 | * | ||
718 | * Definition and user space usage example: | ||
719 | * | ||
720 | * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc) | ||
721 | * | ||
722 | * User space may read this to determine the curent number of helpers | ||
723 | * available. | ||
724 | */ | ||
725 | |||
726 | __kuser_helper_version: @ 0xffff0ffc | ||
727 | .word ((__kuser_helper_end - __kuser_helper_start) >> 5) | ||
728 | |||
729 | .globl __kuser_helper_end | ||
730 | __kuser_helper_end: | ||
731 | |||
732 | |||
522 | /* | 733 | /* |
523 | * Vector stubs. | 734 | * Vector stubs. |
524 | * | 735 | * |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index efd7a341614b..cd99b83f14c2 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/user.h> | 19 | #include <linux/user.h> |
20 | #include <linux/security.h> | 20 | #include <linux/security.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/signal.h> | ||
22 | 23 | ||
23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
24 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
@@ -693,7 +694,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat | |||
693 | case PTRACE_SYSCALL: | 694 | case PTRACE_SYSCALL: |
694 | case PTRACE_CONT: | 695 | case PTRACE_CONT: |
695 | ret = -EIO; | 696 | ret = -EIO; |
696 | if ((unsigned long) data > _NSIG) | 697 | if (!valid_signal(data)) |
697 | break; | 698 | break; |
698 | if (request == PTRACE_SYSCALL) | 699 | if (request == PTRACE_SYSCALL) |
699 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 700 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -728,7 +729,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat | |||
728 | */ | 729 | */ |
729 | case PTRACE_SINGLESTEP: | 730 | case PTRACE_SINGLESTEP: |
730 | ret = -EIO; | 731 | ret = -EIO; |
731 | if ((unsigned long) data > _NSIG) | 732 | if (!valid_signal(data)) |
732 | break; | 733 | break; |
733 | child->ptrace |= PT_SINGLESTEP; | 734 | child->ptrace |= PT_SINGLESTEP; |
734 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 735 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 7ba6342cf93d..ef32577da304 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
@@ -227,18 +227,6 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third, | |||
227 | } | 227 | } |
228 | } | 228 | } |
229 | 229 | ||
230 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg, | ||
231 | unsigned long __user *addr) | ||
232 | { | ||
233 | unsigned long ret; | ||
234 | long err; | ||
235 | |||
236 | err = do_shmat(shmid, shmaddr, shmflg, &ret); | ||
237 | if (err == 0) | ||
238 | err = put_user(ret, addr); | ||
239 | return err; | ||
240 | } | ||
241 | |||
242 | /* Fork a new task - this creates a new program thread. | 230 | /* Fork a new task - this creates a new program thread. |
243 | * This is called indirectly via a small wrapper | 231 | * This is called indirectly via a small wrapper |
244 | */ | 232 | */ |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 0078aeb85737..3a001fe5540b 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -450,13 +450,17 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
450 | 450 | ||
451 | case NR(set_tls): | 451 | case NR(set_tls): |
452 | thread->tp_value = regs->ARM_r0; | 452 | thread->tp_value = regs->ARM_r0; |
453 | #ifdef CONFIG_HAS_TLS_REG | ||
454 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); | ||
455 | #else | ||
453 | /* | 456 | /* |
454 | * Our user accessible TLS ptr is located at 0xffff0ffc. | 457 | * User space must never try to access this directly. |
455 | * On SMP read access to this address must raise a fault | 458 | * Expect your app to break eventually if you do so. |
456 | * and be emulated from the data abort handler. | 459 | * The user helper at 0xffff0fe0 must be used instead. |
457 | * m | 460 | * (see entry-armv.S for details) |
458 | */ | 461 | */ |
459 | *((unsigned long *)0xffff0ffc) = thread->tp_value; | 462 | *((unsigned int *)0xffff0ff0) = regs->ARM_r0; |
463 | #endif | ||
460 | return 0; | 464 | return 0; |
461 | 465 | ||
462 | default: | 466 | default: |
@@ -493,6 +497,41 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
493 | return 0; | 497 | return 0; |
494 | } | 498 | } |
495 | 499 | ||
500 | #if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG) | ||
501 | |||
502 | /* | ||
503 | * We might be running on an ARMv6+ processor which should have the TLS | ||
504 | * register, but for some reason we can't use it and have to emulate it. | ||
505 | */ | ||
506 | |||
507 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) | ||
508 | { | ||
509 | int reg = (instr >> 12) & 15; | ||
510 | if (reg == 15) | ||
511 | return 1; | ||
512 | regs->uregs[reg] = current_thread_info()->tp_value; | ||
513 | regs->ARM_pc += 4; | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static struct undef_hook arm_mrc_hook = { | ||
518 | .instr_mask = 0x0fff0fff, | ||
519 | .instr_val = 0x0e1d0f70, | ||
520 | .cpsr_mask = PSR_T_BIT, | ||
521 | .cpsr_val = 0, | ||
522 | .fn = get_tp_trap, | ||
523 | }; | ||
524 | |||
525 | static int __init arm_mrc_hook_init(void) | ||
526 | { | ||
527 | register_undef_hook(&arm_mrc_hook); | ||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | late_initcall(arm_mrc_hook_init); | ||
532 | |||
533 | #endif | ||
534 | |||
496 | void __bad_xchg(volatile void *ptr, int size) | 535 | void __bad_xchg(volatile void *ptr, int size) |
497 | { | 536 | { |
498 | printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", | 537 | printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", |
@@ -580,14 +619,17 @@ void __init trap_init(void) | |||
580 | { | 619 | { |
581 | extern char __stubs_start[], __stubs_end[]; | 620 | extern char __stubs_start[], __stubs_end[]; |
582 | extern char __vectors_start[], __vectors_end[]; | 621 | extern char __vectors_start[], __vectors_end[]; |
622 | extern char __kuser_helper_start[], __kuser_helper_end[]; | ||
623 | int kuser_sz = __kuser_helper_end - __kuser_helper_start; | ||
583 | 624 | ||
584 | /* | 625 | /* |
585 | * Copy the vectors and stubs (in entry-armv.S) into the | 626 | * Copy the vectors, stubs and kuser helpers (in entry-armv.S) |
586 | * vector page, mapped at 0xffff0000, and ensure these are | 627 | * into the vector page, mapped at 0xffff0000, and ensure these |
587 | * visible to the instruction stream. | 628 | * are visible to the instruction stream. |
588 | */ | 629 | */ |
589 | memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); | 630 | memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); |
590 | memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); | 631 | memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); |
632 | memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); | ||
591 | flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); | 633 | flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); |
592 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); | 634 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); |
593 | } | 635 | } |
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 54377d0f578c..41e5849ae8da 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <asm/arch/imxfb.h> | ||
29 | #include <asm/hardware.h> | 30 | #include <asm/hardware.h> |
30 | 31 | ||
31 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
@@ -228,6 +229,14 @@ static struct platform_device imx_uart2_device = { | |||
228 | .resource = imx_uart2_resources, | 229 | .resource = imx_uart2_resources, |
229 | }; | 230 | }; |
230 | 231 | ||
232 | static struct imxfb_mach_info imx_fb_info; | ||
233 | |||
234 | void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info) | ||
235 | { | ||
236 | memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imxfb_mach_info)); | ||
237 | } | ||
238 | EXPORT_SYMBOL(set_imx_fb_info); | ||
239 | |||
231 | static struct resource imxfb_resources[] = { | 240 | static struct resource imxfb_resources[] = { |
232 | [0] = { | 241 | [0] = { |
233 | .start = 0x00205000, | 242 | .start = 0x00205000, |
@@ -241,9 +250,16 @@ static struct resource imxfb_resources[] = { | |||
241 | }, | 250 | }, |
242 | }; | 251 | }; |
243 | 252 | ||
253 | static u64 fb_dma_mask = ~(u64)0; | ||
254 | |||
244 | static struct platform_device imxfb_device = { | 255 | static struct platform_device imxfb_device = { |
245 | .name = "imx-fb", | 256 | .name = "imx-fb", |
246 | .id = 0, | 257 | .id = 0, |
258 | .dev = { | ||
259 | .platform_data = &imx_fb_info, | ||
260 | .dma_mask = &fb_dma_mask, | ||
261 | .coherent_dma_mask = 0xffffffff, | ||
262 | }, | ||
247 | .num_resources = ARRAY_SIZE(imxfb_resources), | 263 | .num_resources = ARRAY_SIZE(imxfb_resources), |
248 | .resource = imxfb_resources, | 264 | .resource = imxfb_resources, |
249 | }; | 265 | }; |
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 86c50c3889b7..bd17b5154311 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -216,7 +216,9 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
216 | 216 | ||
217 | write_seqlock(&xtime_lock); | 217 | write_seqlock(&xtime_lock); |
218 | 218 | ||
219 | // ...clear the interrupt | 219 | /* |
220 | * clear the interrupt | ||
221 | */ | ||
220 | timer1->TimerClear = 1; | 222 | timer1->TimerClear = 1; |
221 | 223 | ||
222 | timer_tick(regs); | 224 | timer_tick(regs); |
@@ -264,7 +266,7 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) | |||
264 | timer1->TimerValue = timer_reload; | 266 | timer1->TimerValue = timer_reload; |
265 | timer1->TimerControl = timer_ctrl; | 267 | timer1->TimerControl = timer_ctrl; |
266 | 268 | ||
267 | /* | 269 | /* |
268 | * Make irqs happen for the system timer | 270 | * Make irqs happen for the system timer |
269 | */ | 271 | */ |
270 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); | 272 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 68e15c36e336..3b948e8c2751 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -420,7 +420,22 @@ static struct clcd_panel vga = { | |||
420 | */ | 420 | */ |
421 | static void cp_clcd_enable(struct clcd_fb *fb) | 421 | static void cp_clcd_enable(struct clcd_fb *fb) |
422 | { | 422 | { |
423 | cm_control(CM_CTRL_LCDMUXSEL_MASK, CM_CTRL_LCDMUXSEL_VGA); | 423 | u32 val; |
424 | |||
425 | if (fb->fb.var.bits_per_pixel <= 8) | ||
426 | val = CM_CTRL_LCDMUXSEL_VGA_8421BPP; | ||
427 | else if (fb->fb.var.bits_per_pixel <= 16) | ||
428 | val = CM_CTRL_LCDMUXSEL_VGA_16BPP; | ||
429 | else | ||
430 | val = 0; /* no idea for this, don't trust the docs */ | ||
431 | |||
432 | cm_control(CM_CTRL_LCDMUXSEL_MASK| | ||
433 | CM_CTRL_LCDEN0| | ||
434 | CM_CTRL_LCDEN1| | ||
435 | CM_CTRL_STATIC1| | ||
436 | CM_CTRL_STATIC2| | ||
437 | CM_CTRL_STATIC| | ||
438 | CM_CTRL_n24BITEN, val); | ||
424 | } | 439 | } |
425 | 440 | ||
426 | static unsigned long framesize = SZ_1M; | 441 | static unsigned long framesize = SZ_1M; |
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index 9d182b77b312..d2c0ab21150c 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c | |||
@@ -37,7 +37,7 @@ static void integrator_leds_event(led_event_t ledevt) | |||
37 | unsigned long flags; | 37 | unsigned long flags; |
38 | const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); | 38 | const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); |
39 | unsigned int update_alpha_leds; | 39 | unsigned int update_alpha_leds; |
40 | 40 | ||
41 | // yup, change the LEDs | 41 | // yup, change the LEDs |
42 | local_irq_save(flags); | 42 | local_irq_save(flags); |
43 | update_alpha_leds = 0; | 43 | update_alpha_leds = 0; |
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c index 20729de2af28..1a844ca139e0 100644 --- a/arch/arm/mach-integrator/time.c +++ b/arch/arm/mach-integrator/time.c | |||
@@ -40,25 +40,32 @@ static int integrator_set_rtc(void) | |||
40 | return 1; | 40 | return 1; |
41 | } | 41 | } |
42 | 42 | ||
43 | static void rtc_read_alarm(struct rtc_wkalrm *alrm) | 43 | static int rtc_read_alarm(struct rtc_wkalrm *alrm) |
44 | { | 44 | { |
45 | rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); | 45 | rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); |
46 | return 0; | ||
46 | } | 47 | } |
47 | 48 | ||
48 | static int rtc_set_alarm(struct rtc_wkalrm *alrm) | 49 | static inline int rtc_set_alarm(struct rtc_wkalrm *alrm) |
49 | { | 50 | { |
50 | unsigned long time; | 51 | unsigned long time; |
51 | int ret; | 52 | int ret; |
52 | 53 | ||
53 | ret = rtc_tm_to_time(&alrm->time, &time); | 54 | /* |
55 | * At the moment, we can only deal with non-wildcarded alarm times. | ||
56 | */ | ||
57 | ret = rtc_valid_tm(&alrm->time); | ||
58 | if (ret == 0) | ||
59 | ret = rtc_tm_to_time(&alrm->time, &time); | ||
54 | if (ret == 0) | 60 | if (ret == 0) |
55 | writel(time, rtc_base + RTC_MR); | 61 | writel(time, rtc_base + RTC_MR); |
56 | return ret; | 62 | return ret; |
57 | } | 63 | } |
58 | 64 | ||
59 | static void rtc_read_time(struct rtc_time *tm) | 65 | static int rtc_read_time(struct rtc_time *tm) |
60 | { | 66 | { |
61 | rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); | 67 | rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); |
68 | return 0; | ||
62 | } | 69 | } |
63 | 70 | ||
64 | /* | 71 | /* |
@@ -69,7 +76,7 @@ static void rtc_read_time(struct rtc_time *tm) | |||
69 | * edge of the 1Hz clock, we must write the time one second | 76 | * edge of the 1Hz clock, we must write the time one second |
70 | * in advance. | 77 | * in advance. |
71 | */ | 78 | */ |
72 | static int rtc_set_time(struct rtc_time *tm) | 79 | static inline int rtc_set_time(struct rtc_time *tm) |
73 | { | 80 | { |
74 | unsigned long time; | 81 | unsigned long time; |
75 | int ret; | 82 | int ret; |
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index c4683aaff84a..aec13c7108a9 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c | |||
@@ -65,19 +65,102 @@ static struct sys_timer ixdp2800_timer = { | |||
65 | /************************************************************************* | 65 | /************************************************************************* |
66 | * IXDP2800 PCI | 66 | * IXDP2800 PCI |
67 | *************************************************************************/ | 67 | *************************************************************************/ |
68 | static void __init ixdp2800_slave_disable_pci_master(void) | ||
69 | { | ||
70 | *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); | ||
71 | } | ||
72 | |||
73 | static void __init ixdp2800_master_wait_for_slave(void) | ||
74 | { | ||
75 | volatile u32 *addr; | ||
76 | |||
77 | printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure " | ||
78 | "its BAR sizes\n"); | ||
79 | |||
80 | addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN, | ||
81 | PCI_BASE_ADDRESS_1); | ||
82 | do { | ||
83 | *addr = 0xffffffff; | ||
84 | cpu_relax(); | ||
85 | } while (*addr != 0xfe000008); | ||
86 | |||
87 | addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN, | ||
88 | PCI_BASE_ADDRESS_2); | ||
89 | do { | ||
90 | *addr = 0xffffffff; | ||
91 | cpu_relax(); | ||
92 | } while (*addr != 0xc0000008); | ||
93 | |||
94 | /* | ||
95 | * Configure the slave's SDRAM BAR by hand. | ||
96 | */ | ||
97 | *addr = 0x40000008; | ||
98 | } | ||
99 | |||
100 | static void __init ixdp2800_slave_wait_for_master_enable(void) | ||
101 | { | ||
102 | printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n"); | ||
103 | |||
104 | while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0) | ||
105 | cpu_relax(); | ||
106 | } | ||
107 | |||
68 | void __init ixdp2800_pci_preinit(void) | 108 | void __init ixdp2800_pci_preinit(void) |
69 | { | 109 | { |
70 | printk("ixdp2x00_pci_preinit called\n"); | 110 | printk("ixdp2x00_pci_preinit called\n"); |
71 | 111 | ||
72 | *IXP2000_PCI_ADDR_EXT = 0x0000e000; | 112 | *IXP2000_PCI_ADDR_EXT = 0x0001e000; |
113 | |||
114 | if (!ixdp2x00_master_npu()) | ||
115 | ixdp2800_slave_disable_pci_master(); | ||
73 | 116 | ||
74 | *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff; | ||
75 | *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff; | 117 | *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff; |
118 | *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff; | ||
76 | 119 | ||
77 | ixp2000_pci_preinit(); | 120 | ixp2000_pci_preinit(); |
121 | |||
122 | if (ixdp2x00_master_npu()) { | ||
123 | /* | ||
124 | * Wait until the slave set its SRAM/SDRAM BAR sizes | ||
125 | * correctly before we proceed to scan and enumerate | ||
126 | * the bus. | ||
127 | */ | ||
128 | ixdp2800_master_wait_for_slave(); | ||
129 | |||
130 | /* | ||
131 | * We configure the SDRAM BARs by hand because they | ||
132 | * are 1G and fall outside of the regular allocated | ||
133 | * PCI address space. | ||
134 | */ | ||
135 | *IXP2000_PCI_SDRAM_BAR = 0x00000008; | ||
136 | } else { | ||
137 | /* | ||
138 | * Wait for the master to complete scanning the bus | ||
139 | * and assigning resources before we proceed to scan | ||
140 | * the bus ourselves. Set pci=firmware to honor the | ||
141 | * master's resource assignment. | ||
142 | */ | ||
143 | ixdp2800_slave_wait_for_master_enable(); | ||
144 | pcibios_setup("firmware"); | ||
145 | } | ||
78 | } | 146 | } |
79 | 147 | ||
80 | int ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) | 148 | /* |
149 | * We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside | ||
150 | * of the regular PCI window, because there's only 512M of outbound PCI | ||
151 | * memory window on each IXP, while we need 1G for each of the BARs. | ||
152 | */ | ||
153 | static void __devinit ixp2800_pci_fixup(struct pci_dev *dev) | ||
154 | { | ||
155 | if (machine_is_ixdp2800()) { | ||
156 | dev->resource[2].start = 0; | ||
157 | dev->resource[2].end = 0; | ||
158 | dev->resource[2].flags = 0; | ||
159 | } | ||
160 | } | ||
161 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup); | ||
162 | |||
163 | static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) | ||
81 | { | 164 | { |
82 | sys->mem_offset = 0x00000000; | 165 | sys->mem_offset = 0x00000000; |
83 | 166 | ||
@@ -129,22 +212,47 @@ static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
129 | } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ | 212 | } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ |
130 | } | 213 | } |
131 | 214 | ||
132 | static void ixdp2800_pci_postinit(void) | 215 | static void __init ixdp2800_master_enable_slave(void) |
133 | { | 216 | { |
134 | struct pci_dev *dev; | 217 | volatile u32 *addr; |
135 | 218 | ||
136 | if (ixdp2x00_master_npu()) { | 219 | printk(KERN_INFO "IXDP2800: enabling slave NPU\n"); |
137 | dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); | 220 | |
138 | pci_remove_bus_device(dev); | 221 | addr = (volatile u32 *)ixp2000_pci_config_addr(0, |
139 | } else { | 222 | IXDP2X00_SLAVE_NPU_DEVFN, |
140 | dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); | 223 | PCI_COMMAND); |
141 | pci_remove_bus_device(dev); | 224 | |
225 | *addr |= PCI_COMMAND_MASTER; | ||
226 | } | ||
142 | 227 | ||
228 | static void __init ixdp2800_master_wait_for_slave_bus_scan(void) | ||
229 | { | ||
230 | volatile u32 *addr; | ||
231 | |||
232 | printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n"); | ||
233 | |||
234 | addr = (volatile u32 *)ixp2000_pci_config_addr(0, | ||
235 | IXDP2X00_SLAVE_NPU_DEVFN, | ||
236 | PCI_COMMAND); | ||
237 | while ((*addr & PCI_COMMAND_MEMORY) == 0) | ||
238 | cpu_relax(); | ||
239 | } | ||
240 | |||
241 | static void __init ixdp2800_slave_signal_bus_scan_completion(void) | ||
242 | { | ||
243 | printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n"); | ||
244 | *IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY; | ||
245 | } | ||
246 | |||
247 | static void __init ixdp2800_pci_postinit(void) | ||
248 | { | ||
249 | if (!ixdp2x00_master_npu()) { | ||
143 | ixdp2x00_slave_pci_postinit(); | 250 | ixdp2x00_slave_pci_postinit(); |
251 | ixdp2800_slave_signal_bus_scan_completion(); | ||
144 | } | 252 | } |
145 | } | 253 | } |
146 | 254 | ||
147 | struct hw_pci ixdp2800_pci __initdata = { | 255 | struct __initdata hw_pci ixdp2800_pci __initdata = { |
148 | .nr_controllers = 1, | 256 | .nr_controllers = 1, |
149 | .setup = ixdp2800_pci_setup, | 257 | .setup = ixdp2800_pci_setup, |
150 | .preinit = ixdp2800_pci_preinit, | 258 | .preinit = ixdp2800_pci_preinit, |
@@ -155,8 +263,21 @@ struct hw_pci ixdp2800_pci __initdata = { | |||
155 | 263 | ||
156 | int __init ixdp2800_pci_init(void) | 264 | int __init ixdp2800_pci_init(void) |
157 | { | 265 | { |
158 | if (machine_is_ixdp2800()) | 266 | if (machine_is_ixdp2800()) { |
267 | struct pci_dev *dev; | ||
268 | |||
159 | pci_common_init(&ixdp2800_pci); | 269 | pci_common_init(&ixdp2800_pci); |
270 | if (ixdp2x00_master_npu()) { | ||
271 | dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); | ||
272 | pci_remove_bus_device(dev); | ||
273 | |||
274 | ixdp2800_master_enable_slave(); | ||
275 | ixdp2800_master_wait_for_slave_bus_scan(); | ||
276 | } else { | ||
277 | dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); | ||
278 | pci_remove_bus_device(dev); | ||
279 | } | ||
280 | } | ||
160 | 281 | ||
161 | return 0; | 282 | return 0; |
162 | } | 283 | } |
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 831f8ffb6b61..5ff2f2718c58 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c | |||
@@ -37,7 +37,7 @@ static int pci_master_aborts = 0; | |||
37 | 37 | ||
38 | static int clear_master_aborts(void); | 38 | static int clear_master_aborts(void); |
39 | 39 | ||
40 | static u32 * | 40 | u32 * |
41 | ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) | 41 | ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) |
42 | { | 42 | { |
43 | u32 *paddress; | 43 | u32 *paddress; |
@@ -208,15 +208,15 @@ ixp2000_pci_preinit(void) | |||
208 | * use our own resource space. | 208 | * use our own resource space. |
209 | */ | 209 | */ |
210 | static struct resource ixp2000_pci_mem_space = { | 210 | static struct resource ixp2000_pci_mem_space = { |
211 | .start = 0x00000000, | 211 | .start = 0xe0000000, |
212 | .end = 0xffffffff, | 212 | .end = 0xffffffff, |
213 | .flags = IORESOURCE_MEM, | 213 | .flags = IORESOURCE_MEM, |
214 | .name = "PCI Mem Space" | 214 | .name = "PCI Mem Space" |
215 | }; | 215 | }; |
216 | 216 | ||
217 | static struct resource ixp2000_pci_io_space = { | 217 | static struct resource ixp2000_pci_io_space = { |
218 | .start = 0x00000000, | 218 | .start = 0x00010000, |
219 | .end = 0xffffffff, | 219 | .end = 0x0001ffff, |
220 | .flags = IORESOURCE_IO, | 220 | .flags = IORESOURCE_IO, |
221 | .name = "PCI I/O Space" | 221 | .name = "PCI I/O Space" |
222 | }; | 222 | }; |
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index b1575b8dc1cd..a45aaa115a76 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c | |||
@@ -220,6 +220,30 @@ static struct platform_device stuart_device = { | |||
220 | .id = 2, | 220 | .id = 2, |
221 | }; | 221 | }; |
222 | 222 | ||
223 | static struct resource i2c_resources[] = { | ||
224 | { | ||
225 | .start = 0x40301680, | ||
226 | .end = 0x403016a3, | ||
227 | .flags = IORESOURCE_MEM, | ||
228 | }, { | ||
229 | .start = IRQ_I2C, | ||
230 | .end = IRQ_I2C, | ||
231 | .flags = IORESOURCE_IRQ, | ||
232 | }, | ||
233 | }; | ||
234 | |||
235 | static struct platform_device i2c_device = { | ||
236 | .name = "pxa2xx-i2c", | ||
237 | .id = 0, | ||
238 | .resource = i2c_resources, | ||
239 | .num_resources = ARRAY_SIZE(i2c_resources), | ||
240 | }; | ||
241 | |||
242 | void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) | ||
243 | { | ||
244 | i2c_device.dev.platform_data = info; | ||
245 | } | ||
246 | |||
223 | static struct platform_device *devices[] __initdata = { | 247 | static struct platform_device *devices[] __initdata = { |
224 | &pxamci_device, | 248 | &pxamci_device, |
225 | &udc_device, | 249 | &udc_device, |
@@ -227,6 +251,7 @@ static struct platform_device *devices[] __initdata = { | |||
227 | &ffuart_device, | 251 | &ffuart_device, |
228 | &btuart_device, | 252 | &btuart_device, |
229 | &stuart_device, | 253 | &stuart_device, |
254 | &i2c_device, | ||
230 | }; | 255 | }; |
231 | 256 | ||
232 | static int __init pxa_init(void) | 257 | static int __init pxa_init(void) |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 5b670c9ac5ef..27892e34b060 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -409,3 +409,18 @@ config CPU_BPREDICT_DISABLE | |||
409 | depends on CPU_ARM1020 | 409 | depends on CPU_ARM1020 |
410 | help | 410 | help |
411 | Say Y here to disable branch prediction. If unsure, say N. | 411 | Say Y here to disable branch prediction. If unsure, say N. |
412 | |||
413 | config HAS_TLS_REG | ||
414 | bool | ||
415 | depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3 | ||
416 | default y | ||
417 | help | ||
418 | This selects support for the CP15 thread register. | ||
419 | It is defined to be available on ARMv6 or later. However | ||
420 | if the kernel is configured to support multiple CPUs including | ||
421 | a pre-ARMv6 processors, or if a given ARMv6 processor doesn't | ||
422 | implement the thread register for some reason, then access to | ||
423 | this register from user space must be trapped and emulated. | ||
424 | If user space is relying on the __kuser_get_tls code then | ||
425 | there should not be any impact. | ||
426 | |||
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index 38b2cbb89beb..8f76f3df7b4c 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/linkage.h> | 1 | #include <linux/linkage.h> |
2 | #include <asm/assembler.h> | 2 | #include <asm/assembler.h> |
3 | #include "abort-macro.S" | ||
3 | /* | 4 | /* |
4 | * Function: v6_early_abort | 5 | * Function: v6_early_abort |
5 | * | 6 | * |
@@ -13,11 +14,26 @@ | |||
13 | * : sp = pointer to registers | 14 | * : sp = pointer to registers |
14 | * | 15 | * |
15 | * Purpose : obtain information about current aborted instruction. | 16 | * Purpose : obtain information about current aborted instruction. |
17 | * Note: we read user space. This means we might cause a data | ||
18 | * abort here if the I-TLB and D-TLB aren't seeing the same | ||
19 | * picture. Unfortunately, this does happen. We live with it. | ||
16 | */ | 20 | */ |
17 | .align 5 | 21 | .align 5 |
18 | ENTRY(v6_early_abort) | 22 | ENTRY(v6_early_abort) |
19 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 23 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
20 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 24 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
25 | /* | ||
26 | * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR. | ||
27 | * The test below covers all the write situations, including Java bytecodes | ||
28 | */ | ||
29 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR | ||
30 | tst r3, #PSR_J_BIT @ Java? | ||
31 | movne pc, lr | ||
32 | do_thumb_abort | ||
33 | ldreq r3, [r2] @ read aborted ARM instruction | ||
34 | do_ldrd_abort | ||
35 | tst r3, #1 << 20 @ L = 0 -> write | ||
36 | orreq r1, r1, #1 << 11 @ yes. | ||
21 | mov pc, lr | 37 | mov pc, lr |
22 | 38 | ||
23 | 39 | ||
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index f5a87db8b498..585dfb8e20b9 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
@@ -411,9 +411,10 @@ static void __init build_mem_type_table(void) | |||
411 | mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; | 411 | mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; |
412 | mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; | 412 | mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; |
413 | /* | 413 | /* |
414 | * Mark cache clean areas read only from SVC mode | 414 | * Mark cache clean areas and XIP ROM read only |
415 | * and no access from userspace. | 415 | * from SVC mode and no access from userspace. |
416 | */ | 416 | */ |
417 | mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | ||
417 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 418 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
418 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 419 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
419 | } | 420 | } |
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c index 2a137146a77c..8a52124de0e1 100644 --- a/arch/arm26/kernel/ptrace.c +++ b/arch/arm26/kernel/ptrace.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/ptrace.h> | 18 | #include <linux/ptrace.h> |
19 | #include <linux/user.h> | 19 | #include <linux/user.h> |
20 | #include <linux/security.h> | 20 | #include <linux/security.h> |
21 | #include <linux/signal.h> | ||
21 | 22 | ||
22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
23 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
@@ -591,7 +592,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat | |||
591 | case PTRACE_SYSCALL: | 592 | case PTRACE_SYSCALL: |
592 | case PTRACE_CONT: | 593 | case PTRACE_CONT: |
593 | ret = -EIO; | 594 | ret = -EIO; |
594 | if ((unsigned long) data > _NSIG) | 595 | if (!valid_signal(data)) |
595 | break; | 596 | break; |
596 | if (request == PTRACE_SYSCALL) | 597 | if (request == PTRACE_SYSCALL) |
597 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 598 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -626,7 +627,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat | |||
626 | */ | 627 | */ |
627 | case PTRACE_SINGLESTEP: | 628 | case PTRACE_SINGLESTEP: |
628 | ret = -EIO; | 629 | ret = -EIO; |
629 | if ((unsigned long) data > _NSIG) | 630 | if (!valid_signal(data)) |
630 | break; | 631 | break; |
631 | child->ptrace |= PT_SINGLESTEP; | 632 | child->ptrace |= PT_SINGLESTEP; |
632 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 633 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
diff --git a/arch/arm26/mm/small_page.c b/arch/arm26/mm/small_page.c index 77be86cca789..30447106c25f 100644 --- a/arch/arm26/mm/small_page.c +++ b/arch/arm26/mm/small_page.c | |||
@@ -92,8 +92,7 @@ static unsigned long __get_small_page(int priority, struct order *order) | |||
92 | page = list_entry(order->queue.next, struct page, lru); | 92 | page = list_entry(order->queue.next, struct page, lru); |
93 | again: | 93 | again: |
94 | #ifdef PEDANTIC | 94 | #ifdef PEDANTIC |
95 | if (USED_MAP(page) & ~order->all_used) | 95 | BUG_ON(USED_MAP(page) & ~order->all_used); |
96 | PAGE_BUG(page); | ||
97 | #endif | 96 | #endif |
98 | offset = ffz(USED_MAP(page)); | 97 | offset = ffz(USED_MAP(page)); |
99 | SET_USED(page, offset); | 98 | SET_USED(page, offset); |
@@ -141,8 +140,7 @@ static void __free_small_page(unsigned long spage, struct order *order) | |||
141 | goto non_small; | 140 | goto non_small; |
142 | 141 | ||
143 | #ifdef PEDANTIC | 142 | #ifdef PEDANTIC |
144 | if (USED_MAP(page) & ~order->all_used) | 143 | BUG_ON(USED_MAP(page) & ~order->all_used); |
145 | PAGE_BUG(page); | ||
146 | #endif | 144 | #endif |
147 | 145 | ||
148 | spage = spage >> order->shift; | 146 | spage = spage >> order->shift; |
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index da15db8ae482..581ecabaae53 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/ptrace.h> | 11 | #include <linux/ptrace.h> |
12 | #include <linux/user.h> | 12 | #include <linux/user.h> |
13 | #include <linux/signal.h> | ||
13 | 14 | ||
14 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
15 | #include <asm/page.h> | 16 | #include <asm/page.h> |
@@ -184,7 +185,7 @@ sys_ptrace(long request, long pid, long addr, long data) | |||
184 | case PTRACE_CONT: | 185 | case PTRACE_CONT: |
185 | ret = -EIO; | 186 | ret = -EIO; |
186 | 187 | ||
187 | if ((unsigned long) data > _NSIG) | 188 | if (!valid_signal(data)) |
188 | break; | 189 | break; |
189 | 190 | ||
190 | if (request == PTRACE_SYSCALL) { | 191 | if (request == PTRACE_SYSCALL) { |
@@ -219,7 +220,7 @@ sys_ptrace(long request, long pid, long addr, long data) | |||
219 | case PTRACE_SINGLESTEP: | 220 | case PTRACE_SINGLESTEP: |
220 | ret = -EIO; | 221 | ret = -EIO; |
221 | 222 | ||
222 | if ((unsigned long) data > _NSIG) | 223 | if (!valid_signal(data)) |
223 | break; | 224 | break; |
224 | 225 | ||
225 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 226 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c index 2a0efb739adc..cbe03cba9f02 100644 --- a/arch/frv/kernel/ptrace.c +++ b/arch/frv/kernel/ptrace.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/user.h> | 20 | #include <linux/user.h> |
21 | #include <linux/config.h> | 21 | #include <linux/config.h> |
22 | #include <linux/security.h> | 22 | #include <linux/security.h> |
23 | #include <linux/signal.h> | ||
23 | 24 | ||
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | #include <asm/page.h> | 26 | #include <asm/page.h> |
@@ -239,7 +240,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
239 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 240 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
240 | case PTRACE_CONT: /* restart after signal. */ | 241 | case PTRACE_CONT: /* restart after signal. */ |
241 | ret = -EIO; | 242 | ret = -EIO; |
242 | if ((unsigned long) data > _NSIG) | 243 | if (!valid_signal(data)) |
243 | break; | 244 | break; |
244 | if (request == PTRACE_SYSCALL) | 245 | if (request == PTRACE_SYSCALL) |
245 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 246 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -267,7 +268,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
267 | 268 | ||
268 | case PTRACE_SINGLESTEP: /* set the trap flag. */ | 269 | case PTRACE_SINGLESTEP: /* set the trap flag. */ |
269 | ret = -EIO; | 270 | ret = -EIO; |
270 | if ((unsigned long) data > _NSIG) | 271 | if (!valid_signal(data)) |
271 | break; | 272 | break; |
272 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 273 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
273 | ptrace_enable(child); | 274 | ptrace_enable(child); |
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c index 5f19d774a288..05c15e869777 100644 --- a/arch/h8300/kernel/ptrace.c +++ b/arch/h8300/kernel/ptrace.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/user.h> | 25 | #include <linux/user.h> |
26 | #include <linux/config.h> | 26 | #include <linux/config.h> |
27 | #include <linux/signal.h> | ||
27 | 28 | ||
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | #include <asm/page.h> | 30 | #include <asm/page.h> |
@@ -171,7 +172,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
171 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 172 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
172 | case PTRACE_CONT: { /* restart after signal. */ | 173 | case PTRACE_CONT: { /* restart after signal. */ |
173 | ret = -EIO; | 174 | ret = -EIO; |
174 | if ((unsigned long) data >= _NSIG) | 175 | if (!valid_signal(data)) |
175 | break ; | 176 | break ; |
176 | if (request == PTRACE_SYSCALL) | 177 | if (request == PTRACE_SYSCALL) |
177 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 178 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -202,7 +203,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
202 | 203 | ||
203 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 204 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
204 | ret = -EIO; | 205 | ret = -EIO; |
205 | if ((unsigned long) data > _NSIG) | 206 | if (!valid_signal(data)) |
206 | break; | 207 | break; |
207 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 208 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
208 | child->exit_code = data; | 209 | child->exit_code = data; |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 17a0cbce6f30..99b4f294a52d 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -653,6 +653,24 @@ config I8K | |||
653 | Say Y if you intend to run this kernel on a Dell Inspiron 8000. | 653 | Say Y if you intend to run this kernel on a Dell Inspiron 8000. |
654 | Say N otherwise. | 654 | Say N otherwise. |
655 | 655 | ||
656 | config X86_REBOOTFIXUPS | ||
657 | bool "Enable X86 board specific fixups for reboot" | ||
658 | depends on X86 | ||
659 | default n | ||
660 | ---help--- | ||
661 | This enables chipset and/or board specific fixups to be done | ||
662 | in order to get reboot to work correctly. This is only needed on | ||
663 | some combinations of hardware and BIOS. The symptom, for which | ||
664 | this config is intended, is when reboot ends with a stalled/hung | ||
665 | system. | ||
666 | |||
667 | Currently, the only fixup is for the Geode GX1/CS5530A/TROM2.1. | ||
668 | combination. | ||
669 | |||
670 | Say Y if you want to enable the fixup. Currently, it's safe to | ||
671 | enable this option even if you don't need it. | ||
672 | Say N otherwise. | ||
673 | |||
656 | config MICROCODE | 674 | config MICROCODE |
657 | tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" | 675 | tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" |
658 | ---help--- | 676 | ---help--- |
diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 314c7146e9bf..04783ceb050c 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile | |||
@@ -123,7 +123,7 @@ AFLAGS += $(mflags-y) | |||
123 | boot := arch/i386/boot | 123 | boot := arch/i386/boot |
124 | 124 | ||
125 | .PHONY: zImage bzImage compressed zlilo bzlilo \ | 125 | .PHONY: zImage bzImage compressed zlilo bzlilo \ |
126 | zdisk bzdisk fdimage fdimage144 fdimage288 install | 126 | zdisk bzdisk fdimage fdimage144 fdimage288 install kernel_install |
127 | 127 | ||
128 | all: bzImage | 128 | all: bzImage |
129 | 129 | ||
@@ -145,8 +145,9 @@ zdisk bzdisk: vmlinux | |||
145 | fdimage fdimage144 fdimage288: vmlinux | 145 | fdimage fdimage144 fdimage288: vmlinux |
146 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ | 146 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ |
147 | 147 | ||
148 | install: | 148 | install: vmlinux |
149 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ | 149 | install kernel_install: |
150 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install | ||
150 | 151 | ||
151 | prepare: include/asm-$(ARCH)/asm_offsets.h | 152 | prepare: include/asm-$(ARCH)/asm_offsets.h |
152 | CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h | 153 | CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h |
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index fa67045234a3..cedc55cc47de 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
13 | #include <linux/vmalloc.h> | 13 | #include <linux/vmalloc.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <video/edid.h> | ||
16 | #include <asm/io.h> | 15 | #include <asm/io.h> |
17 | 16 | ||
18 | /* | 17 | /* |
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index a934ab32bf8e..caa1fde6904e 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S | |||
@@ -164,7 +164,7 @@ ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff | |||
164 | trampoline: call start_of_setup | 164 | trampoline: call start_of_setup |
165 | .align 16 | 165 | .align 16 |
166 | # The offset at this point is 0x240 | 166 | # The offset at this point is 0x240 |
167 | .space (0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff) | 167 | .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff) |
168 | # End of setup header ##################################################### | 168 | # End of setup header ##################################################### |
169 | 169 | ||
170 | start_of_setup: | 170 | start_of_setup: |
@@ -333,9 +333,9 @@ jmpe820: | |||
333 | # sizeof(e820rec). | 333 | # sizeof(e820rec). |
334 | # | 334 | # |
335 | good820: | 335 | good820: |
336 | movb (E820NR), %al # up to 32 entries | 336 | movb (E820NR), %al # up to 128 entries |
337 | cmpb $E820MAX, %al | 337 | cmpb $E820MAX, %al |
338 | jnl bail820 | 338 | jae bail820 |
339 | 339 | ||
340 | incb (E820NR) | 340 | incb (E820NR) |
341 | movw %di, %ax | 341 | movw %di, %ax |
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index aacdae6f372d..0fbcfe00dd8d 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o | |||
23 | obj-$(CONFIG_X86_MPPARSE) += mpparse.o | 23 | obj-$(CONFIG_X86_MPPARSE) += mpparse.o |
24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o | 24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o |
25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o | 25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o |
26 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o | ||
26 | obj-$(CONFIG_X86_NUMAQ) += numaq.o | 27 | obj-$(CONFIG_X86_NUMAQ) += numaq.o |
27 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o | 28 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o |
28 | obj-$(CONFIG_KPROBES) += kprobes.o | 29 | obj-$(CONFIG_KPROBES) += kprobes.o |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index e3879f7625c2..d509836b70c3 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -1265,8 +1265,6 @@ int __init APIC_init_uniprocessor (void) | |||
1265 | 1265 | ||
1266 | setup_local_APIC(); | 1266 | setup_local_APIC(); |
1267 | 1267 | ||
1268 | if (nmi_watchdog == NMI_LOCAL_APIC) | ||
1269 | check_nmi_watchdog(); | ||
1270 | #ifdef CONFIG_X86_IO_APIC | 1268 | #ifdef CONFIG_X86_IO_APIC |
1271 | if (smp_found_config) | 1269 | if (smp_found_config) |
1272 | if (!skip_ioapic_setup && nr_ioapics) | 1270 | if (!skip_ioapic_setup && nr_ioapics) |
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 9f7a7ea6388d..f468a979e9aa 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c | |||
@@ -124,8 +124,8 @@ int generic_get_free_region(unsigned long base, unsigned long size) | |||
124 | return -ENOSPC; | 124 | return -ENOSPC; |
125 | } | 125 | } |
126 | 126 | ||
127 | void generic_get_mtrr(unsigned int reg, unsigned long *base, | 127 | static void generic_get_mtrr(unsigned int reg, unsigned long *base, |
128 | unsigned int *size, mtrr_type * type) | 128 | unsigned int *size, mtrr_type * type) |
129 | { | 129 | { |
130 | unsigned int mask_lo, mask_hi, base_lo, base_hi; | 130 | unsigned int mask_lo, mask_hi, base_lo, base_hi; |
131 | 131 | ||
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 54999e4c55fd..e1c2042b9b7e 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c | |||
@@ -72,17 +72,21 @@ void set_mtrr_ops(struct mtrr_ops * ops) | |||
72 | static int have_wrcomb(void) | 72 | static int have_wrcomb(void) |
73 | { | 73 | { |
74 | struct pci_dev *dev; | 74 | struct pci_dev *dev; |
75 | u8 rev; | ||
75 | 76 | ||
76 | if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) { | 77 | if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) { |
77 | /* ServerWorks LE chipsets have problems with write-combining | 78 | /* ServerWorks LE chipsets < rev 6 have problems with write-combining |
78 | Don't allow it and leave room for other chipsets to be tagged */ | 79 | Don't allow it and leave room for other chipsets to be tagged */ |
79 | if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && | 80 | if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && |
80 | dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) { | 81 | dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) { |
81 | printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n"); | 82 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); |
82 | pci_dev_put(dev); | 83 | if (rev <= 5) { |
83 | return 0; | 84 | printk(KERN_INFO "mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n"); |
85 | pci_dev_put(dev); | ||
86 | return 0; | ||
87 | } | ||
84 | } | 88 | } |
85 | /* Intel 450NX errata # 23. Non ascending cachline evictions to | 89 | /* Intel 450NX errata # 23. Non ascending cacheline evictions to |
86 | write combining memory may resulting in data corruption */ | 90 | write combining memory may resulting in data corruption */ |
87 | if (dev->vendor == PCI_VENDOR_ID_INTEL && | 91 | if (dev->vendor == PCI_VENDOR_ID_INTEL && |
88 | dev->device == PCI_DEVICE_ID_INTEL_82451NX) { | 92 | dev->device == PCI_DEVICE_ID_INTEL_82451NX) { |
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index 4f28eba7fb8a..7323c19f354e 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c | |||
@@ -25,7 +25,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
25 | "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", | 25 | "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", |
26 | 26 | ||
27 | /* AMD-defined */ | 27 | /* AMD-defined */ |
28 | "pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 28 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
29 | NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, | 29 | NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, |
30 | NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, | 30 | NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, |
31 | NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow", | 31 | NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow", |
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 3c73dc865ead..a991d4e5edd2 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S | |||
@@ -260,11 +260,9 @@ restore_nocheck: | |||
260 | .section .fixup,"ax" | 260 | .section .fixup,"ax" |
261 | iret_exc: | 261 | iret_exc: |
262 | sti | 262 | sti |
263 | movl $__USER_DS, %edx | 263 | pushl $0 # no error code |
264 | movl %edx, %ds | 264 | pushl $do_iret_error |
265 | movl %edx, %es | 265 | jmp error_code |
266 | movl $11,%eax | ||
267 | call do_exit | ||
268 | .previous | 266 | .previous |
269 | .section __ex_table,"a" | 267 | .section __ex_table,"a" |
270 | .align 4 | 268 | .align 4 |
@@ -516,8 +514,6 @@ debug_stack_correct: | |||
516 | xorl %edx,%edx # error code 0 | 514 | xorl %edx,%edx # error code 0 |
517 | movl %esp,%eax # pt_regs pointer | 515 | movl %esp,%eax # pt_regs pointer |
518 | call do_debug | 516 | call do_debug |
519 | testl %eax,%eax | ||
520 | jnz restore_all | ||
521 | jmp ret_from_exception | 517 | jmp ret_from_exception |
522 | 518 | ||
523 | /* | 519 | /* |
@@ -598,8 +594,6 @@ ENTRY(int3) | |||
598 | xorl %edx,%edx # zero error code | 594 | xorl %edx,%edx # zero error code |
599 | movl %esp,%eax # pt_regs pointer | 595 | movl %esp,%eax # pt_regs pointer |
600 | call do_int3 | 596 | call do_int3 |
601 | testl %eax,%eax | ||
602 | jnz restore_all | ||
603 | jmp ret_from_exception | 597 | jmp ret_from_exception |
604 | 598 | ||
605 | ENTRY(overflow) | 599 | ENTRY(overflow) |
@@ -658,296 +652,6 @@ ENTRY(spurious_interrupt_bug) | |||
658 | pushl $do_spurious_interrupt_bug | 652 | pushl $do_spurious_interrupt_bug |
659 | jmp error_code | 653 | jmp error_code |
660 | 654 | ||
661 | .data | 655 | #include "syscall_table.S" |
662 | ENTRY(sys_call_table) | ||
663 | .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ | ||
664 | .long sys_exit | ||
665 | .long sys_fork | ||
666 | .long sys_read | ||
667 | .long sys_write | ||
668 | .long sys_open /* 5 */ | ||
669 | .long sys_close | ||
670 | .long sys_waitpid | ||
671 | .long sys_creat | ||
672 | .long sys_link | ||
673 | .long sys_unlink /* 10 */ | ||
674 | .long sys_execve | ||
675 | .long sys_chdir | ||
676 | .long sys_time | ||
677 | .long sys_mknod | ||
678 | .long sys_chmod /* 15 */ | ||
679 | .long sys_lchown16 | ||
680 | .long sys_ni_syscall /* old break syscall holder */ | ||
681 | .long sys_stat | ||
682 | .long sys_lseek | ||
683 | .long sys_getpid /* 20 */ | ||
684 | .long sys_mount | ||
685 | .long sys_oldumount | ||
686 | .long sys_setuid16 | ||
687 | .long sys_getuid16 | ||
688 | .long sys_stime /* 25 */ | ||
689 | .long sys_ptrace | ||
690 | .long sys_alarm | ||
691 | .long sys_fstat | ||
692 | .long sys_pause | ||
693 | .long sys_utime /* 30 */ | ||
694 | .long sys_ni_syscall /* old stty syscall holder */ | ||
695 | .long sys_ni_syscall /* old gtty syscall holder */ | ||
696 | .long sys_access | ||
697 | .long sys_nice | ||
698 | .long sys_ni_syscall /* 35 - old ftime syscall holder */ | ||
699 | .long sys_sync | ||
700 | .long sys_kill | ||
701 | .long sys_rename | ||
702 | .long sys_mkdir | ||
703 | .long sys_rmdir /* 40 */ | ||
704 | .long sys_dup | ||
705 | .long sys_pipe | ||
706 | .long sys_times | ||
707 | .long sys_ni_syscall /* old prof syscall holder */ | ||
708 | .long sys_brk /* 45 */ | ||
709 | .long sys_setgid16 | ||
710 | .long sys_getgid16 | ||
711 | .long sys_signal | ||
712 | .long sys_geteuid16 | ||
713 | .long sys_getegid16 /* 50 */ | ||
714 | .long sys_acct | ||
715 | .long sys_umount /* recycled never used phys() */ | ||
716 | .long sys_ni_syscall /* old lock syscall holder */ | ||
717 | .long sys_ioctl | ||
718 | .long sys_fcntl /* 55 */ | ||
719 | .long sys_ni_syscall /* old mpx syscall holder */ | ||
720 | .long sys_setpgid | ||
721 | .long sys_ni_syscall /* old ulimit syscall holder */ | ||
722 | .long sys_olduname | ||
723 | .long sys_umask /* 60 */ | ||
724 | .long sys_chroot | ||
725 | .long sys_ustat | ||
726 | .long sys_dup2 | ||
727 | .long sys_getppid | ||
728 | .long sys_getpgrp /* 65 */ | ||
729 | .long sys_setsid | ||
730 | .long sys_sigaction | ||
731 | .long sys_sgetmask | ||
732 | .long sys_ssetmask | ||
733 | .long sys_setreuid16 /* 70 */ | ||
734 | .long sys_setregid16 | ||
735 | .long sys_sigsuspend | ||
736 | .long sys_sigpending | ||
737 | .long sys_sethostname | ||
738 | .long sys_setrlimit /* 75 */ | ||
739 | .long sys_old_getrlimit | ||
740 | .long sys_getrusage | ||
741 | .long sys_gettimeofday | ||
742 | .long sys_settimeofday | ||
743 | .long sys_getgroups16 /* 80 */ | ||
744 | .long sys_setgroups16 | ||
745 | .long old_select | ||
746 | .long sys_symlink | ||
747 | .long sys_lstat | ||
748 | .long sys_readlink /* 85 */ | ||
749 | .long sys_uselib | ||
750 | .long sys_swapon | ||
751 | .long sys_reboot | ||
752 | .long old_readdir | ||
753 | .long old_mmap /* 90 */ | ||
754 | .long sys_munmap | ||
755 | .long sys_truncate | ||
756 | .long sys_ftruncate | ||
757 | .long sys_fchmod | ||
758 | .long sys_fchown16 /* 95 */ | ||
759 | .long sys_getpriority | ||
760 | .long sys_setpriority | ||
761 | .long sys_ni_syscall /* old profil syscall holder */ | ||
762 | .long sys_statfs | ||
763 | .long sys_fstatfs /* 100 */ | ||
764 | .long sys_ioperm | ||
765 | .long sys_socketcall | ||
766 | .long sys_syslog | ||
767 | .long sys_setitimer | ||
768 | .long sys_getitimer /* 105 */ | ||
769 | .long sys_newstat | ||
770 | .long sys_newlstat | ||
771 | .long sys_newfstat | ||
772 | .long sys_uname | ||
773 | .long sys_iopl /* 110 */ | ||
774 | .long sys_vhangup | ||
775 | .long sys_ni_syscall /* old "idle" system call */ | ||
776 | .long sys_vm86old | ||
777 | .long sys_wait4 | ||
778 | .long sys_swapoff /* 115 */ | ||
779 | .long sys_sysinfo | ||
780 | .long sys_ipc | ||
781 | .long sys_fsync | ||
782 | .long sys_sigreturn | ||
783 | .long sys_clone /* 120 */ | ||
784 | .long sys_setdomainname | ||
785 | .long sys_newuname | ||
786 | .long sys_modify_ldt | ||
787 | .long sys_adjtimex | ||
788 | .long sys_mprotect /* 125 */ | ||
789 | .long sys_sigprocmask | ||
790 | .long sys_ni_syscall /* old "create_module" */ | ||
791 | .long sys_init_module | ||
792 | .long sys_delete_module | ||
793 | .long sys_ni_syscall /* 130: old "get_kernel_syms" */ | ||
794 | .long sys_quotactl | ||
795 | .long sys_getpgid | ||
796 | .long sys_fchdir | ||
797 | .long sys_bdflush | ||
798 | .long sys_sysfs /* 135 */ | ||
799 | .long sys_personality | ||
800 | .long sys_ni_syscall /* reserved for afs_syscall */ | ||
801 | .long sys_setfsuid16 | ||
802 | .long sys_setfsgid16 | ||
803 | .long sys_llseek /* 140 */ | ||
804 | .long sys_getdents | ||
805 | .long sys_select | ||
806 | .long sys_flock | ||
807 | .long sys_msync | ||
808 | .long sys_readv /* 145 */ | ||
809 | .long sys_writev | ||
810 | .long sys_getsid | ||
811 | .long sys_fdatasync | ||
812 | .long sys_sysctl | ||
813 | .long sys_mlock /* 150 */ | ||
814 | .long sys_munlock | ||
815 | .long sys_mlockall | ||
816 | .long sys_munlockall | ||
817 | .long sys_sched_setparam | ||
818 | .long sys_sched_getparam /* 155 */ | ||
819 | .long sys_sched_setscheduler | ||
820 | .long sys_sched_getscheduler | ||
821 | .long sys_sched_yield | ||
822 | .long sys_sched_get_priority_max | ||
823 | .long sys_sched_get_priority_min /* 160 */ | ||
824 | .long sys_sched_rr_get_interval | ||
825 | .long sys_nanosleep | ||
826 | .long sys_mremap | ||
827 | .long sys_setresuid16 | ||
828 | .long sys_getresuid16 /* 165 */ | ||
829 | .long sys_vm86 | ||
830 | .long sys_ni_syscall /* Old sys_query_module */ | ||
831 | .long sys_poll | ||
832 | .long sys_nfsservctl | ||
833 | .long sys_setresgid16 /* 170 */ | ||
834 | .long sys_getresgid16 | ||
835 | .long sys_prctl | ||
836 | .long sys_rt_sigreturn | ||
837 | .long sys_rt_sigaction | ||
838 | .long sys_rt_sigprocmask /* 175 */ | ||
839 | .long sys_rt_sigpending | ||
840 | .long sys_rt_sigtimedwait | ||
841 | .long sys_rt_sigqueueinfo | ||
842 | .long sys_rt_sigsuspend | ||
843 | .long sys_pread64 /* 180 */ | ||
844 | .long sys_pwrite64 | ||
845 | .long sys_chown16 | ||
846 | .long sys_getcwd | ||
847 | .long sys_capget | ||
848 | .long sys_capset /* 185 */ | ||
849 | .long sys_sigaltstack | ||
850 | .long sys_sendfile | ||
851 | .long sys_ni_syscall /* reserved for streams1 */ | ||
852 | .long sys_ni_syscall /* reserved for streams2 */ | ||
853 | .long sys_vfork /* 190 */ | ||
854 | .long sys_getrlimit | ||
855 | .long sys_mmap2 | ||
856 | .long sys_truncate64 | ||
857 | .long sys_ftruncate64 | ||
858 | .long sys_stat64 /* 195 */ | ||
859 | .long sys_lstat64 | ||
860 | .long sys_fstat64 | ||
861 | .long sys_lchown | ||
862 | .long sys_getuid | ||
863 | .long sys_getgid /* 200 */ | ||
864 | .long sys_geteuid | ||
865 | .long sys_getegid | ||
866 | .long sys_setreuid | ||
867 | .long sys_setregid | ||
868 | .long sys_getgroups /* 205 */ | ||
869 | .long sys_setgroups | ||
870 | .long sys_fchown | ||
871 | .long sys_setresuid | ||
872 | .long sys_getresuid | ||
873 | .long sys_setresgid /* 210 */ | ||
874 | .long sys_getresgid | ||
875 | .long sys_chown | ||
876 | .long sys_setuid | ||
877 | .long sys_setgid | ||
878 | .long sys_setfsuid /* 215 */ | ||
879 | .long sys_setfsgid | ||
880 | .long sys_pivot_root | ||
881 | .long sys_mincore | ||
882 | .long sys_madvise | ||
883 | .long sys_getdents64 /* 220 */ | ||
884 | .long sys_fcntl64 | ||
885 | .long sys_ni_syscall /* reserved for TUX */ | ||
886 | .long sys_ni_syscall | ||
887 | .long sys_gettid | ||
888 | .long sys_readahead /* 225 */ | ||
889 | .long sys_setxattr | ||
890 | .long sys_lsetxattr | ||
891 | .long sys_fsetxattr | ||
892 | .long sys_getxattr | ||
893 | .long sys_lgetxattr /* 230 */ | ||
894 | .long sys_fgetxattr | ||
895 | .long sys_listxattr | ||
896 | .long sys_llistxattr | ||
897 | .long sys_flistxattr | ||
898 | .long sys_removexattr /* 235 */ | ||
899 | .long sys_lremovexattr | ||
900 | .long sys_fremovexattr | ||
901 | .long sys_tkill | ||
902 | .long sys_sendfile64 | ||
903 | .long sys_futex /* 240 */ | ||
904 | .long sys_sched_setaffinity | ||
905 | .long sys_sched_getaffinity | ||
906 | .long sys_set_thread_area | ||
907 | .long sys_get_thread_area | ||
908 | .long sys_io_setup /* 245 */ | ||
909 | .long sys_io_destroy | ||
910 | .long sys_io_getevents | ||
911 | .long sys_io_submit | ||
912 | .long sys_io_cancel | ||
913 | .long sys_fadvise64 /* 250 */ | ||
914 | .long sys_ni_syscall | ||
915 | .long sys_exit_group | ||
916 | .long sys_lookup_dcookie | ||
917 | .long sys_epoll_create | ||
918 | .long sys_epoll_ctl /* 255 */ | ||
919 | .long sys_epoll_wait | ||
920 | .long sys_remap_file_pages | ||
921 | .long sys_set_tid_address | ||
922 | .long sys_timer_create | ||
923 | .long sys_timer_settime /* 260 */ | ||
924 | .long sys_timer_gettime | ||
925 | .long sys_timer_getoverrun | ||
926 | .long sys_timer_delete | ||
927 | .long sys_clock_settime | ||
928 | .long sys_clock_gettime /* 265 */ | ||
929 | .long sys_clock_getres | ||
930 | .long sys_clock_nanosleep | ||
931 | .long sys_statfs64 | ||
932 | .long sys_fstatfs64 | ||
933 | .long sys_tgkill /* 270 */ | ||
934 | .long sys_utimes | ||
935 | .long sys_fadvise64_64 | ||
936 | .long sys_ni_syscall /* sys_vserver */ | ||
937 | .long sys_mbind | ||
938 | .long sys_get_mempolicy | ||
939 | .long sys_set_mempolicy | ||
940 | .long sys_mq_open | ||
941 | .long sys_mq_unlink | ||
942 | .long sys_mq_timedsend | ||
943 | .long sys_mq_timedreceive /* 280 */ | ||
944 | .long sys_mq_notify | ||
945 | .long sys_mq_getsetattr | ||
946 | .long sys_ni_syscall /* reserved for kexec */ | ||
947 | .long sys_waitid | ||
948 | .long sys_ni_syscall /* 285 */ /* available */ | ||
949 | .long sys_add_key | ||
950 | .long sys_request_key | ||
951 | .long sys_keyctl | ||
952 | 656 | ||
953 | syscall_table_size=(.-sys_call_table) | 657 | syscall_table_size=(.-sys_call_table) |
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index d273fd746192..e966fc8c44c4 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -380,6 +380,7 @@ rp_sidt: | |||
380 | ALIGN | 380 | ALIGN |
381 | ignore_int: | 381 | ignore_int: |
382 | cld | 382 | cld |
383 | #ifdef CONFIG_PRINTK | ||
383 | pushl %eax | 384 | pushl %eax |
384 | pushl %ecx | 385 | pushl %ecx |
385 | pushl %edx | 386 | pushl %edx |
@@ -400,6 +401,7 @@ ignore_int: | |||
400 | popl %edx | 401 | popl %edx |
401 | popl %ecx | 402 | popl %ecx |
402 | popl %eax | 403 | popl %eax |
404 | #endif | ||
403 | iret | 405 | iret |
404 | 406 | ||
405 | /* | 407 | /* |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 5e0d55be5435..7a324e8b86f9 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -2175,7 +2175,6 @@ static inline void check_timer(void) | |||
2175 | disable_8259A_irq(0); | 2175 | disable_8259A_irq(0); |
2176 | setup_nmi(); | 2176 | setup_nmi(); |
2177 | enable_8259A_irq(0); | 2177 | enable_8259A_irq(0); |
2178 | check_nmi_watchdog(); | ||
2179 | } | 2178 | } |
2180 | return; | 2179 | return; |
2181 | } | 2180 | } |
@@ -2198,7 +2197,6 @@ static inline void check_timer(void) | |||
2198 | add_pin_to_irq(0, 0, pin2); | 2197 | add_pin_to_irq(0, 0, pin2); |
2199 | if (nmi_watchdog == NMI_IO_APIC) { | 2198 | if (nmi_watchdog == NMI_IO_APIC) { |
2200 | setup_nmi(); | 2199 | setup_nmi(); |
2201 | check_nmi_watchdog(); | ||
2202 | } | 2200 | } |
2203 | return; | 2201 | return; |
2204 | } | 2202 | } |
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 2f89d000f954..2c0ee9c2d020 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -102,20 +102,21 @@ int nmi_active; | |||
102 | (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ | 102 | (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ |
103 | P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) | 103 | P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) |
104 | 104 | ||
105 | int __init check_nmi_watchdog (void) | 105 | static int __init check_nmi_watchdog(void) |
106 | { | 106 | { |
107 | unsigned int prev_nmi_count[NR_CPUS]; | 107 | unsigned int prev_nmi_count[NR_CPUS]; |
108 | int cpu; | 108 | int cpu; |
109 | 109 | ||
110 | printk(KERN_INFO "testing NMI watchdog ... "); | 110 | if (nmi_watchdog == NMI_NONE) |
111 | return 0; | ||
112 | |||
113 | printk(KERN_INFO "Testing NMI watchdog ... "); | ||
111 | 114 | ||
112 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 115 | for (cpu = 0; cpu < NR_CPUS; cpu++) |
113 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; | 116 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; |
114 | local_irq_enable(); | 117 | local_irq_enable(); |
115 | mdelay((10*1000)/nmi_hz); // wait 10 ticks | 118 | mdelay((10*1000)/nmi_hz); // wait 10 ticks |
116 | 119 | ||
117 | /* FIXME: Only boot CPU is online at this stage. Check CPUs | ||
118 | as they come up. */ | ||
119 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 120 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
120 | #ifdef CONFIG_SMP | 121 | #ifdef CONFIG_SMP |
121 | /* Check cpu_callin_map here because that is set | 122 | /* Check cpu_callin_map here because that is set |
@@ -139,6 +140,8 @@ int __init check_nmi_watchdog (void) | |||
139 | 140 | ||
140 | return 0; | 141 | return 0; |
141 | } | 142 | } |
143 | /* This needs to happen later in boot so counters are working */ | ||
144 | late_initcall(check_nmi_watchdog); | ||
142 | 145 | ||
143 | static int __init setup_nmi_watchdog(char *str) | 146 | static int __init setup_nmi_watchdog(char *str) |
144 | { | 147 | { |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index b2203e21acb3..85bd56d44314 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -611,8 +611,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas | |||
611 | * Save away %fs and %gs. No need to save %es and %ds, as | 611 | * Save away %fs and %gs. No need to save %es and %ds, as |
612 | * those are always kernel segments while inside the kernel. | 612 | * those are always kernel segments while inside the kernel. |
613 | */ | 613 | */ |
614 | asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->fs)); | 614 | asm volatile("mov %%fs,%0":"=m" (prev->fs)); |
615 | asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs)); | 615 | asm volatile("mov %%gs,%0":"=m" (prev->gs)); |
616 | 616 | ||
617 | /* | 617 | /* |
618 | * Restore %fs and %gs if needed. | 618 | * Restore %fs and %gs if needed. |
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index b2f17640ceff..e8c965ce86eb 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/security.h> | 16 | #include <linux/security.h> |
17 | #include <linux/audit.h> | 17 | #include <linux/audit.h> |
18 | #include <linux/seccomp.h> | 18 | #include <linux/seccomp.h> |
19 | #include <linux/signal.h> | ||
19 | 20 | ||
20 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
21 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
@@ -511,7 +512,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
511 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 512 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
512 | case PTRACE_CONT: /* restart after signal. */ | 513 | case PTRACE_CONT: /* restart after signal. */ |
513 | ret = -EIO; | 514 | ret = -EIO; |
514 | if ((unsigned long) data > _NSIG) | 515 | if (!valid_signal(data)) |
515 | break; | 516 | break; |
516 | if (request == PTRACE_SYSCALL) { | 517 | if (request == PTRACE_SYSCALL) { |
517 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 518 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -543,7 +544,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
543 | 544 | ||
544 | case PTRACE_SINGLESTEP: /* set the trap flag. */ | 545 | case PTRACE_SINGLESTEP: /* set the trap flag. */ |
545 | ret = -EIO; | 546 | ret = -EIO; |
546 | if ((unsigned long) data > _NSIG) | 547 | if (!valid_signal(data)) |
547 | break; | 548 | break; |
548 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 549 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
549 | set_singlestep(child); | 550 | set_singlestep(child); |
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 3d7e994563df..6dc27eb70ee7 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
14 | #include <asm/apic.h> | 14 | #include <asm/apic.h> |
15 | #include "mach_reboot.h" | 15 | #include "mach_reboot.h" |
16 | #include <linux/reboot_fixups.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * Power off function, if any | 19 | * Power off function, if any |
@@ -348,6 +349,7 @@ void machine_restart(char * __unused) | |||
348 | /* rebooting needs to touch the page at absolute addr 0 */ | 349 | /* rebooting needs to touch the page at absolute addr 0 */ |
349 | *((unsigned short *)__va(0x472)) = reboot_mode; | 350 | *((unsigned short *)__va(0x472)) = reboot_mode; |
350 | for (;;) { | 351 | for (;;) { |
352 | mach_reboot_fixups(); /* for board specific fixups */ | ||
351 | mach_reboot(); | 353 | mach_reboot(); |
352 | /* That didn't work - force a triple fault.. */ | 354 | /* That didn't work - force a triple fault.. */ |
353 | __asm__ __volatile__("lidt %0": :"m" (no_idt)); | 355 | __asm__ __volatile__("lidt %0": :"m" (no_idt)); |
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c new file mode 100644 index 000000000000..1b183b378c2c --- /dev/null +++ b/arch/i386/kernel/reboot_fixups.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * linux/arch/i386/kernel/reboot_fixups.c | ||
3 | * | ||
4 | * This is a good place to put board specific reboot fixups. | ||
5 | * | ||
6 | * List of supported fixups: | ||
7 | * geode-gx1/cs5530a - Jaya Kumar <jayalk@intworks.biz> | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <asm/delay.h> | ||
12 | #include <linux/pci.h> | ||
13 | |||
14 | static void cs5530a_warm_reset(struct pci_dev *dev) | ||
15 | { | ||
16 | /* writing 1 to the reset control register, 0x44 causes the | ||
17 | cs5530a to perform a system warm reset */ | ||
18 | pci_write_config_byte(dev, 0x44, 0x1); | ||
19 | udelay(50); /* shouldn't get here but be safe and spin-a-while */ | ||
20 | return; | ||
21 | } | ||
22 | |||
23 | struct device_fixup { | ||
24 | unsigned int vendor; | ||
25 | unsigned int device; | ||
26 | void (*reboot_fixup)(struct pci_dev *); | ||
27 | }; | ||
28 | |||
29 | static struct device_fixup fixups_table[] = { | ||
30 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset }, | ||
31 | }; | ||
32 | |||
33 | /* | ||
34 | * we see if any fixup is available for our current hardware. if there | ||
35 | * is a fixup, we call it and we expect to never return from it. if we | ||
36 | * do return, we keep looking and then eventually fall back to the | ||
37 | * standard mach_reboot on return. | ||
38 | */ | ||
39 | void mach_reboot_fixups(void) | ||
40 | { | ||
41 | struct device_fixup *cur; | ||
42 | struct pci_dev *dev; | ||
43 | int i; | ||
44 | |||
45 | for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) { | ||
46 | cur = &(fixups_table[i]); | ||
47 | dev = pci_get_device(cur->vendor, cur->device, 0); | ||
48 | if (!dev) | ||
49 | continue; | ||
50 | |||
51 | cur->reboot_fixup(dev); | ||
52 | } | ||
53 | |||
54 | printk(KERN_WARNING "No reboot fixup found for your hardware\n"); | ||
55 | } | ||
56 | |||
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index fd36d2f65f88..cbea7ac582e5 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -1089,9 +1089,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1089 | } | 1089 | } |
1090 | } | 1090 | } |
1091 | 1091 | ||
1092 | if (nmi_watchdog == NMI_LOCAL_APIC) | ||
1093 | check_nmi_watchdog(); | ||
1094 | |||
1095 | smpboot_setup_io_apic(); | 1092 | smpboot_setup_io_apic(); |
1096 | 1093 | ||
1097 | setup_boot_APIC_clock(); | 1094 | setup_boot_APIC_clock(); |
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S new file mode 100644 index 000000000000..6cd1ed311f02 --- /dev/null +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -0,0 +1,291 @@ | |||
1 | .data | ||
2 | ENTRY(sys_call_table) | ||
3 | .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ | ||
4 | .long sys_exit | ||
5 | .long sys_fork | ||
6 | .long sys_read | ||
7 | .long sys_write | ||
8 | .long sys_open /* 5 */ | ||
9 | .long sys_close | ||
10 | .long sys_waitpid | ||
11 | .long sys_creat | ||
12 | .long sys_link | ||
13 | .long sys_unlink /* 10 */ | ||
14 | .long sys_execve | ||
15 | .long sys_chdir | ||
16 | .long sys_time | ||
17 | .long sys_mknod | ||
18 | .long sys_chmod /* 15 */ | ||
19 | .long sys_lchown16 | ||
20 | .long sys_ni_syscall /* old break syscall holder */ | ||
21 | .long sys_stat | ||
22 | .long sys_lseek | ||
23 | .long sys_getpid /* 20 */ | ||
24 | .long sys_mount | ||
25 | .long sys_oldumount | ||
26 | .long sys_setuid16 | ||
27 | .long sys_getuid16 | ||
28 | .long sys_stime /* 25 */ | ||
29 | .long sys_ptrace | ||
30 | .long sys_alarm | ||
31 | .long sys_fstat | ||
32 | .long sys_pause | ||
33 | .long sys_utime /* 30 */ | ||
34 | .long sys_ni_syscall /* old stty syscall holder */ | ||
35 | .long sys_ni_syscall /* old gtty syscall holder */ | ||
36 | .long sys_access | ||
37 | .long sys_nice | ||
38 | .long sys_ni_syscall /* 35 - old ftime syscall holder */ | ||
39 | .long sys_sync | ||
40 | .long sys_kill | ||
41 | .long sys_rename | ||
42 | .long sys_mkdir | ||
43 | .long sys_rmdir /* 40 */ | ||
44 | .long sys_dup | ||
45 | .long sys_pipe | ||
46 | .long sys_times | ||
47 | .long sys_ni_syscall /* old prof syscall holder */ | ||
48 | .long sys_brk /* 45 */ | ||
49 | .long sys_setgid16 | ||
50 | .long sys_getgid16 | ||
51 | .long sys_signal | ||
52 | .long sys_geteuid16 | ||
53 | .long sys_getegid16 /* 50 */ | ||
54 | .long sys_acct | ||
55 | .long sys_umount /* recycled never used phys() */ | ||
56 | .long sys_ni_syscall /* old lock syscall holder */ | ||
57 | .long sys_ioctl | ||
58 | .long sys_fcntl /* 55 */ | ||
59 | .long sys_ni_syscall /* old mpx syscall holder */ | ||
60 | .long sys_setpgid | ||
61 | .long sys_ni_syscall /* old ulimit syscall holder */ | ||
62 | .long sys_olduname | ||
63 | .long sys_umask /* 60 */ | ||
64 | .long sys_chroot | ||
65 | .long sys_ustat | ||
66 | .long sys_dup2 | ||
67 | .long sys_getppid | ||
68 | .long sys_getpgrp /* 65 */ | ||
69 | .long sys_setsid | ||
70 | .long sys_sigaction | ||
71 | .long sys_sgetmask | ||
72 | .long sys_ssetmask | ||
73 | .long sys_setreuid16 /* 70 */ | ||
74 | .long sys_setregid16 | ||
75 | .long sys_sigsuspend | ||
76 | .long sys_sigpending | ||
77 | .long sys_sethostname | ||
78 | .long sys_setrlimit /* 75 */ | ||
79 | .long sys_old_getrlimit | ||
80 | .long sys_getrusage | ||
81 | .long sys_gettimeofday | ||
82 | .long sys_settimeofday | ||
83 | .long sys_getgroups16 /* 80 */ | ||
84 | .long sys_setgroups16 | ||
85 | .long old_select | ||
86 | .long sys_symlink | ||
87 | .long sys_lstat | ||
88 | .long sys_readlink /* 85 */ | ||
89 | .long sys_uselib | ||
90 | .long sys_swapon | ||
91 | .long sys_reboot | ||
92 | .long old_readdir | ||
93 | .long old_mmap /* 90 */ | ||
94 | .long sys_munmap | ||
95 | .long sys_truncate | ||
96 | .long sys_ftruncate | ||
97 | .long sys_fchmod | ||
98 | .long sys_fchown16 /* 95 */ | ||
99 | .long sys_getpriority | ||
100 | .long sys_setpriority | ||
101 | .long sys_ni_syscall /* old profil syscall holder */ | ||
102 | .long sys_statfs | ||
103 | .long sys_fstatfs /* 100 */ | ||
104 | .long sys_ioperm | ||
105 | .long sys_socketcall | ||
106 | .long sys_syslog | ||
107 | .long sys_setitimer | ||
108 | .long sys_getitimer /* 105 */ | ||
109 | .long sys_newstat | ||
110 | .long sys_newlstat | ||
111 | .long sys_newfstat | ||
112 | .long sys_uname | ||
113 | .long sys_iopl /* 110 */ | ||
114 | .long sys_vhangup | ||
115 | .long sys_ni_syscall /* old "idle" system call */ | ||
116 | .long sys_vm86old | ||
117 | .long sys_wait4 | ||
118 | .long sys_swapoff /* 115 */ | ||
119 | .long sys_sysinfo | ||
120 | .long sys_ipc | ||
121 | .long sys_fsync | ||
122 | .long sys_sigreturn | ||
123 | .long sys_clone /* 120 */ | ||
124 | .long sys_setdomainname | ||
125 | .long sys_newuname | ||
126 | .long sys_modify_ldt | ||
127 | .long sys_adjtimex | ||
128 | .long sys_mprotect /* 125 */ | ||
129 | .long sys_sigprocmask | ||
130 | .long sys_ni_syscall /* old "create_module" */ | ||
131 | .long sys_init_module | ||
132 | .long sys_delete_module | ||
133 | .long sys_ni_syscall /* 130: old "get_kernel_syms" */ | ||
134 | .long sys_quotactl | ||
135 | .long sys_getpgid | ||
136 | .long sys_fchdir | ||
137 | .long sys_bdflush | ||
138 | .long sys_sysfs /* 135 */ | ||
139 | .long sys_personality | ||
140 | .long sys_ni_syscall /* reserved for afs_syscall */ | ||
141 | .long sys_setfsuid16 | ||
142 | .long sys_setfsgid16 | ||
143 | .long sys_llseek /* 140 */ | ||
144 | .long sys_getdents | ||
145 | .long sys_select | ||
146 | .long sys_flock | ||
147 | .long sys_msync | ||
148 | .long sys_readv /* 145 */ | ||
149 | .long sys_writev | ||
150 | .long sys_getsid | ||
151 | .long sys_fdatasync | ||
152 | .long sys_sysctl | ||
153 | .long sys_mlock /* 150 */ | ||
154 | .long sys_munlock | ||
155 | .long sys_mlockall | ||
156 | .long sys_munlockall | ||
157 | .long sys_sched_setparam | ||
158 | .long sys_sched_getparam /* 155 */ | ||
159 | .long sys_sched_setscheduler | ||
160 | .long sys_sched_getscheduler | ||
161 | .long sys_sched_yield | ||
162 | .long sys_sched_get_priority_max | ||
163 | .long sys_sched_get_priority_min /* 160 */ | ||
164 | .long sys_sched_rr_get_interval | ||
165 | .long sys_nanosleep | ||
166 | .long sys_mremap | ||
167 | .long sys_setresuid16 | ||
168 | .long sys_getresuid16 /* 165 */ | ||
169 | .long sys_vm86 | ||
170 | .long sys_ni_syscall /* Old sys_query_module */ | ||
171 | .long sys_poll | ||
172 | .long sys_nfsservctl | ||
173 | .long sys_setresgid16 /* 170 */ | ||
174 | .long sys_getresgid16 | ||
175 | .long sys_prctl | ||
176 | .long sys_rt_sigreturn | ||
177 | .long sys_rt_sigaction | ||
178 | .long sys_rt_sigprocmask /* 175 */ | ||
179 | .long sys_rt_sigpending | ||
180 | .long sys_rt_sigtimedwait | ||
181 | .long sys_rt_sigqueueinfo | ||
182 | .long sys_rt_sigsuspend | ||
183 | .long sys_pread64 /* 180 */ | ||
184 | .long sys_pwrite64 | ||
185 | .long sys_chown16 | ||
186 | .long sys_getcwd | ||
187 | .long sys_capget | ||
188 | .long sys_capset /* 185 */ | ||
189 | .long sys_sigaltstack | ||
190 | .long sys_sendfile | ||
191 | .long sys_ni_syscall /* reserved for streams1 */ | ||
192 | .long sys_ni_syscall /* reserved for streams2 */ | ||
193 | .long sys_vfork /* 190 */ | ||
194 | .long sys_getrlimit | ||
195 | .long sys_mmap2 | ||
196 | .long sys_truncate64 | ||
197 | .long sys_ftruncate64 | ||
198 | .long sys_stat64 /* 195 */ | ||
199 | .long sys_lstat64 | ||
200 | .long sys_fstat64 | ||
201 | .long sys_lchown | ||
202 | .long sys_getuid | ||
203 | .long sys_getgid /* 200 */ | ||
204 | .long sys_geteuid | ||
205 | .long sys_getegid | ||
206 | .long sys_setreuid | ||
207 | .long sys_setregid | ||
208 | .long sys_getgroups /* 205 */ | ||
209 | .long sys_setgroups | ||
210 | .long sys_fchown | ||
211 | .long sys_setresuid | ||
212 | .long sys_getresuid | ||
213 | .long sys_setresgid /* 210 */ | ||
214 | .long sys_getresgid | ||
215 | .long sys_chown | ||
216 | .long sys_setuid | ||
217 | .long sys_setgid | ||
218 | .long sys_setfsuid /* 215 */ | ||
219 | .long sys_setfsgid | ||
220 | .long sys_pivot_root | ||
221 | .long sys_mincore | ||
222 | .long sys_madvise | ||
223 | .long sys_getdents64 /* 220 */ | ||
224 | .long sys_fcntl64 | ||
225 | .long sys_ni_syscall /* reserved for TUX */ | ||
226 | .long sys_ni_syscall | ||
227 | .long sys_gettid | ||
228 | .long sys_readahead /* 225 */ | ||
229 | .long sys_setxattr | ||
230 | .long sys_lsetxattr | ||
231 | .long sys_fsetxattr | ||
232 | .long sys_getxattr | ||
233 | .long sys_lgetxattr /* 230 */ | ||
234 | .long sys_fgetxattr | ||
235 | .long sys_listxattr | ||
236 | .long sys_llistxattr | ||
237 | .long sys_flistxattr | ||
238 | .long sys_removexattr /* 235 */ | ||
239 | .long sys_lremovexattr | ||
240 | .long sys_fremovexattr | ||
241 | .long sys_tkill | ||
242 | .long sys_sendfile64 | ||
243 | .long sys_futex /* 240 */ | ||
244 | .long sys_sched_setaffinity | ||
245 | .long sys_sched_getaffinity | ||
246 | .long sys_set_thread_area | ||
247 | .long sys_get_thread_area | ||
248 | .long sys_io_setup /* 245 */ | ||
249 | .long sys_io_destroy | ||
250 | .long sys_io_getevents | ||
251 | .long sys_io_submit | ||
252 | .long sys_io_cancel | ||
253 | .long sys_fadvise64 /* 250 */ | ||
254 | .long sys_ni_syscall | ||
255 | .long sys_exit_group | ||
256 | .long sys_lookup_dcookie | ||
257 | .long sys_epoll_create | ||
258 | .long sys_epoll_ctl /* 255 */ | ||
259 | .long sys_epoll_wait | ||
260 | .long sys_remap_file_pages | ||
261 | .long sys_set_tid_address | ||
262 | .long sys_timer_create | ||
263 | .long sys_timer_settime /* 260 */ | ||
264 | .long sys_timer_gettime | ||
265 | .long sys_timer_getoverrun | ||
266 | .long sys_timer_delete | ||
267 | .long sys_clock_settime | ||
268 | .long sys_clock_gettime /* 265 */ | ||
269 | .long sys_clock_getres | ||
270 | .long sys_clock_nanosleep | ||
271 | .long sys_statfs64 | ||
272 | .long sys_fstatfs64 | ||
273 | .long sys_tgkill /* 270 */ | ||
274 | .long sys_utimes | ||
275 | .long sys_fadvise64_64 | ||
276 | .long sys_ni_syscall /* sys_vserver */ | ||
277 | .long sys_mbind | ||
278 | .long sys_get_mempolicy | ||
279 | .long sys_set_mempolicy | ||
280 | .long sys_mq_open | ||
281 | .long sys_mq_unlink | ||
282 | .long sys_mq_timedsend | ||
283 | .long sys_mq_timedreceive /* 280 */ | ||
284 | .long sys_mq_notify | ||
285 | .long sys_mq_getsetattr | ||
286 | .long sys_ni_syscall /* reserved for kexec */ | ||
287 | .long sys_waitid | ||
288 | .long sys_ni_syscall /* 285 */ /* available */ | ||
289 | .long sys_add_key | ||
290 | .long sys_request_key | ||
291 | .long sys_keyctl | ||
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 4d75b373f90e..a0dcb7c87c30 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c | |||
@@ -441,7 +441,7 @@ static void __init hpet_time_init(void) | |||
441 | set_normalized_timespec(&wall_to_monotonic, | 441 | set_normalized_timespec(&wall_to_monotonic, |
442 | -xtime.tv_sec, -xtime.tv_nsec); | 442 | -xtime.tv_sec, -xtime.tv_nsec); |
443 | 443 | ||
444 | if (hpet_enable() >= 0) { | 444 | if ((hpet_enable() >= 0) && hpet_use_timer) { |
445 | printk("Using HPET for base-timer\n"); | 445 | printk("Using HPET for base-timer\n"); |
446 | } | 446 | } |
447 | 447 | ||
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c index 244a31b04be7..10a0cbb88e75 100644 --- a/arch/i386/kernel/time_hpet.c +++ b/arch/i386/kernel/time_hpet.c | |||
@@ -26,6 +26,7 @@ | |||
26 | static unsigned long hpet_period; /* fsecs / HPET clock */ | 26 | static unsigned long hpet_period; /* fsecs / HPET clock */ |
27 | unsigned long hpet_tick; /* hpet clks count per tick */ | 27 | unsigned long hpet_tick; /* hpet clks count per tick */ |
28 | unsigned long hpet_address; /* hpet memory map physical address */ | 28 | unsigned long hpet_address; /* hpet memory map physical address */ |
29 | int hpet_use_timer; | ||
29 | 30 | ||
30 | static int use_hpet; /* can be used for runtime check of hpet */ | 31 | static int use_hpet; /* can be used for runtime check of hpet */ |
31 | static int boot_hpet_disable; /* boottime override for HPET timer */ | 32 | static int boot_hpet_disable; /* boottime override for HPET timer */ |
@@ -73,27 +74,30 @@ static int hpet_timer_stop_set_go(unsigned long tick) | |||
73 | hpet_writel(0, HPET_COUNTER); | 74 | hpet_writel(0, HPET_COUNTER); |
74 | hpet_writel(0, HPET_COUNTER + 4); | 75 | hpet_writel(0, HPET_COUNTER + 4); |
75 | 76 | ||
76 | /* | 77 | if (hpet_use_timer) { |
77 | * Set up timer 0, as periodic with first interrupt to happen at | 78 | /* |
78 | * hpet_tick, and period also hpet_tick. | 79 | * Set up timer 0, as periodic with first interrupt to happen at |
79 | */ | 80 | * hpet_tick, and period also hpet_tick. |
80 | cfg = hpet_readl(HPET_T0_CFG); | 81 | */ |
81 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | | 82 | cfg = hpet_readl(HPET_T0_CFG); |
82 | HPET_TN_SETVAL | HPET_TN_32BIT; | 83 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | |
83 | hpet_writel(cfg, HPET_T0_CFG); | 84 | HPET_TN_SETVAL | HPET_TN_32BIT; |
84 | 85 | hpet_writel(cfg, HPET_T0_CFG); | |
85 | /* | ||
86 | * The first write after writing TN_SETVAL to the config register sets | ||
87 | * the counter value, the second write sets the threshold. | ||
88 | */ | ||
89 | hpet_writel(tick, HPET_T0_CMP); | ||
90 | hpet_writel(tick, HPET_T0_CMP); | ||
91 | 86 | ||
87 | /* | ||
88 | * The first write after writing TN_SETVAL to the config register sets | ||
89 | * the counter value, the second write sets the threshold. | ||
90 | */ | ||
91 | hpet_writel(tick, HPET_T0_CMP); | ||
92 | hpet_writel(tick, HPET_T0_CMP); | ||
93 | } | ||
92 | /* | 94 | /* |
93 | * Go! | 95 | * Go! |
94 | */ | 96 | */ |
95 | cfg = hpet_readl(HPET_CFG); | 97 | cfg = hpet_readl(HPET_CFG); |
96 | cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY; | 98 | if (hpet_use_timer) |
99 | cfg |= HPET_CFG_LEGACY; | ||
100 | cfg |= HPET_CFG_ENABLE; | ||
97 | hpet_writel(cfg, HPET_CFG); | 101 | hpet_writel(cfg, HPET_CFG); |
98 | 102 | ||
99 | return 0; | 103 | return 0; |
@@ -128,12 +132,11 @@ int __init hpet_enable(void) | |||
128 | * However, we can do with one timer otherwise using the | 132 | * However, we can do with one timer otherwise using the |
129 | * the single HPET timer for system time. | 133 | * the single HPET timer for system time. |
130 | */ | 134 | */ |
131 | if ( | ||
132 | #ifdef CONFIG_HPET_EMULATE_RTC | 135 | #ifdef CONFIG_HPET_EMULATE_RTC |
133 | !(id & HPET_ID_NUMBER) || | 136 | if (!(id & HPET_ID_NUMBER)) |
134 | #endif | ||
135 | !(id & HPET_ID_LEGSUP)) | ||
136 | return -1; | 137 | return -1; |
138 | #endif | ||
139 | |||
137 | 140 | ||
138 | hpet_period = hpet_readl(HPET_PERIOD); | 141 | hpet_period = hpet_readl(HPET_PERIOD); |
139 | if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) | 142 | if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) |
@@ -152,6 +155,8 @@ int __init hpet_enable(void) | |||
152 | if (hpet_tick_rem > (hpet_period >> 1)) | 155 | if (hpet_tick_rem > (hpet_period >> 1)) |
153 | hpet_tick++; /* rounding the result */ | 156 | hpet_tick++; /* rounding the result */ |
154 | 157 | ||
158 | hpet_use_timer = id & HPET_ID_LEGSUP; | ||
159 | |||
155 | if (hpet_timer_stop_set_go(hpet_tick)) | 160 | if (hpet_timer_stop_set_go(hpet_tick)) |
156 | return -1; | 161 | return -1; |
157 | 162 | ||
@@ -202,7 +207,8 @@ int __init hpet_enable(void) | |||
202 | #endif | 207 | #endif |
203 | 208 | ||
204 | #ifdef CONFIG_X86_LOCAL_APIC | 209 | #ifdef CONFIG_X86_LOCAL_APIC |
205 | wait_timer_tick = wait_hpet_tick; | 210 | if (hpet_use_timer) |
211 | wait_timer_tick = wait_hpet_tick; | ||
206 | #endif | 212 | #endif |
207 | return 0; | 213 | return 0; |
208 | } | 214 | } |
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c index 713134e71844..f778f471a09a 100644 --- a/arch/i386/kernel/timers/timer_hpet.c +++ b/arch/i386/kernel/timers/timer_hpet.c | |||
@@ -79,7 +79,7 @@ static unsigned long get_offset_hpet(void) | |||
79 | 79 | ||
80 | eax = hpet_readl(HPET_COUNTER); | 80 | eax = hpet_readl(HPET_COUNTER); |
81 | eax -= hpet_last; /* hpet delta */ | 81 | eax -= hpet_last; /* hpet delta */ |
82 | 82 | eax = min(hpet_tick, eax); | |
83 | /* | 83 | /* |
84 | * Time offset = (hpet delta) * ( usecs per HPET clock ) | 84 | * Time offset = (hpet delta) * ( usecs per HPET clock ) |
85 | * = (hpet delta) * ( usecs per tick / HPET clocks per tick) | 85 | * = (hpet delta) * ( usecs per tick / HPET clocks per tick) |
@@ -105,9 +105,12 @@ static void mark_offset_hpet(void) | |||
105 | last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; | 105 | last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; |
106 | rdtsc(last_tsc_low, last_tsc_high); | 106 | rdtsc(last_tsc_low, last_tsc_high); |
107 | 107 | ||
108 | offset = hpet_readl(HPET_T0_CMP) - hpet_tick; | 108 | if (hpet_use_timer) |
109 | if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { | 109 | offset = hpet_readl(HPET_T0_CMP) - hpet_tick; |
110 | int lost_ticks = (offset - hpet_last) / hpet_tick; | 110 | else |
111 | offset = hpet_readl(HPET_COUNTER); | ||
112 | if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0))) { | ||
113 | int lost_ticks = ((offset - hpet_last) / hpet_tick) - 1; | ||
111 | jiffies_64 += lost_ticks; | 114 | jiffies_64 += lost_ticks; |
112 | } | 115 | } |
113 | hpet_last = offset; | 116 | hpet_last = offset; |
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index a685994e5c8e..7926d967be00 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -477,7 +477,7 @@ static int __init init_tsc(char* override) | |||
477 | if (cpu_has_tsc) { | 477 | if (cpu_has_tsc) { |
478 | unsigned long tsc_quotient; | 478 | unsigned long tsc_quotient; |
479 | #ifdef CONFIG_HPET_TIMER | 479 | #ifdef CONFIG_HPET_TIMER |
480 | if (is_hpet_enabled()){ | 480 | if (is_hpet_enabled() && hpet_use_timer) { |
481 | unsigned long result, remain; | 481 | unsigned long result, remain; |
482 | printk("Using TSC for gettimeofday\n"); | 482 | printk("Using TSC for gettimeofday\n"); |
483 | tsc_quotient = calibrate_tsc_hpet(NULL); | 483 | tsc_quotient = calibrate_tsc_hpet(NULL); |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 6c0e383915b6..00c63419c06f 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -451,6 +451,7 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) | |||
451 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) | 451 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) |
452 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | 452 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) |
453 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) | 453 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) |
454 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) | ||
454 | 455 | ||
455 | fastcall void do_general_protection(struct pt_regs * regs, long error_code) | 456 | fastcall void do_general_protection(struct pt_regs * regs, long error_code) |
456 | { | 457 | { |
@@ -642,16 +643,15 @@ void unset_nmi_callback(void) | |||
642 | } | 643 | } |
643 | 644 | ||
644 | #ifdef CONFIG_KPROBES | 645 | #ifdef CONFIG_KPROBES |
645 | fastcall int do_int3(struct pt_regs *regs, long error_code) | 646 | fastcall void do_int3(struct pt_regs *regs, long error_code) |
646 | { | 647 | { |
647 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | 648 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) |
648 | == NOTIFY_STOP) | 649 | == NOTIFY_STOP) |
649 | return 1; | 650 | return; |
650 | /* This is an interrupt gate, because kprobes wants interrupts | 651 | /* This is an interrupt gate, because kprobes wants interrupts |
651 | disabled. Normal trap handlers don't. */ | 652 | disabled. Normal trap handlers don't. */ |
652 | restore_interrupts(regs); | 653 | restore_interrupts(regs); |
653 | do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); | 654 | do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); |
654 | return 0; | ||
655 | } | 655 | } |
656 | #endif | 656 | #endif |
657 | 657 | ||
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 2f3d52dacff7..ec0f68ce6886 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c | |||
@@ -222,7 +222,7 @@ asmlinkage int sys_vm86(struct pt_regs regs) | |||
222 | goto out; | 222 | goto out; |
223 | case VM86_PLUS_INSTALL_CHECK: | 223 | case VM86_PLUS_INSTALL_CHECK: |
224 | /* NOTE: on old vm86 stuff this will return the error | 224 | /* NOTE: on old vm86 stuff this will return the error |
225 | from verify_area(), because the subfunction is | 225 | from access_ok(), because the subfunction is |
226 | interpreted as (invalid) address to vm86_struct. | 226 | interpreted as (invalid) address to vm86_struct. |
227 | So the installation check works. | 227 | So the installation check works. |
228 | */ | 228 | */ |
@@ -294,8 +294,8 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
294 | */ | 294 | */ |
295 | info->regs32->eax = 0; | 295 | info->regs32->eax = 0; |
296 | tsk->thread.saved_esp0 = tsk->thread.esp0; | 296 | tsk->thread.saved_esp0 = tsk->thread.esp0; |
297 | asm volatile("movl %%fs,%0":"=m" (tsk->thread.saved_fs)); | 297 | asm volatile("mov %%fs,%0":"=m" (tsk->thread.saved_fs)); |
298 | asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs)); | 298 | asm volatile("mov %%gs,%0":"=m" (tsk->thread.saved_gs)); |
299 | 299 | ||
300 | tss = &per_cpu(init_tss, get_cpu()); | 300 | tss = &per_cpu(init_tss, get_cpu()); |
301 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; | 301 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; |
@@ -717,12 +717,12 @@ static irqreturn_t irq_handler(int intno, void *dev_id, struct pt_regs * regs) | |||
717 | irqbits |= irq_bit; | 717 | irqbits |= irq_bit; |
718 | if (vm86_irqs[intno].sig) | 718 | if (vm86_irqs[intno].sig) |
719 | send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1); | 719 | send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1); |
720 | spin_unlock_irqrestore(&irqbits_lock, flags); | ||
721 | /* | 720 | /* |
722 | * IRQ will be re-enabled when user asks for the irq (whether | 721 | * IRQ will be re-enabled when user asks for the irq (whether |
723 | * polling or as a result of the signal) | 722 | * polling or as a result of the signal) |
724 | */ | 723 | */ |
725 | disable_irq(intno); | 724 | disable_irq_nosync(intno); |
725 | spin_unlock_irqrestore(&irqbits_lock, flags); | ||
726 | return IRQ_HANDLED; | 726 | return IRQ_HANDLED; |
727 | 727 | ||
728 | out: | 728 | out: |
@@ -754,17 +754,20 @@ static inline int get_and_reset_irq(int irqnumber) | |||
754 | { | 754 | { |
755 | int bit; | 755 | int bit; |
756 | unsigned long flags; | 756 | unsigned long flags; |
757 | int ret = 0; | ||
757 | 758 | ||
758 | if (invalid_vm86_irq(irqnumber)) return 0; | 759 | if (invalid_vm86_irq(irqnumber)) return 0; |
759 | if (vm86_irqs[irqnumber].tsk != current) return 0; | 760 | if (vm86_irqs[irqnumber].tsk != current) return 0; |
760 | spin_lock_irqsave(&irqbits_lock, flags); | 761 | spin_lock_irqsave(&irqbits_lock, flags); |
761 | bit = irqbits & (1 << irqnumber); | 762 | bit = irqbits & (1 << irqnumber); |
762 | irqbits &= ~bit; | 763 | irqbits &= ~bit; |
764 | if (bit) { | ||
765 | enable_irq(irqnumber); | ||
766 | ret = 1; | ||
767 | } | ||
768 | |||
763 | spin_unlock_irqrestore(&irqbits_lock, flags); | 769 | spin_unlock_irqrestore(&irqbits_lock, flags); |
764 | if (!bit) | 770 | return ret; |
765 | return 0; | ||
766 | enable_irq(irqnumber); | ||
767 | return 1; | ||
768 | } | 771 | } |
769 | 772 | ||
770 | 773 | ||
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c index b2e462abf337..c58d0c14f274 100644 --- a/arch/i386/oprofile/nmi_timer_int.c +++ b/arch/i386/oprofile/nmi_timer_int.c | |||
@@ -36,7 +36,7 @@ static void timer_stop(void) | |||
36 | { | 36 | { |
37 | enable_timer_nmi_watchdog(); | 37 | enable_timer_nmi_watchdog(); |
38 | unset_nmi_callback(); | 38 | unset_nmi_callback(); |
39 | synchronize_kernel(); | 39 | synchronize_sched(); /* Allow already-started NMIs to complete. */ |
40 | } | 40 | } |
41 | 41 | ||
42 | 42 | ||
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index e07589d04f64..d6598da4b67b 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -495,6 +495,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
495 | case PCI_DEVICE_ID_INTEL_ICH6_1: | 495 | case PCI_DEVICE_ID_INTEL_ICH6_1: |
496 | case PCI_DEVICE_ID_INTEL_ICH7_0: | 496 | case PCI_DEVICE_ID_INTEL_ICH7_0: |
497 | case PCI_DEVICE_ID_INTEL_ICH7_1: | 497 | case PCI_DEVICE_ID_INTEL_ICH7_1: |
498 | case PCI_DEVICE_ID_INTEL_ICH7_30: | ||
499 | case PCI_DEVICE_ID_INTEL_ICH7_31: | ||
498 | case PCI_DEVICE_ID_INTEL_ESB2_0: | 500 | case PCI_DEVICE_ID_INTEL_ESB2_0: |
499 | r->name = "PIIX/ICH"; | 501 | r->name = "PIIX/ICH"; |
500 | r->get = pirq_piix_get; | 502 | r->get = pirq_piix_get; |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 4517d4ab5ef1..9353adc18956 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1411,7 +1411,7 @@ sys_call_table: | |||
1411 | data8 sys_msgrcv | 1411 | data8 sys_msgrcv |
1412 | data8 sys_msgctl | 1412 | data8 sys_msgctl |
1413 | data8 sys_shmget | 1413 | data8 sys_shmget |
1414 | data8 ia64_shmat | 1414 | data8 sys_shmat |
1415 | data8 sys_shmdt // 1115 | 1415 | data8 sys_shmdt // 1115 |
1416 | data8 sys_shmctl | 1416 | data8 sys_shmctl |
1417 | data8 sys_syslog | 1417 | data8 sys_syslog |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 55789fcd7210..9e730c7bf0cd 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/user.h> | 17 | #include <linux/user.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/audit.h> | 19 | #include <linux/audit.h> |
20 | #include <linux/signal.h> | ||
20 | 21 | ||
21 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
22 | #include <asm/processor.h> | 23 | #include <asm/processor.h> |
@@ -704,12 +705,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, | |||
704 | break; | 705 | break; |
705 | } | 706 | } |
706 | 707 | ||
708 | /* | ||
709 | * Note: at the time of this call, the target task is blocked | ||
710 | * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL | ||
711 | * (aka, "pLvSys") we redirect execution from | ||
712 | * .work_pending_syscall_end to .work_processed_kernel. | ||
713 | */ | ||
707 | unw_get_pr(&prev_info, &pr); | 714 | unw_get_pr(&prev_info, &pr); |
708 | pr &= ~(1UL << PRED_SYSCALL); | 715 | pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL)); |
709 | pr |= (1UL << PRED_NON_SYSCALL); | 716 | pr |= (1UL << PRED_NON_SYSCALL); |
710 | unw_set_pr(&prev_info, pr); | 717 | unw_set_pr(&prev_info, pr); |
711 | 718 | ||
712 | pt->cr_ifs = (1UL << 63) | cfm; | 719 | pt->cr_ifs = (1UL << 63) | cfm; |
720 | /* | ||
721 | * Clear the memory that is NOT written on syscall-entry to | ||
722 | * ensure we do not leak kernel-state to user when execution | ||
723 | * resumes. | ||
724 | */ | ||
725 | pt->r2 = 0; | ||
726 | pt->r3 = 0; | ||
727 | pt->r14 = 0; | ||
728 | memset(&pt->r16, 0, 16*8); /* clear r16-r31 */ | ||
729 | memset(&pt->f6, 0, 6*16); /* clear f6-f11 */ | ||
730 | pt->b7 = 0; | ||
731 | pt->ar_ccv = 0; | ||
732 | pt->ar_csd = 0; | ||
733 | pt->ar_ssd = 0; | ||
713 | } | 734 | } |
714 | 735 | ||
715 | static int | 736 | static int |
@@ -1481,7 +1502,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) | |||
1481 | case PTRACE_CONT: | 1502 | case PTRACE_CONT: |
1482 | /* restart after signal. */ | 1503 | /* restart after signal. */ |
1483 | ret = -EIO; | 1504 | ret = -EIO; |
1484 | if (data > _NSIG) | 1505 | if (!valid_signal(data)) |
1485 | goto out_tsk; | 1506 | goto out_tsk; |
1486 | if (request == PTRACE_SYSCALL) | 1507 | if (request == PTRACE_SYSCALL) |
1487 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 1508 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -1520,7 +1541,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) | |||
1520 | /* let child execute for one instruction */ | 1541 | /* let child execute for one instruction */ |
1521 | case PTRACE_SINGLEBLOCK: | 1542 | case PTRACE_SINGLEBLOCK: |
1522 | ret = -EIO; | 1543 | ret = -EIO; |
1523 | if (data > _NSIG) | 1544 | if (!valid_signal(data)) |
1524 | goto out_tsk; | 1545 | goto out_tsk; |
1525 | 1546 | ||
1526 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 1547 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index 3ac216e1c8bb..a8cf6d8a509c 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c | |||
@@ -93,20 +93,6 @@ sys_getpagesize (void) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | asmlinkage unsigned long | 95 | asmlinkage unsigned long |
96 | ia64_shmat (int shmid, void __user *shmaddr, int shmflg) | ||
97 | { | ||
98 | unsigned long raddr; | ||
99 | int retval; | ||
100 | |||
101 | retval = do_shmat(shmid, shmaddr, shmflg, &raddr); | ||
102 | if (retval < 0) | ||
103 | return retval; | ||
104 | |||
105 | force_successful_syscall_return(); | ||
106 | return raddr; | ||
107 | } | ||
108 | |||
109 | asmlinkage unsigned long | ||
110 | ia64_brk (unsigned long brk) | 96 | ia64_brk (unsigned long brk) |
111 | { | 97 | { |
112 | unsigned long rlim, retval, newbrk, oldbrk; | 98 | unsigned long rlim, retval, newbrk, oldbrk; |
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index 8b40f362dd6f..124f7c1b775e 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/user.h> | 25 | #include <linux/user.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/signal.h> | ||
27 | 28 | ||
28 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
@@ -665,7 +666,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data) | |||
665 | case PTRACE_SYSCALL: | 666 | case PTRACE_SYSCALL: |
666 | case PTRACE_CONT: | 667 | case PTRACE_CONT: |
667 | ret = -EIO; | 668 | ret = -EIO; |
668 | if ((unsigned long) data > _NSIG) | 669 | if (!valid_signal(data)) |
669 | break; | 670 | break; |
670 | if (request == PTRACE_SYSCALL) | 671 | if (request == PTRACE_SYSCALL) |
671 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 672 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -700,7 +701,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data) | |||
700 | unsigned long pc, insn; | 701 | unsigned long pc, insn; |
701 | 702 | ||
702 | ret = -EIO; | 703 | ret = -EIO; |
703 | if ((unsigned long) data > _NSIG) | 704 | if (!valid_signal(data)) |
704 | break; | 705 | break; |
705 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 706 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
706 | if ((child->ptrace & PT_DTRACE) == 0) { | 707 | if ((child->ptrace & PT_DTRACE) == 0) { |
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index 0beb53333ba3..f4e1e5eb8e12 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/ptrace.h> | 19 | #include <linux/ptrace.h> |
20 | #include <linux/user.h> | 20 | #include <linux/user.h> |
21 | #include <linux/config.h> | 21 | #include <linux/config.h> |
22 | #include <linux/signal.h> | ||
22 | 23 | ||
23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
24 | #include <asm/page.h> | 25 | #include <asm/page.h> |
@@ -251,7 +252,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
251 | long tmp; | 252 | long tmp; |
252 | 253 | ||
253 | ret = -EIO; | 254 | ret = -EIO; |
254 | if ((unsigned long) data > _NSIG) | 255 | if (!valid_signal(data)) |
255 | break; | 256 | break; |
256 | if (request == PTRACE_SYSCALL) { | 257 | if (request == PTRACE_SYSCALL) { |
257 | child->thread.work.syscall_trace = ~0; | 258 | child->thread.work.syscall_trace = ~0; |
@@ -292,7 +293,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
292 | long tmp; | 293 | long tmp; |
293 | 294 | ||
294 | ret = -EIO; | 295 | ret = -EIO; |
295 | if ((unsigned long) data > _NSIG) | 296 | if (!valid_signal(data)) |
296 | break; | 297 | break; |
297 | child->thread.work.syscall_trace = 0; | 298 | child->thread.work.syscall_trace = 0; |
298 | tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); | 299 | tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); |
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c index 15cf79080b15..9724e1cd82e5 100644 --- a/arch/m68knommu/kernel/ptrace.c +++ b/arch/m68knommu/kernel/ptrace.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/ptrace.h> | 19 | #include <linux/ptrace.h> |
20 | #include <linux/user.h> | 20 | #include <linux/user.h> |
21 | #include <linux/config.h> | 21 | #include <linux/config.h> |
22 | #include <linux/signal.h> | ||
22 | 23 | ||
23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
24 | #include <asm/page.h> | 25 | #include <asm/page.h> |
@@ -240,7 +241,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
240 | long tmp; | 241 | long tmp; |
241 | 242 | ||
242 | ret = -EIO; | 243 | ret = -EIO; |
243 | if ((unsigned long) data > _NSIG) | 244 | if (!valid_signal(data)) |
244 | break; | 245 | break; |
245 | if (request == PTRACE_SYSCALL) | 246 | if (request == PTRACE_SYSCALL) |
246 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 247 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -278,7 +279,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
278 | long tmp; | 279 | long tmp; |
279 | 280 | ||
280 | ret = -EIO; | 281 | ret = -EIO; |
281 | if ((unsigned long) data > _NSIG) | 282 | if (!valid_signal(data)) |
282 | break; | 283 | break; |
283 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 284 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
284 | tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); | 285 | tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 92f2c39afe27..a2f899c2f4d4 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/smp_lock.h> | 26 | #include <linux/smp_lock.h> |
27 | #include <linux/user.h> | 27 | #include <linux/user.h> |
28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
29 | #include <linux/signal.h> | ||
29 | 30 | ||
30 | #include <asm/cpu.h> | 31 | #include <asm/cpu.h> |
31 | #include <asm/fpu.h> | 32 | #include <asm/fpu.h> |
@@ -257,7 +258,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
257 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 258 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
258 | case PTRACE_CONT: { /* restart after signal. */ | 259 | case PTRACE_CONT: { /* restart after signal. */ |
259 | ret = -EIO; | 260 | ret = -EIO; |
260 | if ((unsigned long) data > _NSIG) | 261 | if (!valid_signal(data)) |
261 | break; | 262 | break; |
262 | if (request == PTRACE_SYSCALL) { | 263 | if (request == PTRACE_SYSCALL) { |
263 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 264 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index 611dee919d50..eee207969c21 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/smp_lock.h> | 24 | #include <linux/smp_lock.h> |
25 | #include <linux/user.h> | 25 | #include <linux/user.h> |
26 | #include <linux/security.h> | 26 | #include <linux/security.h> |
27 | #include <linux/signal.h> | ||
27 | 28 | ||
28 | #include <asm/cpu.h> | 29 | #include <asm/cpu.h> |
29 | #include <asm/fpu.h> | 30 | #include <asm/fpu.h> |
@@ -241,7 +242,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
241 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 242 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
242 | case PTRACE_CONT: { /* restart after signal. */ | 243 | case PTRACE_CONT: { /* restart after signal. */ |
243 | ret = -EIO; | 244 | ret = -EIO; |
244 | if ((unsigned int) data > _NSIG) | 245 | if (!valid_signal(data)) |
245 | break; | 246 | break; |
246 | if (request == PTRACE_SYSCALL) { | 247 | if (request == PTRACE_SYSCALL) { |
247 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 248 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 598bfe7426a2..ae2a1312d4ef 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -374,22 +374,6 @@ asmlinkage int sys_ipc (uint call, int first, int second, | |||
374 | } | 374 | } |
375 | 375 | ||
376 | /* | 376 | /* |
377 | * Native ABI that is O32 or N64 version | ||
378 | */ | ||
379 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, | ||
380 | int shmflg, unsigned long *addr) | ||
381 | { | ||
382 | unsigned long raddr; | ||
383 | int err; | ||
384 | |||
385 | err = do_shmat(shmid, shmaddr, shmflg, &raddr); | ||
386 | if (err) | ||
387 | return err; | ||
388 | |||
389 | return put_user(raddr, addr); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * No implemented yet ... | 377 | * No implemented yet ... |
394 | */ | 378 | */ |
395 | asmlinkage int sys_cachectl(char *addr, int nbytes, int op) | 379 | asmlinkage int sys_cachectl(char *addr, int nbytes, int op) |
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 2937a9236384..c07db9dff7cd 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/personality.h> | 17 | #include <linux/personality.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/compat.h> | 19 | #include <linux/compat.h> |
20 | #include <linux/signal.h> | ||
20 | 21 | ||
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
22 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
@@ -285,7 +286,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data) | |||
285 | ret = -EIO; | 286 | ret = -EIO; |
286 | DBG("sys_ptrace(%s)\n", | 287 | DBG("sys_ptrace(%s)\n", |
287 | request == PTRACE_SYSCALL ? "SYSCALL" : "CONT"); | 288 | request == PTRACE_SYSCALL ? "SYSCALL" : "CONT"); |
288 | if ((unsigned long) data > _NSIG) | 289 | if (!valid_signal(data)) |
289 | goto out_tsk; | 290 | goto out_tsk; |
290 | child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP); | 291 | child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP); |
291 | if (request == PTRACE_SYSCALL) { | 292 | if (request == PTRACE_SYSCALL) { |
@@ -311,7 +312,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data) | |||
311 | case PTRACE_SINGLEBLOCK: | 312 | case PTRACE_SINGLEBLOCK: |
312 | DBG("sys_ptrace(SINGLEBLOCK)\n"); | 313 | DBG("sys_ptrace(SINGLEBLOCK)\n"); |
313 | ret = -EIO; | 314 | ret = -EIO; |
314 | if ((unsigned long) data > _NSIG) | 315 | if (!valid_signal(data)) |
315 | goto out_tsk; | 316 | goto out_tsk; |
316 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 317 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
317 | child->ptrace &= ~PT_SINGLESTEP; | 318 | child->ptrace &= ~PT_SINGLESTEP; |
@@ -328,7 +329,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data) | |||
328 | case PTRACE_SINGLESTEP: | 329 | case PTRACE_SINGLESTEP: |
329 | DBG("sys_ptrace(SINGLESTEP)\n"); | 330 | DBG("sys_ptrace(SINGLESTEP)\n"); |
330 | ret = -EIO; | 331 | ret = -EIO; |
331 | if ((unsigned long) data > _NSIG) | 332 | if (!valid_signal(data)) |
332 | goto out_tsk; | 333 | goto out_tsk; |
333 | 334 | ||
334 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 335 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 7958cd8c8bf8..d15a1d53e101 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -161,17 +161,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | |||
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
164 | long sys_shmat_wrapper(int shmid, char __user *shmaddr, int shmflag) | ||
165 | { | ||
166 | unsigned long raddr; | ||
167 | int r; | ||
168 | |||
169 | r = do_shmat(shmid, shmaddr, shmflag, &raddr); | ||
170 | if (r < 0) | ||
171 | return r; | ||
172 | return raddr; | ||
173 | } | ||
174 | |||
175 | /* Fucking broken ABI */ | 164 | /* Fucking broken ABI */ |
176 | 165 | ||
177 | #ifdef CONFIG_64BIT | 166 | #ifdef CONFIG_64BIT |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 779b537100ec..dcfa4d3d0e7d 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -297,7 +297,7 @@ | |||
297 | ENTRY_DIFF(msgrcv) | 297 | ENTRY_DIFF(msgrcv) |
298 | ENTRY_SAME(msgget) /* 190 */ | 298 | ENTRY_SAME(msgget) /* 190 */ |
299 | ENTRY_SAME(msgctl) | 299 | ENTRY_SAME(msgctl) |
300 | ENTRY_SAME(shmat_wrapper) | 300 | ENTRY_SAME(shmat) |
301 | ENTRY_SAME(shmdt) | 301 | ENTRY_SAME(shmdt) |
302 | ENTRY_SAME(shmget) | 302 | ENTRY_SAME(shmget) |
303 | ENTRY_SAME(shmctl) /* 195 */ | 303 | ENTRY_SAME(shmctl) /* 195 */ |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 74aa1e92a395..c3d941345e3d 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -53,6 +53,7 @@ choice | |||
53 | 53 | ||
54 | config 6xx | 54 | config 6xx |
55 | bool "6xx/7xx/74xx/52xx/82xx/83xx" | 55 | bool "6xx/7xx/74xx/52xx/82xx/83xx" |
56 | select PPC_FPU | ||
56 | help | 57 | help |
57 | There are four types of PowerPC chips supported. The more common | 58 | There are four types of PowerPC chips supported. The more common |
58 | types (601, 603, 604, 740, 750, 7400), the Motorola embedded | 59 | types (601, 603, 604, 740, 750, 7400), the Motorola embedded |
@@ -86,6 +87,9 @@ config E500 | |||
86 | 87 | ||
87 | endchoice | 88 | endchoice |
88 | 89 | ||
90 | config PPC_FPU | ||
91 | bool | ||
92 | |||
89 | config BOOKE | 93 | config BOOKE |
90 | bool | 94 | bool |
91 | depends on E500 | 95 | depends on E500 |
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 73cbdda5b597..0432a25b4735 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile | |||
@@ -53,6 +53,7 @@ head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o | |||
53 | 53 | ||
54 | head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o | 54 | head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o |
55 | head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o | 55 | head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o |
56 | head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o | ||
56 | 57 | ||
57 | core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ | 58 | core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ |
58 | arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ | 59 | arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ |
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index 774de8e23871..f850fb0fb511 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile | |||
@@ -20,8 +20,9 @@ quiet_cmd_uimage = UIMAGE $@ | |||
20 | 20 | ||
21 | targets += uImage | 21 | targets += uImage |
22 | $(obj)/uImage: $(obj)/vmlinux.gz | 22 | $(obj)/uImage: $(obj)/vmlinux.gz |
23 | $(Q)rm -f $@ | ||
23 | $(call if_changed,uimage) | 24 | $(call if_changed,uimage) |
24 | @echo ' Image $@ is ready' | 25 | @echo ' Image: $@' $(if $(wildcard $@),'is ready','not made') |
25 | 26 | ||
26 | # Files generated that shall be removed upon make clean | 27 | # Files generated that shall be removed upon make clean |
27 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage | 28 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage |
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 86bc878cb3ee..b284451802c9 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
@@ -9,6 +9,7 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o | |||
9 | extra-$(CONFIG_8xx) := head_8xx.o | 9 | extra-$(CONFIG_8xx) := head_8xx.o |
10 | extra-$(CONFIG_6xx) += idle_6xx.o | 10 | extra-$(CONFIG_6xx) += idle_6xx.o |
11 | extra-$(CONFIG_POWER4) += idle_power4.o | 11 | extra-$(CONFIG_POWER4) += idle_power4.o |
12 | extra-$(CONFIG_PPC_FPU) += fpu.o | ||
12 | extra-y += vmlinux.lds | 13 | extra-y += vmlinux.lds |
13 | 14 | ||
14 | 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 \ |
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c index 79c929475037..ff81da9598d8 100644 --- a/arch/ppc/kernel/align.c +++ b/arch/ppc/kernel/align.c | |||
@@ -290,6 +290,10 @@ fix_alignment(struct pt_regs *regs) | |||
290 | /* lwm, stmw */ | 290 | /* lwm, stmw */ |
291 | nb = (32 - reg) * 4; | 291 | nb = (32 - reg) * 4; |
292 | } | 292 | } |
293 | |||
294 | if (!access_ok((flags & ST? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0)) | ||
295 | return -EFAULT; /* bad address */ | ||
296 | |||
293 | rptr = (unsigned char *) ®s->gpr[reg]; | 297 | rptr = (unsigned char *) ®s->gpr[reg]; |
294 | if (flags & LD) { | 298 | if (flags & LD) { |
295 | for (i = 0; i < nb; ++i) | 299 | for (i = 0; i < nb; ++i) |
@@ -368,16 +372,24 @@ fix_alignment(struct pt_regs *regs) | |||
368 | 372 | ||
369 | /* Single-precision FP load and store require conversions... */ | 373 | /* Single-precision FP load and store require conversions... */ |
370 | case LD+F+S: | 374 | case LD+F+S: |
375 | #ifdef CONFIG_PPC_FPU | ||
371 | preempt_disable(); | 376 | preempt_disable(); |
372 | enable_kernel_fp(); | 377 | enable_kernel_fp(); |
373 | cvt_fd(&data.f, &data.d, ¤t->thread.fpscr); | 378 | cvt_fd(&data.f, &data.d, ¤t->thread.fpscr); |
374 | preempt_enable(); | 379 | preempt_enable(); |
380 | #else | ||
381 | return 0; | ||
382 | #endif | ||
375 | break; | 383 | break; |
376 | case ST+F+S: | 384 | case ST+F+S: |
385 | #ifdef CONFIG_PPC_FPU | ||
377 | preempt_disable(); | 386 | preempt_disable(); |
378 | enable_kernel_fp(); | 387 | enable_kernel_fp(); |
379 | cvt_df(&data.d, &data.f, ¤t->thread.fpscr); | 388 | cvt_df(&data.d, &data.f, ¤t->thread.fpscr); |
380 | preempt_enable(); | 389 | preempt_enable(); |
390 | #else | ||
391 | return 0; | ||
392 | #endif | ||
381 | break; | 393 | break; |
382 | } | 394 | } |
383 | 395 | ||
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S index 74f781b486a3..468721d9ebd2 100644 --- a/arch/ppc/kernel/cpu_setup_6xx.S +++ b/arch/ppc/kernel/cpu_setup_6xx.S | |||
@@ -30,12 +30,14 @@ _GLOBAL(__setup_cpu_604) | |||
30 | blr | 30 | blr |
31 | _GLOBAL(__setup_cpu_750) | 31 | _GLOBAL(__setup_cpu_750) |
32 | mflr r4 | 32 | mflr r4 |
33 | bl __init_fpu_registers | ||
33 | bl setup_common_caches | 34 | bl setup_common_caches |
34 | bl setup_750_7400_hid0 | 35 | bl setup_750_7400_hid0 |
35 | mtlr r4 | 36 | mtlr r4 |
36 | blr | 37 | blr |
37 | _GLOBAL(__setup_cpu_750cx) | 38 | _GLOBAL(__setup_cpu_750cx) |
38 | mflr r4 | 39 | mflr r4 |
40 | bl __init_fpu_registers | ||
39 | bl setup_common_caches | 41 | bl setup_common_caches |
40 | bl setup_750_7400_hid0 | 42 | bl setup_750_7400_hid0 |
41 | bl setup_750cx | 43 | bl setup_750cx |
@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx) | |||
43 | blr | 45 | blr |
44 | _GLOBAL(__setup_cpu_750fx) | 46 | _GLOBAL(__setup_cpu_750fx) |
45 | mflr r4 | 47 | mflr r4 |
48 | bl __init_fpu_registers | ||
46 | bl setup_common_caches | 49 | bl setup_common_caches |
47 | bl setup_750_7400_hid0 | 50 | bl setup_750_7400_hid0 |
48 | bl setup_750fx | 51 | bl setup_750fx |
@@ -50,6 +53,7 @@ _GLOBAL(__setup_cpu_750fx) | |||
50 | blr | 53 | blr |
51 | _GLOBAL(__setup_cpu_7400) | 54 | _GLOBAL(__setup_cpu_7400) |
52 | mflr r4 | 55 | mflr r4 |
56 | bl __init_fpu_registers | ||
53 | bl setup_7400_workarounds | 57 | bl setup_7400_workarounds |
54 | bl setup_common_caches | 58 | bl setup_common_caches |
55 | bl setup_750_7400_hid0 | 59 | bl setup_750_7400_hid0 |
@@ -57,6 +61,7 @@ _GLOBAL(__setup_cpu_7400) | |||
57 | blr | 61 | blr |
58 | _GLOBAL(__setup_cpu_7410) | 62 | _GLOBAL(__setup_cpu_7410) |
59 | mflr r4 | 63 | mflr r4 |
64 | bl __init_fpu_registers | ||
60 | bl setup_7410_workarounds | 65 | bl setup_7410_workarounds |
61 | bl setup_common_caches | 66 | bl setup_common_caches |
62 | bl setup_750_7400_hid0 | 67 | bl setup_750_7400_hid0 |
@@ -80,7 +85,7 @@ setup_common_caches: | |||
80 | bne 1f /* don't invalidate the D-cache */ | 85 | bne 1f /* don't invalidate the D-cache */ |
81 | ori r8,r8,HID0_DCI /* unless it wasn't enabled */ | 86 | ori r8,r8,HID0_DCI /* unless it wasn't enabled */ |
82 | 1: sync | 87 | 1: sync |
83 | mtspr SPRN_HID0,r8 /* enable and invalidate caches */ | 88 | mtspr SPRN_HID0,r8 /* enable and invalidate caches */ |
84 | sync | 89 | sync |
85 | mtspr SPRN_HID0,r11 /* enable caches */ | 90 | mtspr SPRN_HID0,r11 /* enable caches */ |
86 | sync | 91 | sync |
@@ -152,9 +157,13 @@ setup_7410_workarounds: | |||
152 | setup_750_7400_hid0: | 157 | setup_750_7400_hid0: |
153 | mfspr r11,SPRN_HID0 | 158 | mfspr r11,SPRN_HID0 |
154 | ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC | 159 | ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC |
160 | oris r11,r11,HID0_DPM@h | ||
155 | BEGIN_FTR_SECTION | 161 | BEGIN_FTR_SECTION |
156 | oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ | 162 | xori r11,r11,HID0_BTIC |
157 | END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) | 163 | END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) |
164 | BEGIN_FTR_SECTION | ||
165 | xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */ | ||
166 | END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM) | ||
158 | li r3,HID0_SPD | 167 | li r3,HID0_SPD |
159 | andc r11,r11,r3 /* clear SPD: enable speculative */ | 168 | andc r11,r11,r3 /* clear SPD: enable speculative */ |
160 | li r3,0 | 169 | li r3,0 |
@@ -218,13 +227,15 @@ setup_745x_specifics: | |||
218 | 227 | ||
219 | /* All of the bits we have to set..... | 228 | /* All of the bits we have to set..... |
220 | */ | 229 | */ |
221 | ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_LRSTK | HID0_BTIC | 230 | ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE |
231 | ori r11,r11,HID0_LRSTK | HID0_BTIC | ||
232 | oris r11,r11,HID0_DPM@h | ||
222 | BEGIN_FTR_SECTION | 233 | BEGIN_FTR_SECTION |
223 | xori r11,r11,HID0_BTIC | 234 | xori r11,r11,HID0_BTIC |
224 | END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) | 235 | END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) |
225 | BEGIN_FTR_SECTION | 236 | BEGIN_FTR_SECTION |
226 | oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ | 237 | xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */ |
227 | END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) | 238 | END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM) |
228 | 239 | ||
229 | /* All of the bits we have to clear.... | 240 | /* All of the bits we have to clear.... |
230 | */ | 241 | */ |
@@ -248,6 +259,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) | |||
248 | isync | 259 | isync |
249 | blr | 260 | blr |
250 | 261 | ||
262 | /* | ||
263 | * Initialize the FPU registers. This is needed to work around an errata | ||
264 | * in some 750 cpus where using a not yet initialized FPU register after | ||
265 | * power on reset may hang the CPU | ||
266 | */ | ||
267 | _GLOBAL(__init_fpu_registers) | ||
268 | mfmsr r10 | ||
269 | ori r11,r10,MSR_FP | ||
270 | mtmsr r11 | ||
271 | isync | ||
272 | addis r9,r3,empty_zero_page@ha | ||
273 | addi r9,r9,empty_zero_page@l | ||
274 | REST_32FPRS(0,r9) | ||
275 | sync | ||
276 | mtmsr r10 | ||
277 | isync | ||
278 | blr | ||
279 | |||
280 | |||
251 | /* Definitions for the table use to save CPU states */ | 281 | /* Definitions for the table use to save CPU states */ |
252 | #define CS_HID0 0 | 282 | #define CS_HID0 0 |
253 | #define CS_HID1 4 | 283 | #define CS_HID1 4 |
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 035217d6c0f1..5f075dbc4ee7 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
@@ -563,6 +563,65 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
563 | addi r1,r1,INT_FRAME_SIZE | 563 | addi r1,r1,INT_FRAME_SIZE |
564 | blr | 564 | blr |
565 | 565 | ||
566 | .globl fast_exception_return | ||
567 | fast_exception_return: | ||
568 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) | ||
569 | andi. r10,r9,MSR_RI /* check for recoverable interrupt */ | ||
570 | beq 1f /* if not, we've got problems */ | ||
571 | #endif | ||
572 | |||
573 | 2: REST_4GPRS(3, r11) | ||
574 | lwz r10,_CCR(r11) | ||
575 | REST_GPR(1, r11) | ||
576 | mtcr r10 | ||
577 | lwz r10,_LINK(r11) | ||
578 | mtlr r10 | ||
579 | REST_GPR(10, r11) | ||
580 | mtspr SPRN_SRR1,r9 | ||
581 | mtspr SPRN_SRR0,r12 | ||
582 | REST_GPR(9, r11) | ||
583 | REST_GPR(12, r11) | ||
584 | lwz r11,GPR11(r11) | ||
585 | SYNC | ||
586 | RFI | ||
587 | |||
588 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) | ||
589 | /* check if the exception happened in a restartable section */ | ||
590 | 1: lis r3,exc_exit_restart_end@ha | ||
591 | addi r3,r3,exc_exit_restart_end@l | ||
592 | cmplw r12,r3 | ||
593 | bge 3f | ||
594 | lis r4,exc_exit_restart@ha | ||
595 | addi r4,r4,exc_exit_restart@l | ||
596 | cmplw r12,r4 | ||
597 | blt 3f | ||
598 | lis r3,fee_restarts@ha | ||
599 | tophys(r3,r3) | ||
600 | lwz r5,fee_restarts@l(r3) | ||
601 | addi r5,r5,1 | ||
602 | stw r5,fee_restarts@l(r3) | ||
603 | mr r12,r4 /* restart at exc_exit_restart */ | ||
604 | b 2b | ||
605 | |||
606 | .comm fee_restarts,4 | ||
607 | |||
608 | /* aargh, a nonrecoverable interrupt, panic */ | ||
609 | /* aargh, we don't know which trap this is */ | ||
610 | /* but the 601 doesn't implement the RI bit, so assume it's OK */ | ||
611 | 3: | ||
612 | BEGIN_FTR_SECTION | ||
613 | b 2b | ||
614 | END_FTR_SECTION_IFSET(CPU_FTR_601) | ||
615 | li r10,-1 | ||
616 | stw r10,TRAP(r11) | ||
617 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
618 | lis r10,MSR_KERNEL@h | ||
619 | ori r10,r10,MSR_KERNEL@l | ||
620 | bl transfer_to_handler_full | ||
621 | .long nonrecoverable_exception | ||
622 | .long ret_from_except | ||
623 | #endif | ||
624 | |||
566 | .globl sigreturn_exit | 625 | .globl sigreturn_exit |
567 | sigreturn_exit: | 626 | sigreturn_exit: |
568 | subi r1,r3,STACK_FRAME_OVERHEAD | 627 | subi r1,r3,STACK_FRAME_OVERHEAD |
diff --git a/arch/ppc/kernel/fpu.S b/arch/ppc/kernel/fpu.S new file mode 100644 index 000000000000..6189b26f640f --- /dev/null +++ b/arch/ppc/kernel/fpu.S | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * FPU support code, moved here from head.S so that it can be used | ||
3 | * by chips which use other head-whatever.S files. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <asm/processor.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/mmu.h> | ||
16 | #include <asm/pgtable.h> | ||
17 | #include <asm/cputable.h> | ||
18 | #include <asm/cache.h> | ||
19 | #include <asm/thread_info.h> | ||
20 | #include <asm/ppc_asm.h> | ||
21 | #include <asm/offsets.h> | ||
22 | |||
23 | /* | ||
24 | * This task wants to use the FPU now. | ||
25 | * On UP, disable FP for the task which had the FPU previously, | ||
26 | * and save its floating-point registers in its thread_struct. | ||
27 | * Load up this task's FP registers from its thread_struct, | ||
28 | * enable the FPU for the current task and return to the task. | ||
29 | */ | ||
30 | .globl load_up_fpu | ||
31 | load_up_fpu: | ||
32 | mfmsr r5 | ||
33 | ori r5,r5,MSR_FP | ||
34 | #ifdef CONFIG_PPC64BRIDGE | ||
35 | clrldi r5,r5,1 /* turn off 64-bit mode */ | ||
36 | #endif /* CONFIG_PPC64BRIDGE */ | ||
37 | SYNC | ||
38 | MTMSRD(r5) /* enable use of fpu now */ | ||
39 | isync | ||
40 | /* | ||
41 | * For SMP, we don't do lazy FPU switching because it just gets too | ||
42 | * horrendously complex, especially when a task switches from one CPU | ||
43 | * to another. Instead we call giveup_fpu in switch_to. | ||
44 | */ | ||
45 | #ifndef CONFIG_SMP | ||
46 | tophys(r6,0) /* get __pa constant */ | ||
47 | addis r3,r6,last_task_used_math@ha | ||
48 | lwz r4,last_task_used_math@l(r3) | ||
49 | cmpwi 0,r4,0 | ||
50 | beq 1f | ||
51 | add r4,r4,r6 | ||
52 | addi r4,r4,THREAD /* want last_task_used_math->thread */ | ||
53 | SAVE_32FPRS(0, r4) | ||
54 | mffs fr0 | ||
55 | stfd fr0,THREAD_FPSCR-4(r4) | ||
56 | lwz r5,PT_REGS(r4) | ||
57 | add r5,r5,r6 | ||
58 | lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
59 | li r10,MSR_FP|MSR_FE0|MSR_FE1 | ||
60 | andc r4,r4,r10 /* disable FP for previous task */ | ||
61 | stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
62 | 1: | ||
63 | #endif /* CONFIG_SMP */ | ||
64 | /* enable use of FP after return */ | ||
65 | mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ | ||
66 | lwz r4,THREAD_FPEXC_MODE(r5) | ||
67 | ori r9,r9,MSR_FP /* enable FP for current */ | ||
68 | or r9,r9,r4 | ||
69 | lfd fr0,THREAD_FPSCR-4(r5) | ||
70 | mtfsf 0xff,fr0 | ||
71 | REST_32FPRS(0, r5) | ||
72 | #ifndef CONFIG_SMP | ||
73 | subi r4,r5,THREAD | ||
74 | sub r4,r4,r6 | ||
75 | stw r4,last_task_used_math@l(r3) | ||
76 | #endif /* CONFIG_SMP */ | ||
77 | /* restore registers and return */ | ||
78 | /* we haven't used ctr or xer or lr */ | ||
79 | b fast_exception_return | ||
80 | |||
81 | /* | ||
82 | * FP unavailable trap from kernel - print a message, but let | ||
83 | * the task use FP in the kernel until it returns to user mode. | ||
84 | */ | ||
85 | .globl KernelFP | ||
86 | KernelFP: | ||
87 | lwz r3,_MSR(r1) | ||
88 | ori r3,r3,MSR_FP | ||
89 | stw r3,_MSR(r1) /* enable use of FP after return */ | ||
90 | lis r3,86f@h | ||
91 | ori r3,r3,86f@l | ||
92 | mr r4,r2 /* current */ | ||
93 | lwz r5,_NIP(r1) | ||
94 | bl printk | ||
95 | b ret_from_except | ||
96 | 86: .string "floating point used in kernel (task=%p, pc=%x)\n" | ||
97 | .align 4,0 | ||
98 | |||
99 | /* | ||
100 | * giveup_fpu(tsk) | ||
101 | * Disable FP for the task given as the argument, | ||
102 | * and save the floating-point registers in its thread_struct. | ||
103 | * Enables the FPU for use in the kernel on return. | ||
104 | */ | ||
105 | .globl giveup_fpu | ||
106 | giveup_fpu: | ||
107 | mfmsr r5 | ||
108 | ori r5,r5,MSR_FP | ||
109 | SYNC_601 | ||
110 | ISYNC_601 | ||
111 | MTMSRD(r5) /* enable use of fpu now */ | ||
112 | SYNC_601 | ||
113 | isync | ||
114 | cmpwi 0,r3,0 | ||
115 | beqlr- /* if no previous owner, done */ | ||
116 | addi r3,r3,THREAD /* want THREAD of task */ | ||
117 | lwz r5,PT_REGS(r3) | ||
118 | cmpwi 0,r5,0 | ||
119 | SAVE_32FPRS(0, r3) | ||
120 | mffs fr0 | ||
121 | stfd fr0,THREAD_FPSCR-4(r3) | ||
122 | beq 1f | ||
123 | lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
124 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | ||
125 | andc r4,r4,r3 /* disable FP for previous task */ | ||
126 | stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
127 | 1: | ||
128 | #ifndef CONFIG_SMP | ||
129 | li r5,0 | ||
130 | lis r4,last_task_used_math@ha | ||
131 | stw r5,last_task_used_math@l(r4) | ||
132 | #endif /* CONFIG_SMP */ | ||
133 | blr | ||
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 1a89a71e0acc..a931d773715f 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S | |||
@@ -775,133 +775,6 @@ InstructionSegment: | |||
775 | EXC_XFER_STD(0x480, UnknownException) | 775 | EXC_XFER_STD(0x480, UnknownException) |
776 | #endif /* CONFIG_PPC64BRIDGE */ | 776 | #endif /* CONFIG_PPC64BRIDGE */ |
777 | 777 | ||
778 | /* | ||
779 | * This task wants to use the FPU now. | ||
780 | * On UP, disable FP for the task which had the FPU previously, | ||
781 | * and save its floating-point registers in its thread_struct. | ||
782 | * Load up this task's FP registers from its thread_struct, | ||
783 | * enable the FPU for the current task and return to the task. | ||
784 | */ | ||
785 | load_up_fpu: | ||
786 | mfmsr r5 | ||
787 | ori r5,r5,MSR_FP | ||
788 | #ifdef CONFIG_PPC64BRIDGE | ||
789 | clrldi r5,r5,1 /* turn off 64-bit mode */ | ||
790 | #endif /* CONFIG_PPC64BRIDGE */ | ||
791 | SYNC | ||
792 | MTMSRD(r5) /* enable use of fpu now */ | ||
793 | isync | ||
794 | /* | ||
795 | * For SMP, we don't do lazy FPU switching because it just gets too | ||
796 | * horrendously complex, especially when a task switches from one CPU | ||
797 | * to another. Instead we call giveup_fpu in switch_to. | ||
798 | */ | ||
799 | #ifndef CONFIG_SMP | ||
800 | tophys(r6,0) /* get __pa constant */ | ||
801 | addis r3,r6,last_task_used_math@ha | ||
802 | lwz r4,last_task_used_math@l(r3) | ||
803 | cmpwi 0,r4,0 | ||
804 | beq 1f | ||
805 | add r4,r4,r6 | ||
806 | addi r4,r4,THREAD /* want last_task_used_math->thread */ | ||
807 | SAVE_32FPRS(0, r4) | ||
808 | mffs fr0 | ||
809 | stfd fr0,THREAD_FPSCR-4(r4) | ||
810 | lwz r5,PT_REGS(r4) | ||
811 | add r5,r5,r6 | ||
812 | lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
813 | li r10,MSR_FP|MSR_FE0|MSR_FE1 | ||
814 | andc r4,r4,r10 /* disable FP for previous task */ | ||
815 | stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
816 | 1: | ||
817 | #endif /* CONFIG_SMP */ | ||
818 | /* enable use of FP after return */ | ||
819 | mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */ | ||
820 | lwz r4,THREAD_FPEXC_MODE(r5) | ||
821 | ori r9,r9,MSR_FP /* enable FP for current */ | ||
822 | or r9,r9,r4 | ||
823 | lfd fr0,THREAD_FPSCR-4(r5) | ||
824 | mtfsf 0xff,fr0 | ||
825 | REST_32FPRS(0, r5) | ||
826 | #ifndef CONFIG_SMP | ||
827 | subi r4,r5,THREAD | ||
828 | sub r4,r4,r6 | ||
829 | stw r4,last_task_used_math@l(r3) | ||
830 | #endif /* CONFIG_SMP */ | ||
831 | /* restore registers and return */ | ||
832 | /* we haven't used ctr or xer or lr */ | ||
833 | /* fall through to fast_exception_return */ | ||
834 | |||
835 | .globl fast_exception_return | ||
836 | fast_exception_return: | ||
837 | andi. r10,r9,MSR_RI /* check for recoverable interrupt */ | ||
838 | beq 1f /* if not, we've got problems */ | ||
839 | 2: REST_4GPRS(3, r11) | ||
840 | lwz r10,_CCR(r11) | ||
841 | REST_GPR(1, r11) | ||
842 | mtcr r10 | ||
843 | lwz r10,_LINK(r11) | ||
844 | mtlr r10 | ||
845 | REST_GPR(10, r11) | ||
846 | mtspr SPRN_SRR1,r9 | ||
847 | mtspr SPRN_SRR0,r12 | ||
848 | REST_GPR(9, r11) | ||
849 | REST_GPR(12, r11) | ||
850 | lwz r11,GPR11(r11) | ||
851 | SYNC | ||
852 | RFI | ||
853 | |||
854 | /* check if the exception happened in a restartable section */ | ||
855 | 1: lis r3,exc_exit_restart_end@ha | ||
856 | addi r3,r3,exc_exit_restart_end@l | ||
857 | cmplw r12,r3 | ||
858 | bge 3f | ||
859 | lis r4,exc_exit_restart@ha | ||
860 | addi r4,r4,exc_exit_restart@l | ||
861 | cmplw r12,r4 | ||
862 | blt 3f | ||
863 | lis r3,fee_restarts@ha | ||
864 | tophys(r3,r3) | ||
865 | lwz r5,fee_restarts@l(r3) | ||
866 | addi r5,r5,1 | ||
867 | stw r5,fee_restarts@l(r3) | ||
868 | mr r12,r4 /* restart at exc_exit_restart */ | ||
869 | b 2b | ||
870 | |||
871 | .comm fee_restarts,4 | ||
872 | |||
873 | /* aargh, a nonrecoverable interrupt, panic */ | ||
874 | /* aargh, we don't know which trap this is */ | ||
875 | /* but the 601 doesn't implement the RI bit, so assume it's OK */ | ||
876 | 3: | ||
877 | BEGIN_FTR_SECTION | ||
878 | b 2b | ||
879 | END_FTR_SECTION_IFSET(CPU_FTR_601) | ||
880 | li r10,-1 | ||
881 | stw r10,TRAP(r11) | ||
882 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
883 | li r10,MSR_KERNEL | ||
884 | bl transfer_to_handler_full | ||
885 | .long nonrecoverable_exception | ||
886 | .long ret_from_except | ||
887 | |||
888 | /* | ||
889 | * FP unavailable trap from kernel - print a message, but let | ||
890 | * the task use FP in the kernel until it returns to user mode. | ||
891 | */ | ||
892 | KernelFP: | ||
893 | lwz r3,_MSR(r1) | ||
894 | ori r3,r3,MSR_FP | ||
895 | stw r3,_MSR(r1) /* enable use of FP after return */ | ||
896 | lis r3,86f@h | ||
897 | ori r3,r3,86f@l | ||
898 | mr r4,r2 /* current */ | ||
899 | lwz r5,_NIP(r1) | ||
900 | bl printk | ||
901 | b ret_from_except | ||
902 | 86: .string "floating point used in kernel (task=%p, pc=%x)\n" | ||
903 | .align 4,0 | ||
904 | |||
905 | #ifdef CONFIG_ALTIVEC | 778 | #ifdef CONFIG_ALTIVEC |
906 | /* Note that the AltiVec support is closely modeled after the FP | 779 | /* Note that the AltiVec support is closely modeled after the FP |
907 | * support. Changes to one are likely to be applicable to the | 780 | * support. Changes to one are likely to be applicable to the |
@@ -1016,42 +889,6 @@ giveup_altivec: | |||
1016 | #endif /* CONFIG_ALTIVEC */ | 889 | #endif /* CONFIG_ALTIVEC */ |
1017 | 890 | ||
1018 | /* | 891 | /* |
1019 | * giveup_fpu(tsk) | ||
1020 | * Disable FP for the task given as the argument, | ||
1021 | * and save the floating-point registers in its thread_struct. | ||
1022 | * Enables the FPU for use in the kernel on return. | ||
1023 | */ | ||
1024 | .globl giveup_fpu | ||
1025 | giveup_fpu: | ||
1026 | mfmsr r5 | ||
1027 | ori r5,r5,MSR_FP | ||
1028 | SYNC_601 | ||
1029 | ISYNC_601 | ||
1030 | MTMSRD(r5) /* enable use of fpu now */ | ||
1031 | SYNC_601 | ||
1032 | isync | ||
1033 | cmpwi 0,r3,0 | ||
1034 | beqlr- /* if no previous owner, done */ | ||
1035 | addi r3,r3,THREAD /* want THREAD of task */ | ||
1036 | lwz r5,PT_REGS(r3) | ||
1037 | cmpwi 0,r5,0 | ||
1038 | SAVE_32FPRS(0, r3) | ||
1039 | mffs fr0 | ||
1040 | stfd fr0,THREAD_FPSCR-4(r3) | ||
1041 | beq 1f | ||
1042 | lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
1043 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | ||
1044 | andc r4,r4,r3 /* disable FP for previous task */ | ||
1045 | stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
1046 | 1: | ||
1047 | #ifndef CONFIG_SMP | ||
1048 | li r5,0 | ||
1049 | lis r4,last_task_used_math@ha | ||
1050 | stw r5,last_task_used_math@l(r4) | ||
1051 | #endif /* CONFIG_SMP */ | ||
1052 | blr | ||
1053 | |||
1054 | /* | ||
1055 | * This code is jumped to from the startup code to copy | 892 | * This code is jumped to from the startup code to copy |
1056 | * the kernel image to physical address 0. | 893 | * the kernel image to physical address 0. |
1057 | */ | 894 | */ |
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S index 9ed8165a3d6c..9b6a8e513657 100644 --- a/arch/ppc/kernel/head_44x.S +++ b/arch/ppc/kernel/head_44x.S | |||
@@ -426,7 +426,11 @@ interrupt_base: | |||
426 | PROGRAM_EXCEPTION | 426 | PROGRAM_EXCEPTION |
427 | 427 | ||
428 | /* Floating Point Unavailable Interrupt */ | 428 | /* Floating Point Unavailable Interrupt */ |
429 | #ifdef CONFIG_PPC_FPU | ||
430 | FP_UNAVAILABLE_EXCEPTION | ||
431 | #else | ||
429 | EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) | 432 | EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) |
433 | #endif | ||
430 | 434 | ||
431 | /* System Call Interrupt */ | 435 | /* System Call Interrupt */ |
432 | START_EXCEPTION(SystemCall) | 436 | START_EXCEPTION(SystemCall) |
@@ -686,8 +690,10 @@ _GLOBAL(giveup_altivec) | |||
686 | * | 690 | * |
687 | * The 44x core does not have an FPU. | 691 | * The 44x core does not have an FPU. |
688 | */ | 692 | */ |
693 | #ifndef CONFIG_PPC_FPU | ||
689 | _GLOBAL(giveup_fpu) | 694 | _GLOBAL(giveup_fpu) |
690 | blr | 695 | blr |
696 | #endif | ||
691 | 697 | ||
692 | /* | 698 | /* |
693 | * extern void abort(void) | 699 | * extern void abort(void) |
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h index 884dac916bce..f213d12eec08 100644 --- a/arch/ppc/kernel/head_booke.h +++ b/arch/ppc/kernel/head_booke.h | |||
@@ -337,4 +337,11 @@ label: | |||
337 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 337 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
338 | EXC_XFER_LITE(0x0900, timer_interrupt) | 338 | EXC_XFER_LITE(0x0900, timer_interrupt) |
339 | 339 | ||
340 | #define FP_UNAVAILABLE_EXCEPTION \ | ||
341 | START_EXCEPTION(FloatingPointUnavailable) \ | ||
342 | NORMAL_EXCEPTION_PROLOG; \ | ||
343 | bne load_up_fpu; /* if from user, just load it up */ \ | ||
344 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | ||
345 | EXC_XFER_EE_LITE(0x800, KernelFP) | ||
346 | |||
340 | #endif /* __HEAD_BOOKE_H__ */ | 347 | #endif /* __HEAD_BOOKE_H__ */ |
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index d64bf61d2b1f..f22ddce36135 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S | |||
@@ -504,7 +504,11 @@ interrupt_base: | |||
504 | PROGRAM_EXCEPTION | 504 | PROGRAM_EXCEPTION |
505 | 505 | ||
506 | /* Floating Point Unavailable Interrupt */ | 506 | /* Floating Point Unavailable Interrupt */ |
507 | #ifdef CONFIG_PPC_FPU | ||
508 | FP_UNAVAILABLE_EXCEPTION | ||
509 | #else | ||
507 | EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) | 510 | EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) |
511 | #endif | ||
508 | 512 | ||
509 | /* System Call Interrupt */ | 513 | /* System Call Interrupt */ |
510 | START_EXCEPTION(SystemCall) | 514 | START_EXCEPTION(SystemCall) |
@@ -916,10 +920,12 @@ _GLOBAL(giveup_spe) | |||
916 | /* | 920 | /* |
917 | * extern void giveup_fpu(struct task_struct *prev) | 921 | * extern void giveup_fpu(struct task_struct *prev) |
918 | * | 922 | * |
919 | * The e500 core does not have an FPU. | 923 | * Not all FSL Book-E cores have an FPU |
920 | */ | 924 | */ |
925 | #ifndef CONFIG_PPC_FPU | ||
921 | _GLOBAL(giveup_fpu) | 926 | _GLOBAL(giveup_fpu) |
922 | blr | 927 | blr |
928 | #endif | ||
923 | 929 | ||
924 | /* | 930 | /* |
925 | * extern void abort(void) | 931 | * extern void abort(void) |
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 73f7c23b0dd4..e4f1615ec13f 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -1096,17 +1096,7 @@ _GLOBAL(_get_SP) | |||
1096 | * and exceptions as if the cpu had performed the load or store. | 1096 | * and exceptions as if the cpu had performed the load or store. |
1097 | */ | 1097 | */ |
1098 | 1098 | ||
1099 | #if defined(CONFIG_4xx) || defined(CONFIG_E500) | 1099 | #ifdef CONFIG_PPC_FPU |
1100 | _GLOBAL(cvt_fd) | ||
1101 | lfs 0,0(r3) | ||
1102 | stfd 0,0(r4) | ||
1103 | blr | ||
1104 | |||
1105 | _GLOBAL(cvt_df) | ||
1106 | lfd 0,0(r3) | ||
1107 | stfs 0,0(r4) | ||
1108 | blr | ||
1109 | #else | ||
1110 | _GLOBAL(cvt_fd) | 1100 | _GLOBAL(cvt_fd) |
1111 | lfd 0,-4(r5) /* load up fpscr value */ | 1101 | lfd 0,-4(r5) /* load up fpscr value */ |
1112 | mtfsf 0xff,0 | 1102 | mtfsf 0xff,0 |
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c index 426b6f7d9de3..59d59a8dc249 100644 --- a/arch/ppc/kernel/ptrace.c +++ b/arch/ppc/kernel/ptrace.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ptrace.h> | 26 | #include <linux/ptrace.h> |
27 | #include <linux/user.h> | 27 | #include <linux/user.h> |
28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
29 | #include <linux/signal.h> | ||
29 | 30 | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/page.h> | 32 | #include <asm/page.h> |
@@ -356,7 +357,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
356 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 357 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
357 | case PTRACE_CONT: { /* restart after signal. */ | 358 | case PTRACE_CONT: { /* restart after signal. */ |
358 | ret = -EIO; | 359 | ret = -EIO; |
359 | if ((unsigned long) data > _NSIG) | 360 | if (!valid_signal(data)) |
360 | break; | 361 | break; |
361 | if (request == PTRACE_SYSCALL) { | 362 | if (request == PTRACE_SYSCALL) { |
362 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 363 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -389,7 +390,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
389 | 390 | ||
390 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 391 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
391 | ret = -EIO; | 392 | ret = -EIO; |
392 | if ((unsigned long) data > _NSIG) | 393 | if (!valid_signal(data)) |
393 | break; | 394 | break; |
394 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 395 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
395 | set_single_step(child); | 396 | set_single_step(child); |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 361865c4bc84..f8e7e324a173 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -176,7 +176,7 @@ static inline int check_io_access(struct pt_regs *regs) | |||
176 | #else | 176 | #else |
177 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR)) | 177 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR)) |
178 | #endif | 178 | #endif |
179 | #define REASON_FP 0 | 179 | #define REASON_FP ESR_FP |
180 | #define REASON_ILLEGAL ESR_PIL | 180 | #define REASON_ILLEGAL ESR_PIL |
181 | #define REASON_PRIVILEGED ESR_PPR | 181 | #define REASON_PRIVILEGED ESR_PPR |
182 | #define REASON_TRAP ESR_PTR | 182 | #define REASON_TRAP ESR_PTR |
diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S index da34a9bc9299..fb977de6b704 100644 --- a/arch/ppc/platforms/pmac_cache.S +++ b/arch/ppc/platforms/pmac_cache.S | |||
@@ -64,27 +64,39 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
64 | mtspr SPRN_HID0,r4 /* Disable DPM */ | 64 | mtspr SPRN_HID0,r4 /* Disable DPM */ |
65 | sync | 65 | sync |
66 | 66 | ||
67 | /* disp-flush L1 */ | 67 | /* Disp-flush L1. We have a weird problem here that I never |
68 | li r4,0x4000 | 68 | * totally figured out. On 750FX, using the ROM for the flush |
69 | mtctr r4 | 69 | * results in a non-working flush. We use that workaround for |
70 | * now until I finally understand what's going on. --BenH | ||
71 | */ | ||
72 | |||
73 | /* ROM base by default */ | ||
70 | lis r4,0xfff0 | 74 | lis r4,0xfff0 |
71 | 1: lwzx r0,r0,r4 | 75 | mfpvr r3 |
76 | srwi r3,r3,16 | ||
77 | cmplwi cr0,r3,0x7000 | ||
78 | bne+ 1f | ||
79 | /* RAM base on 750FX */ | ||
80 | li r4,0 | ||
81 | 1: li r4,0x4000 | ||
82 | mtctr r4 | ||
83 | 1: lwz r0,0(r4) | ||
72 | addi r4,r4,32 | 84 | addi r4,r4,32 |
73 | bdnz 1b | 85 | bdnz 1b |
74 | sync | 86 | sync |
75 | isync | 87 | isync |
76 | 88 | ||
77 | /* disable / invalidate / enable L1 data */ | 89 | /* Disable / invalidate / enable L1 data */ |
78 | mfspr r3,SPRN_HID0 | 90 | mfspr r3,SPRN_HID0 |
79 | rlwinm r0,r0,0,~HID0_DCE | 91 | rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE) |
80 | mtspr SPRN_HID0,r3 | 92 | mtspr SPRN_HID0,r3 |
81 | sync | 93 | sync |
82 | isync | 94 | isync |
83 | ori r3,r3,HID0_DCE|HID0_DCI | 95 | ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI) |
84 | sync | 96 | sync |
85 | isync | 97 | isync |
86 | mtspr SPRN_HID0,r3 | 98 | mtspr SPRN_HID0,r3 |
87 | xori r3,r3,HID0_DCI | 99 | xori r3,r3,(HID0_DCI|HID0_ICFI) |
88 | mtspr SPRN_HID0,r3 | 100 | mtspr SPRN_HID0,r3 |
89 | sync | 101 | sync |
90 | 102 | ||
@@ -110,11 +122,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
110 | lis r4,2 | 122 | lis r4,2 |
111 | mtctr r4 | 123 | mtctr r4 |
112 | lis r4,0xfff0 | 124 | lis r4,0xfff0 |
113 | 1: lwzx r0,r0,r4 | 125 | 1: lwz r0,0(r4) |
126 | addi r4,r4,32 | ||
127 | bdnz 1b | ||
128 | sync | ||
129 | isync | ||
130 | lis r4,2 | ||
131 | mtctr r4 | ||
132 | lis r4,0xfff0 | ||
133 | 1: dcbf 0,r4 | ||
114 | addi r4,r4,32 | 134 | addi r4,r4,32 |
115 | bdnz 1b | 135 | bdnz 1b |
116 | sync | 136 | sync |
117 | isync | 137 | isync |
138 | |||
118 | /* now disable L2 */ | 139 | /* now disable L2 */ |
119 | rlwinm r5,r5,0,~L2CR_L2E | 140 | rlwinm r5,r5,0,~L2CR_L2E |
120 | b 2f | 141 | b 2f |
@@ -135,6 +156,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
135 | mtspr SPRN_L2CR,r4 | 156 | mtspr SPRN_L2CR,r4 |
136 | sync | 157 | sync |
137 | isync | 158 | isync |
159 | |||
160 | /* Wait for the invalidation to complete */ | ||
161 | 1: mfspr r3,SPRN_L2CR | ||
162 | rlwinm. r0,r3,0,31,31 | ||
163 | bne 1b | ||
164 | |||
165 | /* Clear L2I */ | ||
138 | xoris r4,r4,L2CR_L2I@h | 166 | xoris r4,r4,L2CR_L2I@h |
139 | sync | 167 | sync |
140 | mtspr SPRN_L2CR,r4 | 168 | mtspr SPRN_L2CR,r4 |
@@ -142,14 +170,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
142 | 170 | ||
143 | /* now disable the L1 data cache */ | 171 | /* now disable the L1 data cache */ |
144 | mfspr r0,SPRN_HID0 | 172 | mfspr r0,SPRN_HID0 |
145 | rlwinm r0,r0,0,~HID0_DCE | 173 | rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE) |
146 | mtspr SPRN_HID0,r0 | 174 | mtspr SPRN_HID0,r0 |
147 | sync | 175 | sync |
148 | isync | 176 | isync |
149 | 177 | ||
150 | /* Restore HID0[DPM] to whatever it was before */ | 178 | /* Restore HID0[DPM] to whatever it was before */ |
151 | sync | 179 | sync |
152 | mtspr SPRN_HID0,r8 | 180 | mfspr r0,SPRN_HID0 |
181 | rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */ | ||
182 | mtspr SPRN_HID0,r0 | ||
153 | sync | 183 | sync |
154 | 184 | ||
155 | /* restore DR and EE */ | 185 | /* restore DR and EE */ |
@@ -201,7 +231,7 @@ flush_disable_745x: | |||
201 | mtctr r4 | 231 | mtctr r4 |
202 | li r4,0 | 232 | li r4,0 |
203 | 1: | 233 | 1: |
204 | lwzx r0,r0,r4 | 234 | lwz r0,0(r4) |
205 | addi r4,r4,32 /* Go to start of next cache line */ | 235 | addi r4,r4,32 /* Go to start of next cache line */ |
206 | bdnz 1b | 236 | bdnz 1b |
207 | isync | 237 | isync |
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c index 46cbf36722db..867336ad5d36 100644 --- a/arch/ppc/platforms/pmac_feature.c +++ b/arch/ppc/platforms/pmac_feature.c | |||
@@ -1590,6 +1590,114 @@ intrepid_shutdown(struct macio_chip* macio, int sleep_mode) | |||
1590 | mdelay(10); | 1590 | mdelay(10); |
1591 | } | 1591 | } |
1592 | 1592 | ||
1593 | |||
1594 | void __pmac pmac_tweak_clock_spreading(int enable) | ||
1595 | { | ||
1596 | struct macio_chip* macio = &macio_chips[0]; | ||
1597 | |||
1598 | /* Hack for doing clock spreading on some machines PowerBooks and | ||
1599 | * iBooks. This implements the "platform-do-clockspreading" OF | ||
1600 | * property as decoded manually on various models. For safety, we also | ||
1601 | * check the product ID in the device-tree in cases we'll whack the i2c | ||
1602 | * chip to make reasonably sure we won't set wrong values in there | ||
1603 | * | ||
1604 | * Of course, ultimately, we have to implement a real parser for | ||
1605 | * the platform-do-* stuff... | ||
1606 | */ | ||
1607 | |||
1608 | if (macio->type == macio_intrepid) { | ||
1609 | if (enable) | ||
1610 | UN_OUT(UNI_N_CLOCK_SPREADING, 2); | ||
1611 | else | ||
1612 | UN_OUT(UNI_N_CLOCK_SPREADING, 0); | ||
1613 | mdelay(40); | ||
1614 | } | ||
1615 | |||
1616 | while (machine_is_compatible("PowerBook5,2") || | ||
1617 | machine_is_compatible("PowerBook5,3") || | ||
1618 | machine_is_compatible("PowerBook6,2") || | ||
1619 | machine_is_compatible("PowerBook6,3")) { | ||
1620 | struct device_node *ui2c = of_find_node_by_type(NULL, "i2c"); | ||
1621 | struct device_node *dt = of_find_node_by_name(NULL, "device-tree"); | ||
1622 | u8 buffer[9]; | ||
1623 | u32 *productID; | ||
1624 | int i, rc, changed = 0; | ||
1625 | |||
1626 | if (dt == NULL) | ||
1627 | break; | ||
1628 | productID = (u32 *)get_property(dt, "pid#", NULL); | ||
1629 | if (productID == NULL) | ||
1630 | break; | ||
1631 | while(ui2c) { | ||
1632 | struct device_node *p = of_get_parent(ui2c); | ||
1633 | if (p && !strcmp(p->name, "uni-n")) | ||
1634 | break; | ||
1635 | ui2c = of_find_node_by_type(ui2c, "i2c"); | ||
1636 | } | ||
1637 | if (ui2c == NULL) | ||
1638 | break; | ||
1639 | DBG("Trying to bump clock speed for PID: %08x...\n", *productID); | ||
1640 | rc = pmac_low_i2c_open(ui2c, 1); | ||
1641 | if (rc != 0) | ||
1642 | break; | ||
1643 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); | ||
1644 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); | ||
1645 | DBG("read result: %d,", rc); | ||
1646 | if (rc != 0) { | ||
1647 | pmac_low_i2c_close(ui2c); | ||
1648 | break; | ||
1649 | } | ||
1650 | for (i=0; i<9; i++) | ||
1651 | DBG(" %02x", buffer[i]); | ||
1652 | DBG("\n"); | ||
1653 | |||
1654 | switch(*productID) { | ||
1655 | case 0x1182: /* AlBook 12" rev 2 */ | ||
1656 | case 0x1183: /* iBook G4 12" */ | ||
1657 | buffer[0] = (buffer[0] & 0x8f) | 0x70; | ||
1658 | buffer[2] = (buffer[2] & 0x7f) | 0x00; | ||
1659 | buffer[5] = (buffer[5] & 0x80) | 0x31; | ||
1660 | buffer[6] = (buffer[6] & 0x40) | 0xb0; | ||
1661 | buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba); | ||
1662 | buffer[8] = (buffer[8] & 0x00) | 0x30; | ||
1663 | changed = 1; | ||
1664 | break; | ||
1665 | case 0x3142: /* AlBook 15" (ATI M10) */ | ||
1666 | case 0x3143: /* AlBook 17" (ATI M10) */ | ||
1667 | buffer[0] = (buffer[0] & 0xaf) | 0x50; | ||
1668 | buffer[2] = (buffer[2] & 0x7f) | 0x00; | ||
1669 | buffer[5] = (buffer[5] & 0x80) | 0x31; | ||
1670 | buffer[6] = (buffer[6] & 0x40) | 0xb0; | ||
1671 | buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0); | ||
1672 | buffer[8] = (buffer[8] & 0x00) | 0x30; | ||
1673 | changed = 1; | ||
1674 | break; | ||
1675 | default: | ||
1676 | DBG("i2c-hwclock: Machine model not handled\n"); | ||
1677 | break; | ||
1678 | } | ||
1679 | if (!changed) { | ||
1680 | pmac_low_i2c_close(ui2c); | ||
1681 | break; | ||
1682 | } | ||
1683 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub); | ||
1684 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9); | ||
1685 | DBG("write result: %d,", rc); | ||
1686 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); | ||
1687 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); | ||
1688 | DBG("read result: %d,", rc); | ||
1689 | if (rc != 0) { | ||
1690 | pmac_low_i2c_close(ui2c); | ||
1691 | break; | ||
1692 | } | ||
1693 | for (i=0; i<9; i++) | ||
1694 | DBG(" %02x", buffer[i]); | ||
1695 | pmac_low_i2c_close(ui2c); | ||
1696 | break; | ||
1697 | } | ||
1698 | } | ||
1699 | |||
1700 | |||
1593 | static int __pmac | 1701 | static int __pmac |
1594 | core99_sleep(void) | 1702 | core99_sleep(void) |
1595 | { | 1703 | { |
@@ -1601,12 +1709,6 @@ core99_sleep(void) | |||
1601 | macio->type != macio_intrepid) | 1709 | macio->type != macio_intrepid) |
1602 | return -ENODEV; | 1710 | return -ENODEV; |
1603 | 1711 | ||
1604 | /* The device-tree contains that in the hwclock node */ | ||
1605 | if (macio->type == macio_intrepid) { | ||
1606 | UN_OUT(UNI_N_CLOCK_SPREADING, 0); | ||
1607 | mdelay(40); | ||
1608 | } | ||
1609 | |||
1610 | /* We power off the wireless slot in case it was not done | 1712 | /* We power off the wireless slot in case it was not done |
1611 | * by the driver. We don't power it on automatically however | 1713 | * by the driver. We don't power it on automatically however |
1612 | */ | 1714 | */ |
@@ -1749,12 +1851,6 @@ core99_wake_up(void) | |||
1749 | UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl); | 1851 | UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl); |
1750 | udelay(100); | 1852 | udelay(100); |
1751 | 1853 | ||
1752 | /* Restore clock spreading */ | ||
1753 | if (macio->type == macio_intrepid) { | ||
1754 | UN_OUT(UNI_N_CLOCK_SPREADING, 2); | ||
1755 | mdelay(40); | ||
1756 | } | ||
1757 | |||
1758 | return 0; | 1854 | return 0; |
1759 | } | 1855 | } |
1760 | 1856 | ||
@@ -2149,7 +2245,7 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { | |||
2149 | }, | 2245 | }, |
2150 | { "PowerBook1,1", "PowerBook 101 (Lombard)", | 2246 | { "PowerBook1,1", "PowerBook 101 (Lombard)", |
2151 | PMAC_TYPE_101_PBOOK, paddington_features, | 2247 | PMAC_TYPE_101_PBOOK, paddington_features, |
2152 | PMAC_MB_MAY_SLEEP | PMAC_MB_MOBILE | 2248 | PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE |
2153 | }, | 2249 | }, |
2154 | { "PowerBook2,1", "iBook (first generation)", | 2250 | { "PowerBook2,1", "iBook (first generation)", |
2155 | PMAC_TYPE_ORIG_IBOOK, core99_features, | 2251 | PMAC_TYPE_ORIG_IBOOK, core99_features, |
@@ -2718,97 +2814,11 @@ set_initial_features(void) | |||
2718 | MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); | 2814 | MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); |
2719 | } | 2815 | } |
2720 | 2816 | ||
2721 | /* Hack for bumping clock speed on the new PowerBooks and the | 2817 | /* Some machine models need the clock chip to be properly setup for |
2722 | * iBook G4. This implements the "platform-do-clockspreading" OF | 2818 | * clock spreading now. This should be a platform function but we |
2723 | * property. For safety, we also check the product ID in the | 2819 | * don't do these at the moment |
2724 | * device-tree to make reasonably sure we won't set wrong values | ||
2725 | * in the clock chip. | ||
2726 | * | ||
2727 | * Of course, ultimately, we have to implement a real parser for | ||
2728 | * the platform-do-* stuff... | ||
2729 | */ | 2820 | */ |
2730 | while (machine_is_compatible("PowerBook5,2") || | 2821 | pmac_tweak_clock_spreading(1); |
2731 | machine_is_compatible("PowerBook5,3") || | ||
2732 | machine_is_compatible("PowerBook6,2") || | ||
2733 | machine_is_compatible("PowerBook6,3")) { | ||
2734 | struct device_node *ui2c = of_find_node_by_type(NULL, "i2c"); | ||
2735 | struct device_node *dt = of_find_node_by_name(NULL, "device-tree"); | ||
2736 | u8 buffer[9]; | ||
2737 | u32 *productID; | ||
2738 | int i, rc, changed = 0; | ||
2739 | |||
2740 | if (dt == NULL) | ||
2741 | break; | ||
2742 | productID = (u32 *)get_property(dt, "pid#", NULL); | ||
2743 | if (productID == NULL) | ||
2744 | break; | ||
2745 | while(ui2c) { | ||
2746 | struct device_node *p = of_get_parent(ui2c); | ||
2747 | if (p && !strcmp(p->name, "uni-n")) | ||
2748 | break; | ||
2749 | ui2c = of_find_node_by_type(ui2c, "i2c"); | ||
2750 | } | ||
2751 | if (ui2c == NULL) | ||
2752 | break; | ||
2753 | DBG("Trying to bump clock speed for PID: %08x...\n", *productID); | ||
2754 | rc = pmac_low_i2c_open(ui2c, 1); | ||
2755 | if (rc != 0) | ||
2756 | break; | ||
2757 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); | ||
2758 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); | ||
2759 | DBG("read result: %d,", rc); | ||
2760 | if (rc != 0) { | ||
2761 | pmac_low_i2c_close(ui2c); | ||
2762 | break; | ||
2763 | } | ||
2764 | for (i=0; i<9; i++) | ||
2765 | DBG(" %02x", buffer[i]); | ||
2766 | DBG("\n"); | ||
2767 | |||
2768 | switch(*productID) { | ||
2769 | case 0x1182: /* AlBook 12" rev 2 */ | ||
2770 | case 0x1183: /* iBook G4 12" */ | ||
2771 | buffer[0] = (buffer[0] & 0x8f) | 0x70; | ||
2772 | buffer[2] = (buffer[2] & 0x7f) | 0x00; | ||
2773 | buffer[5] = (buffer[5] & 0x80) | 0x31; | ||
2774 | buffer[6] = (buffer[6] & 0x40) | 0xb0; | ||
2775 | buffer[7] = (buffer[7] & 0x00) | 0xc0; | ||
2776 | buffer[8] = (buffer[8] & 0x00) | 0x30; | ||
2777 | changed = 1; | ||
2778 | break; | ||
2779 | case 0x3142: /* AlBook 15" (ATI M10) */ | ||
2780 | case 0x3143: /* AlBook 17" (ATI M10) */ | ||
2781 | buffer[0] = (buffer[0] & 0xaf) | 0x50; | ||
2782 | buffer[2] = (buffer[2] & 0x7f) | 0x00; | ||
2783 | buffer[5] = (buffer[5] & 0x80) | 0x31; | ||
2784 | buffer[6] = (buffer[6] & 0x40) | 0xb0; | ||
2785 | buffer[7] = (buffer[7] & 0x00) | 0xd0; | ||
2786 | buffer[8] = (buffer[8] & 0x00) | 0x30; | ||
2787 | changed = 1; | ||
2788 | break; | ||
2789 | default: | ||
2790 | DBG("i2c-hwclock: Machine model not handled\n"); | ||
2791 | break; | ||
2792 | } | ||
2793 | if (!changed) { | ||
2794 | pmac_low_i2c_close(ui2c); | ||
2795 | break; | ||
2796 | } | ||
2797 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub); | ||
2798 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9); | ||
2799 | DBG("write result: %d,", rc); | ||
2800 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); | ||
2801 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); | ||
2802 | DBG("read result: %d,", rc); | ||
2803 | if (rc != 0) { | ||
2804 | pmac_low_i2c_close(ui2c); | ||
2805 | break; | ||
2806 | } | ||
2807 | for (i=0; i<9; i++) | ||
2808 | DBG(" %02x", buffer[i]); | ||
2809 | pmac_low_i2c_close(ui2c); | ||
2810 | break; | ||
2811 | } | ||
2812 | 2822 | ||
2813 | #endif /* CONFIG_POWER4 */ | 2823 | #endif /* CONFIG_POWER4 */ |
2814 | 2824 | ||
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S index 3139b6766ad3..f459ade1bd63 100644 --- a/arch/ppc/platforms/pmac_sleep.S +++ b/arch/ppc/platforms/pmac_sleep.S | |||
@@ -267,6 +267,10 @@ grackle_wake_up: | |||
267 | /* Restore various CPU config stuffs */ | 267 | /* Restore various CPU config stuffs */ |
268 | bl __restore_cpu_setup | 268 | bl __restore_cpu_setup |
269 | 269 | ||
270 | /* Make sure all FPRs have been initialized */ | ||
271 | bl reloc_offset | ||
272 | bl __init_fpu_registers | ||
273 | |||
270 | /* Invalidate & enable L1 cache, we don't care about | 274 | /* Invalidate & enable L1 cache, we don't care about |
271 | * whatever the ROM may have tried to write to memory | 275 | * whatever the ROM may have tried to write to memory |
272 | */ | 276 | */ |
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c index 2a99b43737a8..c30607a972d8 100644 --- a/arch/ppc/platforms/radstone_ppc7d.c +++ b/arch/ppc/platforms/radstone_ppc7d.c | |||
@@ -68,6 +68,7 @@ | |||
68 | #define PPC7D_RST_PIN 17 /* GPP17 */ | 68 | #define PPC7D_RST_PIN 17 /* GPP17 */ |
69 | 69 | ||
70 | extern u32 mv64360_irq_base; | 70 | extern u32 mv64360_irq_base; |
71 | extern spinlock_t rtc_lock; | ||
71 | 72 | ||
72 | static struct mv64x60_handle bh; | 73 | static struct mv64x60_handle bh; |
73 | static int ppc7d_has_alma; | 74 | static int ppc7d_has_alma; |
@@ -75,6 +76,11 @@ static int ppc7d_has_alma; | |||
75 | extern void gen550_progress(char *, unsigned short); | 76 | extern void gen550_progress(char *, unsigned short); |
76 | extern void gen550_init(int, struct uart_port *); | 77 | extern void gen550_init(int, struct uart_port *); |
77 | 78 | ||
79 | /* FIXME - move to h file */ | ||
80 | extern int ds1337_do_command(int id, int cmd, void *arg); | ||
81 | #define DS1337_GET_DATE 0 | ||
82 | #define DS1337_SET_DATE 1 | ||
83 | |||
78 | /* residual data */ | 84 | /* residual data */ |
79 | unsigned char __res[sizeof(bd_t)]; | 85 | unsigned char __res[sizeof(bd_t)]; |
80 | 86 | ||
@@ -253,6 +259,8 @@ static int ppc7d_show_cpuinfo(struct seq_file *m) | |||
253 | u8 val1, val2; | 259 | u8 val1, val2; |
254 | static int flash_sizes[4] = { 64, 32, 0, 16 }; | 260 | static int flash_sizes[4] = { 64, 32, 0, 16 }; |
255 | static int flash_banks[4] = { 4, 3, 2, 1 }; | 261 | static int flash_banks[4] = { 4, 3, 2, 1 }; |
262 | static int sdram_bank_sizes[4] = { 128, 256, 512, 1 }; | ||
263 | int sdram_num_banks = 2; | ||
256 | static char *pci_modes[] = { "PCI33", "PCI66", | 264 | static char *pci_modes[] = { "PCI33", "PCI66", |
257 | "Unknown", "Unknown", | 265 | "Unknown", "Unknown", |
258 | "PCIX33", "PCIX66", | 266 | "PCIX33", "PCIX66", |
@@ -279,13 +287,17 @@ static int ppc7d_show_cpuinfo(struct seq_file *m) | |||
279 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 : | 287 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 : |
280 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0); | 288 | (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0); |
281 | 289 | ||
290 | val = inb(PPC7D_CPLD_MEM_CONFIG); | ||
291 | if (val & PPC7D_CPLD_SDRAM_BANK_NUM_MASK) sdram_num_banks--; | ||
292 | |||
282 | val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND); | 293 | val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND); |
283 | val1 = val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK; | 294 | val1 = (val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK) >> 6; |
284 | seq_printf(m, "SDRAM\t\t: %d%c", | 295 | seq_printf(m, "SDRAM\t\t: %d banks of %d%c, total %d%c", |
285 | (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_128M) ? 128 : | 296 | sdram_num_banks, |
286 | (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_256M) ? 256 : | 297 | sdram_bank_sizes[val1], |
287 | (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_512M) ? 512 : 1, | 298 | (sdram_bank_sizes[val1] < 128) ? 'G' : 'M', |
288 | (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_1G) ? 'G' : 'M'); | 299 | sdram_num_banks * sdram_bank_sizes[val1], |
300 | (sdram_bank_sizes[val1] < 128) ? 'G' : 'M'); | ||
289 | if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) { | 301 | if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) { |
290 | seq_printf(m, " [ECC %sabled]", | 302 | seq_printf(m, " [ECC %sabled]", |
291 | (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" : | 303 | (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" : |
@@ -1236,6 +1248,38 @@ static void __init ppc7d_setup_arch(void) | |||
1236 | printk(KERN_INFO "Radstone Technology PPC7D\n"); | 1248 | printk(KERN_INFO "Radstone Technology PPC7D\n"); |
1237 | if (ppc_md.progress) | 1249 | if (ppc_md.progress) |
1238 | ppc_md.progress("ppc7d_setup_arch: exit", 0); | 1250 | ppc_md.progress("ppc7d_setup_arch: exit", 0); |
1251 | |||
1252 | } | ||
1253 | |||
1254 | /* Real Time Clock support. | ||
1255 | * PPC7D has a DS1337 accessed by I2C. | ||
1256 | */ | ||
1257 | static ulong ppc7d_get_rtc_time(void) | ||
1258 | { | ||
1259 | struct rtc_time tm; | ||
1260 | int result; | ||
1261 | |||
1262 | spin_lock(&rtc_lock); | ||
1263 | result = ds1337_do_command(0, DS1337_GET_DATE, &tm); | ||
1264 | spin_unlock(&rtc_lock); | ||
1265 | |||
1266 | if (result == 0) | ||
1267 | result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
1268 | |||
1269 | return result; | ||
1270 | } | ||
1271 | |||
1272 | static int ppc7d_set_rtc_time(unsigned long nowtime) | ||
1273 | { | ||
1274 | struct rtc_time tm; | ||
1275 | int result; | ||
1276 | |||
1277 | spin_lock(&rtc_lock); | ||
1278 | to_tm(nowtime, &tm); | ||
1279 | result = ds1337_do_command(0, DS1337_SET_DATE, &tm); | ||
1280 | spin_unlock(&rtc_lock); | ||
1281 | |||
1282 | return result; | ||
1239 | } | 1283 | } |
1240 | 1284 | ||
1241 | /* This kernel command line parameter can be used to have the target | 1285 | /* This kernel command line parameter can be used to have the target |
@@ -1293,6 +1337,10 @@ static void ppc7d_init2(void) | |||
1293 | data8 |= 0x07; | 1337 | data8 |= 0x07; |
1294 | outb(data8, PPC7D_CPLD_LEDS); | 1338 | outb(data8, PPC7D_CPLD_LEDS); |
1295 | 1339 | ||
1340 | /* Hook up RTC. We couldn't do this earlier because we need the I2C subsystem */ | ||
1341 | ppc_md.set_rtc_time = ppc7d_set_rtc_time; | ||
1342 | ppc_md.get_rtc_time = ppc7d_get_rtc_time; | ||
1343 | |||
1296 | pr_debug("%s: exit\n", __FUNCTION__); | 1344 | pr_debug("%s: exit\n", __FUNCTION__); |
1297 | } | 1345 | } |
1298 | 1346 | ||
diff --git a/arch/ppc/platforms/radstone_ppc7d.h b/arch/ppc/platforms/radstone_ppc7d.h index 4546fff2b0c3..938375510be4 100644 --- a/arch/ppc/platforms/radstone_ppc7d.h +++ b/arch/ppc/platforms/radstone_ppc7d.h | |||
@@ -240,6 +240,7 @@ | |||
240 | #define PPC7D_CPLD_FLASH_CNTL 0x086E | 240 | #define PPC7D_CPLD_FLASH_CNTL 0x086E |
241 | 241 | ||
242 | /* MEMORY_CONFIG_EXTEND */ | 242 | /* MEMORY_CONFIG_EXTEND */ |
243 | #define PPC7D_CPLD_SDRAM_BANK_NUM_MASK 0x02 | ||
243 | #define PPC7D_CPLD_SDRAM_BANK_SIZE_MASK 0xc0 | 244 | #define PPC7D_CPLD_SDRAM_BANK_SIZE_MASK 0xc0 |
244 | #define PPC7D_CPLD_SDRAM_BANK_SIZE_128M 0 | 245 | #define PPC7D_CPLD_SDRAM_BANK_SIZE_128M 0 |
245 | #define PPC7D_CPLD_SDRAM_BANK_SIZE_256M 0x40 | 246 | #define PPC7D_CPLD_SDRAM_BANK_SIZE_256M 0x40 |
diff --git a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c index 954b07fc1df3..c867be6981cb 100644 --- a/arch/ppc/syslib/cpm2_pic.c +++ b/arch/ppc/syslib/cpm2_pic.c | |||
@@ -107,6 +107,11 @@ static void cpm2_end_irq(unsigned int irq_nr) | |||
107 | simr = &(cpm2_immr->im_intctl.ic_simrh); | 107 | simr = &(cpm2_immr->im_intctl.ic_simrh); |
108 | ppc_cached_irq_mask[word] |= 1 << bit; | 108 | ppc_cached_irq_mask[word] |= 1 << bit; |
109 | simr[word] = ppc_cached_irq_mask[word]; | 109 | simr[word] = ppc_cached_irq_mask[word]; |
110 | /* | ||
111 | * Work around large numbers of spurious IRQs on PowerPC 82xx | ||
112 | * systems. | ||
113 | */ | ||
114 | mb(); | ||
110 | } | 115 | } |
111 | } | 116 | } |
112 | 117 | ||
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index d33e20bcc52f..691f3008e698 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile | |||
@@ -56,13 +56,20 @@ LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) | |||
56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ | 56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ |
57 | -mcall-aixdesc | 57 | -mcall-aixdesc |
58 | 58 | ||
59 | GCC_VERSION := $(call cc-version) | ||
60 | GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) | ||
61 | |||
59 | ifeq ($(CONFIG_POWER4_ONLY),y) | 62 | ifeq ($(CONFIG_POWER4_ONLY),y) |
60 | ifeq ($(CONFIG_ALTIVEC),y) | 63 | ifeq ($(CONFIG_ALTIVEC),y) |
64 | ifeq ($(GCC_BROKEN_VEC),y) | ||
61 | CFLAGS += $(call cc-option,-mcpu=970) | 65 | CFLAGS += $(call cc-option,-mcpu=970) |
62 | else | 66 | else |
63 | CFLAGS += $(call cc-option,-mcpu=power4) | 67 | CFLAGS += $(call cc-option,-mcpu=power4) |
64 | endif | 68 | endif |
65 | else | 69 | else |
70 | CFLAGS += $(call cc-option,-mcpu=power4) | ||
71 | endif | ||
72 | else | ||
66 | CFLAGS += $(call cc-option,-mtune=power4) | 73 | CFLAGS += $(call cc-option,-mtune=power4) |
67 | endif | 74 | endif |
68 | 75 | ||
diff --git a/arch/ppc64/boot/addnote.c b/arch/ppc64/boot/addnote.c index 66ff8103bf4d..719663a694bb 100644 --- a/arch/ppc64/boot/addnote.c +++ b/arch/ppc64/boot/addnote.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <unistd.h> | 19 | #include <unistd.h> |
20 | #include <string.h> | 20 | #include <string.h> |
21 | 21 | ||
22 | /* CHRP note section */ | ||
22 | char arch[] = "PowerPC"; | 23 | char arch[] = "PowerPC"; |
23 | 24 | ||
24 | #define N_DESCR 6 | 25 | #define N_DESCR 6 |
@@ -31,6 +32,29 @@ unsigned int descr[N_DESCR] = { | |||
31 | 0x4000, /* load-base */ | 32 | 0x4000, /* load-base */ |
32 | }; | 33 | }; |
33 | 34 | ||
35 | /* RPA note section */ | ||
36 | char rpaname[] = "IBM,RPA-Client-Config"; | ||
37 | |||
38 | /* | ||
39 | * Note: setting ignore_my_client_config *should* mean that OF ignores | ||
40 | * all the other fields, but there is a firmware bug which means that | ||
41 | * it looks at the splpar field at least. So these values need to be | ||
42 | * reasonable. | ||
43 | */ | ||
44 | #define N_RPA_DESCR 8 | ||
45 | unsigned int rpanote[N_RPA_DESCR] = { | ||
46 | 0, /* lparaffinity */ | ||
47 | 64, /* min_rmo_size */ | ||
48 | 0, /* min_rmo_percent */ | ||
49 | 40, /* max_pft_size */ | ||
50 | 1, /* splpar */ | ||
51 | -1, /* min_load */ | ||
52 | 0, /* new_mem_def */ | ||
53 | 1, /* ignore_my_client_config */ | ||
54 | }; | ||
55 | |||
56 | #define ROUNDUP(len) (((len) + 3) & ~3) | ||
57 | |||
34 | unsigned char buf[512]; | 58 | unsigned char buf[512]; |
35 | 59 | ||
36 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) | 60 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) |
@@ -69,7 +93,7 @@ main(int ac, char **av) | |||
69 | { | 93 | { |
70 | int fd, n, i; | 94 | int fd, n, i; |
71 | int ph, ps, np; | 95 | int ph, ps, np; |
72 | int nnote, ns; | 96 | int nnote, nnote2, ns; |
73 | 97 | ||
74 | if (ac != 2) { | 98 | if (ac != 2) { |
75 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); | 99 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); |
@@ -81,7 +105,8 @@ main(int ac, char **av) | |||
81 | exit(1); | 105 | exit(1); |
82 | } | 106 | } |
83 | 107 | ||
84 | nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; | 108 | nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr); |
109 | nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote); | ||
85 | 110 | ||
86 | n = read(fd, buf, sizeof(buf)); | 111 | n = read(fd, buf, sizeof(buf)); |
87 | if (n < 0) { | 112 | if (n < 0) { |
@@ -104,7 +129,7 @@ main(int ac, char **av) | |||
104 | np = GET_16BE(E_PHNUM); | 129 | np = GET_16BE(E_PHNUM); |
105 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) | 130 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) |
106 | goto notelf; | 131 | goto notelf; |
107 | if (ph + (np + 1) * ps + nnote > n) | 132 | if (ph + (np + 2) * ps + nnote + nnote2 > n) |
108 | goto nospace; | 133 | goto nospace; |
109 | 134 | ||
110 | for (i = 0; i < np; ++i) { | 135 | for (i = 0; i < np; ++i) { |
@@ -117,12 +142,12 @@ main(int ac, char **av) | |||
117 | } | 142 | } |
118 | 143 | ||
119 | /* XXX check that the area we want to use is all zeroes */ | 144 | /* XXX check that the area we want to use is all zeroes */ |
120 | for (i = 0; i < ps + nnote; ++i) | 145 | for (i = 0; i < 2 * ps + nnote + nnote2; ++i) |
121 | if (buf[ph + i] != 0) | 146 | if (buf[ph + i] != 0) |
122 | goto nospace; | 147 | goto nospace; |
123 | 148 | ||
124 | /* fill in the program header entry */ | 149 | /* fill in the program header entry */ |
125 | ns = ph + ps; | 150 | ns = ph + 2 * ps; |
126 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | 151 | PUT_32BE(ph + PH_TYPE, PT_NOTE); |
127 | PUT_32BE(ph + PH_OFFSET, ns); | 152 | PUT_32BE(ph + PH_OFFSET, ns); |
128 | PUT_32BE(ph + PH_FILESZ, nnote); | 153 | PUT_32BE(ph + PH_FILESZ, nnote); |
@@ -134,11 +159,26 @@ main(int ac, char **av) | |||
134 | PUT_32BE(ns + 8, 0x1275); | 159 | PUT_32BE(ns + 8, 0x1275); |
135 | strcpy(&buf[ns + 12], arch); | 160 | strcpy(&buf[ns + 12], arch); |
136 | ns += 12 + strlen(arch) + 1; | 161 | ns += 12 + strlen(arch) + 1; |
137 | for (i = 0; i < N_DESCR; ++i) | 162 | for (i = 0; i < N_DESCR; ++i, ns += 4) |
138 | PUT_32BE(ns + i * 4, descr[i]); | 163 | PUT_32BE(ns, descr[i]); |
164 | |||
165 | /* fill in the second program header entry and the RPA note area */ | ||
166 | ph += ps; | ||
167 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | ||
168 | PUT_32BE(ph + PH_OFFSET, ns); | ||
169 | PUT_32BE(ph + PH_FILESZ, nnote2); | ||
170 | |||
171 | /* fill in the note area we point to */ | ||
172 | PUT_32BE(ns, strlen(rpaname) + 1); | ||
173 | PUT_32BE(ns + 4, sizeof(rpanote)); | ||
174 | PUT_32BE(ns + 8, 0x12759999); | ||
175 | strcpy(&buf[ns + 12], rpaname); | ||
176 | ns += 12 + ROUNDUP(strlen(rpaname) + 1); | ||
177 | for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) | ||
178 | PUT_32BE(ns, rpanote[i]); | ||
139 | 179 | ||
140 | /* Update the number of program headers */ | 180 | /* Update the number of program headers */ |
141 | PUT_16BE(E_PHNUM, np + 1); | 181 | PUT_16BE(E_PHNUM, np + 2); |
142 | 182 | ||
143 | /* write back */ | 183 | /* write back */ |
144 | lseek(fd, (long) 0, SEEK_SET); | 184 | lseek(fd, (long) 0, SEEK_SET); |
@@ -155,11 +195,11 @@ main(int ac, char **av) | |||
155 | exit(0); | 195 | exit(0); |
156 | 196 | ||
157 | notelf: | 197 | notelf: |
158 | fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); | 198 | fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); |
159 | exit(1); | 199 | exit(1); |
160 | 200 | ||
161 | nospace: | 201 | nospace: |
162 | fprintf(stderr, "sorry, I can't find space in %s to put the note\n", | 202 | fprintf(stderr, "sorry, I can't find space in %s to put the note\n", |
163 | av[0]); | 203 | av[1]); |
164 | exit(1); | 204 | exit(1); |
165 | } | 205 | } |
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c index 9802beefa217..f8f19637f73f 100644 --- a/arch/ppc64/kernel/HvLpEvent.c +++ b/arch/ppc64/kernel/HvLpEvent.c | |||
@@ -45,7 +45,7 @@ int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType ) | |||
45 | /* We now sleep until all other CPUs have scheduled. This ensures that | 45 | /* We now sleep until all other CPUs have scheduled. This ensures that |
46 | * the deletion is seen by all other CPUs, and that the deleted handler | 46 | * the deletion is seen by all other CPUs, and that the deleted handler |
47 | * isn't still running on another CPU when we return. */ | 47 | * isn't still running on another CPU when we return. */ |
48 | synchronize_kernel(); | 48 | synchronize_rcu(); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | return rc; | 51 | return rc; |
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index b9069c2d1933..4e71781a4414 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c | |||
@@ -339,9 +339,9 @@ static int nvram_remove_os_partition(void) | |||
339 | static int nvram_create_os_partition(void) | 339 | static int nvram_create_os_partition(void) |
340 | { | 340 | { |
341 | struct list_head * p; | 341 | struct list_head * p; |
342 | struct nvram_partition * part; | 342 | struct nvram_partition *part = NULL; |
343 | struct nvram_partition * new_part = NULL; | 343 | struct nvram_partition *new_part = NULL; |
344 | struct nvram_partition * free_part = NULL; | 344 | struct nvram_partition *free_part = NULL; |
345 | int seq_init[2] = { 0, 0 }; | 345 | int seq_init[2] = { 0, 0 }; |
346 | loff_t tmp_index; | 346 | loff_t tmp_index; |
347 | long size = 0; | 347 | long size = 0; |
@@ -364,13 +364,11 @@ static int nvram_create_os_partition(void) | |||
364 | free_part = part; | 364 | free_part = part; |
365 | } | 365 | } |
366 | } | 366 | } |
367 | if (!size) { | 367 | if (!size) |
368 | return -ENOSPC; | 368 | return -ENOSPC; |
369 | } | ||
370 | 369 | ||
371 | /* Create our OS partition */ | 370 | /* Create our OS partition */ |
372 | new_part = (struct nvram_partition *) | 371 | new_part = kmalloc(sizeof(*new_part), GFP_KERNEL); |
373 | kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); | ||
374 | if (!new_part) { | 372 | if (!new_part) { |
375 | printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n"); | 373 | printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n"); |
376 | return -ENOMEM; | 374 | return -ENOMEM; |
@@ -379,7 +377,7 @@ static int nvram_create_os_partition(void) | |||
379 | new_part->index = free_part->index; | 377 | new_part->index = free_part->index; |
380 | new_part->header.signature = NVRAM_SIG_OS; | 378 | new_part->header.signature = NVRAM_SIG_OS; |
381 | new_part->header.length = size; | 379 | new_part->header.length = size; |
382 | sprintf(new_part->header.name, "ppc64,linux"); | 380 | strcpy(new_part->header.name, "ppc64,linux"); |
383 | new_part->header.checksum = nvram_checksum(&new_part->header); | 381 | new_part->header.checksum = nvram_checksum(&new_part->header); |
384 | 382 | ||
385 | rc = nvram_write_header(new_part); | 383 | rc = nvram_write_header(new_part); |
@@ -394,7 +392,8 @@ static int nvram_create_os_partition(void) | |||
394 | tmp_index = new_part->index + NVRAM_HEADER_LEN; | 392 | tmp_index = new_part->index + NVRAM_HEADER_LEN; |
395 | rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index); | 393 | rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index); |
396 | if (rc <= 0) { | 394 | if (rc <= 0) { |
397 | printk(KERN_ERR "nvram_create_os_partition: nvram_write failed (%d)\n", rc); | 395 | printk(KERN_ERR "nvram_create_os_partition: nvram_write " |
396 | "failed (%d)\n", rc); | ||
398 | return rc; | 397 | return rc; |
399 | } | 398 | } |
400 | 399 | ||
diff --git a/arch/ppc64/kernel/pSeries_hvCall.S b/arch/ppc64/kernel/pSeries_hvCall.S index 0715d3038019..176e8da76466 100644 --- a/arch/ppc64/kernel/pSeries_hvCall.S +++ b/arch/ppc64/kernel/pSeries_hvCall.S | |||
@@ -28,6 +28,8 @@ | |||
28 | unsigned long *out3); R10 | 28 | unsigned long *out3); R10 |
29 | */ | 29 | */ |
30 | _GLOBAL(plpar_hcall) | 30 | _GLOBAL(plpar_hcall) |
31 | HMT_MEDIUM | ||
32 | |||
31 | mfcr r0 | 33 | mfcr r0 |
32 | 34 | ||
33 | std r8,STK_PARM(r8)(r1) /* Save out ptrs */ | 35 | std r8,STK_PARM(r8)(r1) /* Save out ptrs */ |
@@ -53,6 +55,8 @@ _GLOBAL(plpar_hcall) | |||
53 | 55 | ||
54 | /* Simple interface with no output values (other than status) */ | 56 | /* Simple interface with no output values (other than status) */ |
55 | _GLOBAL(plpar_hcall_norets) | 57 | _GLOBAL(plpar_hcall_norets) |
58 | HMT_MEDIUM | ||
59 | |||
56 | mfcr r0 | 60 | mfcr r0 |
57 | stw r0,8(r1) | 61 | stw r0,8(r1) |
58 | 62 | ||
@@ -75,6 +79,8 @@ _GLOBAL(plpar_hcall_norets) | |||
75 | unsigned long *out1); 120(R1) | 79 | unsigned long *out1); 120(R1) |
76 | */ | 80 | */ |
77 | _GLOBAL(plpar_hcall_8arg_2ret) | 81 | _GLOBAL(plpar_hcall_8arg_2ret) |
82 | HMT_MEDIUM | ||
83 | |||
78 | mfcr r0 | 84 | mfcr r0 |
79 | ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ | 85 | ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ |
80 | stw r0,8(r1) | 86 | stw r0,8(r1) |
@@ -99,6 +105,8 @@ _GLOBAL(plpar_hcall_8arg_2ret) | |||
99 | unsigned long *out4); 112(R1) | 105 | unsigned long *out4); 112(R1) |
100 | */ | 106 | */ |
101 | _GLOBAL(plpar_hcall_4out) | 107 | _GLOBAL(plpar_hcall_4out) |
108 | HMT_MEDIUM | ||
109 | |||
102 | mfcr r0 | 110 | mfcr r0 |
103 | stw r0,8(r1) | 111 | stw r0,8(r1) |
104 | 112 | ||
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 45a4ad08fbc2..fe2946c58314 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -321,6 +321,10 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
321 | char *name = get_property(ic->parent, "name", NULL); | 321 | char *name = get_property(ic->parent, "name", NULL); |
322 | if (name && !strcmp(name, "u3")) | 322 | if (name && !strcmp(name, "u3")) |
323 | np->intrs[intrcount].line += 128; | 323 | np->intrs[intrcount].line += 128; |
324 | else if (!(name && !strcmp(name, "mac-io"))) | ||
325 | /* ignore other cascaded controllers, such as | ||
326 | the k2-sata-root */ | ||
327 | break; | ||
324 | } | 328 | } |
325 | np->intrs[intrcount].sense = 1; | 329 | np->intrs[intrcount].sense = 1; |
326 | if (n > 1) | 330 | if (n > 1) |
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 8dffa9ae2623..35ec42de962e 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c | |||
@@ -493,6 +493,113 @@ static void __init early_cmdline_parse(void) | |||
493 | } | 493 | } |
494 | 494 | ||
495 | /* | 495 | /* |
496 | * To tell the firmware what our capabilities are, we have to pass | ||
497 | * it a fake 32-bit ELF header containing a couple of PT_NOTE sections | ||
498 | * that contain structures that contain the actual values. | ||
499 | */ | ||
500 | static struct fake_elf { | ||
501 | Elf32_Ehdr elfhdr; | ||
502 | Elf32_Phdr phdr[2]; | ||
503 | struct chrpnote { | ||
504 | u32 namesz; | ||
505 | u32 descsz; | ||
506 | u32 type; | ||
507 | char name[8]; /* "PowerPC" */ | ||
508 | struct chrpdesc { | ||
509 | u32 real_mode; | ||
510 | u32 real_base; | ||
511 | u32 real_size; | ||
512 | u32 virt_base; | ||
513 | u32 virt_size; | ||
514 | u32 load_base; | ||
515 | } chrpdesc; | ||
516 | } chrpnote; | ||
517 | struct rpanote { | ||
518 | u32 namesz; | ||
519 | u32 descsz; | ||
520 | u32 type; | ||
521 | char name[24]; /* "IBM,RPA-Client-Config" */ | ||
522 | struct rpadesc { | ||
523 | u32 lpar_affinity; | ||
524 | u32 min_rmo_size; | ||
525 | u32 min_rmo_percent; | ||
526 | u32 max_pft_size; | ||
527 | u32 splpar; | ||
528 | u32 min_load; | ||
529 | u32 new_mem_def; | ||
530 | u32 ignore_me; | ||
531 | } rpadesc; | ||
532 | } rpanote; | ||
533 | } fake_elf = { | ||
534 | .elfhdr = { | ||
535 | .e_ident = { 0x7f, 'E', 'L', 'F', | ||
536 | ELFCLASS32, ELFDATA2MSB, EV_CURRENT }, | ||
537 | .e_type = ET_EXEC, /* yeah right */ | ||
538 | .e_machine = EM_PPC, | ||
539 | .e_version = EV_CURRENT, | ||
540 | .e_phoff = offsetof(struct fake_elf, phdr), | ||
541 | .e_phentsize = sizeof(Elf32_Phdr), | ||
542 | .e_phnum = 2 | ||
543 | }, | ||
544 | .phdr = { | ||
545 | [0] = { | ||
546 | .p_type = PT_NOTE, | ||
547 | .p_offset = offsetof(struct fake_elf, chrpnote), | ||
548 | .p_filesz = sizeof(struct chrpnote) | ||
549 | }, [1] = { | ||
550 | .p_type = PT_NOTE, | ||
551 | .p_offset = offsetof(struct fake_elf, rpanote), | ||
552 | .p_filesz = sizeof(struct rpanote) | ||
553 | } | ||
554 | }, | ||
555 | .chrpnote = { | ||
556 | .namesz = sizeof("PowerPC"), | ||
557 | .descsz = sizeof(struct chrpdesc), | ||
558 | .type = 0x1275, | ||
559 | .name = "PowerPC", | ||
560 | .chrpdesc = { | ||
561 | .real_mode = ~0U, /* ~0 means "don't care" */ | ||
562 | .real_base = ~0U, | ||
563 | .real_size = ~0U, | ||
564 | .virt_base = ~0U, | ||
565 | .virt_size = ~0U, | ||
566 | .load_base = ~0U | ||
567 | }, | ||
568 | }, | ||
569 | .rpanote = { | ||
570 | .namesz = sizeof("IBM,RPA-Client-Config"), | ||
571 | .descsz = sizeof(struct rpadesc), | ||
572 | .type = 0x12759999, | ||
573 | .name = "IBM,RPA-Client-Config", | ||
574 | .rpadesc = { | ||
575 | .lpar_affinity = 0, | ||
576 | .min_rmo_size = 64, /* in megabytes */ | ||
577 | .min_rmo_percent = 0, | ||
578 | .max_pft_size = 48, /* 2^48 bytes max PFT size */ | ||
579 | .splpar = 1, | ||
580 | .min_load = ~0U, | ||
581 | .new_mem_def = 0 | ||
582 | } | ||
583 | } | ||
584 | }; | ||
585 | |||
586 | static void __init prom_send_capabilities(void) | ||
587 | { | ||
588 | unsigned long offset = reloc_offset(); | ||
589 | ihandle elfloader; | ||
590 | int ret; | ||
591 | |||
592 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); | ||
593 | if (elfloader == 0) { | ||
594 | prom_printf("couldn't open /packages/elf-loader\n"); | ||
595 | return; | ||
596 | } | ||
597 | ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), | ||
598 | elfloader, ADDR(&fake_elf)); | ||
599 | call_prom("close", 1, 0, elfloader); | ||
600 | } | ||
601 | |||
602 | /* | ||
496 | * Memory allocation strategy... our layout is normally: | 603 | * Memory allocation strategy... our layout is normally: |
497 | * | 604 | * |
498 | * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd | 605 | * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd |
@@ -1448,6 +1555,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
1448 | } | 1555 | } |
1449 | } | 1556 | } |
1450 | 1557 | ||
1558 | /* | ||
1559 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
1560 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
1561 | */ | ||
1562 | #define MAX_PROPERTY_NAME 64 | ||
1563 | |||
1451 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | 1564 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, |
1452 | unsigned long *mem_end) | 1565 | unsigned long *mem_end) |
1453 | { | 1566 | { |
@@ -1457,7 +1570,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1457 | unsigned long soff; | 1570 | unsigned long soff; |
1458 | unsigned char *valp; | 1571 | unsigned char *valp; |
1459 | unsigned long offset = reloc_offset(); | 1572 | unsigned long offset = reloc_offset(); |
1460 | char pname[32]; | 1573 | char pname[MAX_PROPERTY_NAME]; |
1461 | char *path; | 1574 | char *path; |
1462 | 1575 | ||
1463 | path = RELOC(prom_scratch); | 1576 | path = RELOC(prom_scratch); |
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c index 354a287c67eb..5a846324ca8c 100644 --- a/arch/ppc64/kernel/ptrace.c +++ b/arch/ppc64/kernel/ptrace.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
29 | #include <linux/audit.h> | 29 | #include <linux/audit.h> |
30 | #include <linux/seccomp.h> | 30 | #include <linux/seccomp.h> |
31 | #include <linux/signal.h> | ||
31 | 32 | ||
32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
33 | #include <asm/page.h> | 34 | #include <asm/page.h> |
@@ -162,7 +163,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
162 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 163 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
163 | case PTRACE_CONT: { /* restart after signal. */ | 164 | case PTRACE_CONT: { /* restart after signal. */ |
164 | ret = -EIO; | 165 | ret = -EIO; |
165 | if ((unsigned long) data > _NSIG) | 166 | if (!valid_signal(data)) |
166 | break; | 167 | break; |
167 | if (request == PTRACE_SYSCALL) | 168 | if (request == PTRACE_SYSCALL) |
168 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 169 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -194,7 +195,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
194 | 195 | ||
195 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 196 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
196 | ret = -EIO; | 197 | ret = -EIO; |
197 | if ((unsigned long) data > _NSIG) | 198 | if (!valid_signal(data)) |
198 | break; | 199 | break; |
199 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 200 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
200 | set_single_step(child); | 201 | set_single_step(child); |
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c index ee81b1b776cc..16436426c7e2 100644 --- a/arch/ppc64/kernel/ptrace32.c +++ b/arch/ppc64/kernel/ptrace32.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ptrace.h> | 26 | #include <linux/ptrace.h> |
27 | #include <linux/user.h> | 27 | #include <linux/user.h> |
28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
29 | #include <linux/signal.h> | ||
29 | 30 | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/page.h> | 32 | #include <asm/page.h> |
@@ -293,7 +294,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) | |||
293 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 294 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
294 | case PTRACE_CONT: { /* restart after signal. */ | 295 | case PTRACE_CONT: { /* restart after signal. */ |
295 | ret = -EIO; | 296 | ret = -EIO; |
296 | if ((unsigned long) data > _NSIG) | 297 | if (!valid_signal(data)) |
297 | break; | 298 | break; |
298 | if (request == PTRACE_SYSCALL) | 299 | if (request == PTRACE_SYSCALL) |
299 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 300 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -325,7 +326,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) | |||
325 | 326 | ||
326 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 327 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
327 | ret = -EIO; | 328 | ret = -EIO; |
328 | if ((unsigned long) data > _NSIG) | 329 | if (!valid_signal(data)) |
329 | break; | 330 | break; |
330 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 331 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
331 | set_single_step(child); | 332 | set_single_step(child); |
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c index b0e167db6af9..3c2fa5c284c0 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/ppc64/kernel/signal32.c | |||
@@ -657,7 +657,7 @@ static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
657 | 657 | ||
658 | /* Save user registers on the stack */ | 658 | /* Save user registers on the stack */ |
659 | frame = &rt_sf->uc.uc_mcontext; | 659 | frame = &rt_sf->uc.uc_mcontext; |
660 | if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) | 660 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
661 | goto badframe; | 661 | goto badframe; |
662 | 662 | ||
663 | if (vdso32_rt_sigtramp && current->thread.vdso_base) { | 663 | if (vdso32_rt_sigtramp && current->thread.vdso_base) { |
@@ -842,7 +842,7 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
842 | regs->link = (unsigned long) frame->mctx.tramp; | 842 | regs->link = (unsigned long) frame->mctx.tramp; |
843 | } | 843 | } |
844 | 844 | ||
845 | if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) | 845 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
846 | goto badframe; | 846 | goto badframe; |
847 | regs->gpr[1] = (unsigned long) newsp; | 847 | regs->gpr[1] = (unsigned long) newsp; |
848 | regs->gpr[3] = sig; | 848 | regs->gpr[3] = sig; |
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 1c92da3e4525..3b906cd94037 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c | |||
@@ -125,7 +125,7 @@ void __devinit smp_generic_kick_cpu(int nr) | |||
125 | * the processor will continue on to secondary_start | 125 | * the processor will continue on to secondary_start |
126 | */ | 126 | */ |
127 | paca[nr].cpu_start = 1; | 127 | paca[nr].cpu_start = 1; |
128 | mb(); | 128 | smp_mb(); |
129 | } | 129 | } |
130 | 130 | ||
131 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 131 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
@@ -256,7 +256,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | |||
256 | } | 256 | } |
257 | 257 | ||
258 | call_data = &data; | 258 | call_data = &data; |
259 | wmb(); | 259 | smp_wmb(); |
260 | /* Send a message to all other CPUs and wait for them to respond */ | 260 | /* Send a message to all other CPUs and wait for them to respond */ |
261 | smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); | 261 | smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); |
262 | 262 | ||
@@ -431,7 +431,7 @@ int generic_cpu_enable(unsigned int cpu) | |||
431 | 431 | ||
432 | /* get the target out of it's holding state */ | 432 | /* get the target out of it's holding state */ |
433 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | 433 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; |
434 | wmb(); | 434 | smp_wmb(); |
435 | 435 | ||
436 | while (!cpu_online(cpu)) | 436 | while (!cpu_online(cpu)) |
437 | cpu_relax(); | 437 | cpu_relax(); |
@@ -447,7 +447,7 @@ void generic_cpu_die(unsigned int cpu) | |||
447 | int i; | 447 | int i; |
448 | 448 | ||
449 | for (i = 0; i < 100; i++) { | 449 | for (i = 0; i < 100; i++) { |
450 | rmb(); | 450 | smp_rmb(); |
451 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) | 451 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) |
452 | return; | 452 | return; |
453 | msleep(100); | 453 | msleep(100); |
@@ -463,7 +463,7 @@ void generic_mach_cpu_die(void) | |||
463 | cpu = smp_processor_id(); | 463 | cpu = smp_processor_id(); |
464 | printk(KERN_DEBUG "CPU%d offline\n", cpu); | 464 | printk(KERN_DEBUG "CPU%d offline\n", cpu); |
465 | __get_cpu_var(cpu_state) = CPU_DEAD; | 465 | __get_cpu_var(cpu_state) = CPU_DEAD; |
466 | wmb(); | 466 | smp_wmb(); |
467 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) | 467 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) |
468 | cpu_relax(); | 468 | cpu_relax(); |
469 | 469 | ||
@@ -515,7 +515,7 @@ int __devinit __cpu_up(unsigned int cpu) | |||
515 | * be written out to main store before we release | 515 | * be written out to main store before we release |
516 | * the processor. | 516 | * the processor. |
517 | */ | 517 | */ |
518 | mb(); | 518 | smp_mb(); |
519 | 519 | ||
520 | /* wake up cpus */ | 520 | /* wake up cpus */ |
521 | DBG("smp: kicking cpu %d\n", cpu); | 521 | DBG("smp: kicking cpu %d\n", cpu); |
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 77ded5a363b6..772a465b49f9 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c | |||
@@ -221,15 +221,15 @@ static __inline__ void timer_recalc_offset(unsigned long cur_tb) | |||
221 | temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs; | 221 | temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs; |
222 | temp_varp->tb_orig_stamp = new_tb_orig_stamp; | 222 | temp_varp->tb_orig_stamp = new_tb_orig_stamp; |
223 | temp_varp->stamp_xsec = new_stamp_xsec; | 223 | temp_varp->stamp_xsec = new_stamp_xsec; |
224 | mb(); | 224 | smp_mb(); |
225 | do_gtod.varp = temp_varp; | 225 | do_gtod.varp = temp_varp; |
226 | do_gtod.var_idx = temp_idx; | 226 | do_gtod.var_idx = temp_idx; |
227 | 227 | ||
228 | ++(systemcfg->tb_update_count); | 228 | ++(systemcfg->tb_update_count); |
229 | wmb(); | 229 | smp_wmb(); |
230 | systemcfg->tb_orig_stamp = new_tb_orig_stamp; | 230 | systemcfg->tb_orig_stamp = new_tb_orig_stamp; |
231 | systemcfg->stamp_xsec = new_stamp_xsec; | 231 | systemcfg->stamp_xsec = new_stamp_xsec; |
232 | wmb(); | 232 | smp_wmb(); |
233 | ++(systemcfg->tb_update_count); | 233 | ++(systemcfg->tb_update_count); |
234 | } | 234 | } |
235 | 235 | ||
@@ -648,7 +648,7 @@ void ppc_adjtimex(void) | |||
648 | temp_varp->tb_to_xs = new_tb_to_xs; | 648 | temp_varp->tb_to_xs = new_tb_to_xs; |
649 | temp_varp->stamp_xsec = new_stamp_xsec; | 649 | temp_varp->stamp_xsec = new_stamp_xsec; |
650 | temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp; | 650 | temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp; |
651 | mb(); | 651 | smp_mb(); |
652 | do_gtod.varp = temp_varp; | 652 | do_gtod.varp = temp_varp; |
653 | do_gtod.var_idx = temp_idx; | 653 | do_gtod.var_idx = temp_idx; |
654 | 654 | ||
@@ -662,10 +662,10 @@ void ppc_adjtimex(void) | |||
662 | * loops back and reads them again until this criteria is met. | 662 | * loops back and reads them again until this criteria is met. |
663 | */ | 663 | */ |
664 | ++(systemcfg->tb_update_count); | 664 | ++(systemcfg->tb_update_count); |
665 | wmb(); | 665 | smp_wmb(); |
666 | systemcfg->tb_to_xs = new_tb_to_xs; | 666 | systemcfg->tb_to_xs = new_tb_to_xs; |
667 | systemcfg->stamp_xsec = new_stamp_xsec; | 667 | systemcfg->stamp_xsec = new_stamp_xsec; |
668 | wmb(); | 668 | smp_wmb(); |
669 | ++(systemcfg->tb_update_count); | 669 | ++(systemcfg->tb_update_count); |
670 | 670 | ||
671 | write_sequnlock_irqrestore( &xtime_lock, flags ); | 671 | write_sequnlock_irqrestore( &xtime_lock, flags ); |
diff --git a/arch/ppc64/kernel/vdso32/Makefile b/arch/ppc64/kernel/vdso32/Makefile index ede2f7e477c2..0b1b0df973eb 100644 --- a/arch/ppc64/kernel/vdso32/Makefile +++ b/arch/ppc64/kernel/vdso32/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | 1 | ||
2 | # List of files in the vdso, has to be asm only for now | 2 | # List of files in the vdso, has to be asm only for now |
3 | 3 | ||
4 | obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o | 4 | obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o |
5 | 5 | ||
6 | # Build rules | 6 | # Build rules |
7 | 7 | ||
diff --git a/arch/ppc64/kernel/vdso32/cacheflush.S b/arch/ppc64/kernel/vdso32/cacheflush.S index c74fddb6afd4..0ed7ea721715 100644 --- a/arch/ppc64/kernel/vdso32/cacheflush.S +++ b/arch/ppc64/kernel/vdso32/cacheflush.S | |||
@@ -47,6 +47,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
47 | addi r6,r6,128 | 47 | addi r6,r6,128 |
48 | bdnz 1b | 48 | bdnz 1b |
49 | isync | 49 | isync |
50 | li r3,0 | ||
50 | blr | 51 | blr |
51 | .cfi_endproc | 52 | .cfi_endproc |
52 | V_FUNCTION_END(__kernel_sync_dicache) | 53 | V_FUNCTION_END(__kernel_sync_dicache) |
@@ -59,6 +60,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | |||
59 | .cfi_startproc | 60 | .cfi_startproc |
60 | sync | 61 | sync |
61 | isync | 62 | isync |
63 | li r3,0 | ||
62 | blr | 64 | blr |
63 | .cfi_endproc | 65 | .cfi_endproc |
64 | V_FUNCTION_END(__kernel_sync_dicache_p5) | 66 | V_FUNCTION_END(__kernel_sync_dicache_p5) |
diff --git a/arch/ppc64/kernel/vdso32/gettimeofday.S b/arch/ppc64/kernel/vdso32/gettimeofday.S index ca7f415195c4..2b48bf1fb109 100644 --- a/arch/ppc64/kernel/vdso32/gettimeofday.S +++ b/arch/ppc64/kernel/vdso32/gettimeofday.S | |||
@@ -58,6 +58,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
58 | stw r5,TZONE_TZ_DSTTIME(r11) | 58 | stw r5,TZONE_TZ_DSTTIME(r11) |
59 | 59 | ||
60 | 1: mtlr r12 | 60 | 1: mtlr r12 |
61 | li r3,0 | ||
61 | blr | 62 | blr |
62 | 63 | ||
63 | 2: mr r3,r10 | 64 | 2: mr r3,r10 |
diff --git a/arch/ppc64/kernel/vdso32/note.S b/arch/ppc64/kernel/vdso32/note.S new file mode 100644 index 000000000000..d4b5be4f3d5f --- /dev/null +++ b/arch/ppc64/kernel/vdso32/note.S | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. | ||
3 | * Here we can supply some information useful to userland. | ||
4 | */ | ||
5 | |||
6 | #include <linux/uts.h> | ||
7 | #include <linux/version.h> | ||
8 | |||
9 | #define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type) \ | ||
10 | .section name, flags; \ | ||
11 | .balign 4; \ | ||
12 | .long 1f - 0f; /* name length */ \ | ||
13 | .long 3f - 2f; /* data length */ \ | ||
14 | .long type; /* note type */ \ | ||
15 | 0: .asciz vendor; /* vendor name */ \ | ||
16 | 1: .balign 4; \ | ||
17 | 2: | ||
18 | |||
19 | #define ASM_ELF_NOTE_END \ | ||
20 | 3: .balign 4; /* pad out section */ \ | ||
21 | .previous | ||
22 | |||
23 | ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0) | ||
24 | .long LINUX_VERSION_CODE | ||
25 | ASM_ELF_NOTE_END | ||
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S index cca27bd03a57..11290c902ba3 100644 --- a/arch/ppc64/kernel/vdso32/vdso32.lds.S +++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S | |||
@@ -20,6 +20,8 @@ SECTIONS | |||
20 | .gnu.version_d : { *(.gnu.version_d) } | 20 | .gnu.version_d : { *(.gnu.version_d) } |
21 | .gnu.version_r : { *(.gnu.version_r) } | 21 | .gnu.version_r : { *(.gnu.version_r) } |
22 | 22 | ||
23 | .note : { *(.note.*) } :text :note | ||
24 | |||
23 | . = ALIGN (16); | 25 | . = ALIGN (16); |
24 | .text : | 26 | .text : |
25 | { | 27 | { |
@@ -87,6 +89,7 @@ SECTIONS | |||
87 | PHDRS | 89 | PHDRS |
88 | { | 90 | { |
89 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ | 91 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ |
92 | note PT_NOTE FLAGS(4); /* PF_R */ | ||
90 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 93 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
91 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ | 94 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ |
92 | } | 95 | } |
diff --git a/arch/ppc64/kernel/vdso64/Makefile b/arch/ppc64/kernel/vdso64/Makefile index bd3f70b1a384..ab39988452cc 100644 --- a/arch/ppc64/kernel/vdso64/Makefile +++ b/arch/ppc64/kernel/vdso64/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # List of files in the vdso, has to be asm only for now | 1 | # List of files in the vdso, has to be asm only for now |
2 | 2 | ||
3 | obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o | 3 | obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o |
4 | 4 | ||
5 | # Build rules | 5 | # Build rules |
6 | 6 | ||
diff --git a/arch/ppc64/kernel/vdso64/cacheflush.S b/arch/ppc64/kernel/vdso64/cacheflush.S index d9696ffcf334..e0725b7b7003 100644 --- a/arch/ppc64/kernel/vdso64/cacheflush.S +++ b/arch/ppc64/kernel/vdso64/cacheflush.S | |||
@@ -47,6 +47,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
47 | addi r6,r6,128 | 47 | addi r6,r6,128 |
48 | bdnz 1b | 48 | bdnz 1b |
49 | isync | 49 | isync |
50 | li r3,0 | ||
50 | blr | 51 | blr |
51 | .cfi_endproc | 52 | .cfi_endproc |
52 | V_FUNCTION_END(__kernel_sync_dicache) | 53 | V_FUNCTION_END(__kernel_sync_dicache) |
@@ -59,6 +60,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | |||
59 | .cfi_startproc | 60 | .cfi_startproc |
60 | sync | 61 | sync |
61 | isync | 62 | isync |
63 | li r3,0 | ||
62 | blr | 64 | blr |
63 | .cfi_endproc | 65 | .cfi_endproc |
64 | V_FUNCTION_END(__kernel_sync_dicache_p5) | 66 | V_FUNCTION_END(__kernel_sync_dicache_p5) |
diff --git a/arch/ppc64/kernel/vdso64/note.S b/arch/ppc64/kernel/vdso64/note.S new file mode 100644 index 000000000000..dc2a509f7e8a --- /dev/null +++ b/arch/ppc64/kernel/vdso64/note.S | |||
@@ -0,0 +1 @@ | |||
#include "../vdso32/note.S" | |||
diff --git a/arch/ppc64/kernel/vdso64/vdso64.lds.S b/arch/ppc64/kernel/vdso64/vdso64.lds.S index 942c815c7bc7..9cb28181da80 100644 --- a/arch/ppc64/kernel/vdso64/vdso64.lds.S +++ b/arch/ppc64/kernel/vdso64/vdso64.lds.S | |||
@@ -18,12 +18,14 @@ SECTIONS | |||
18 | .gnu.version_d : { *(.gnu.version_d) } | 18 | .gnu.version_d : { *(.gnu.version_d) } |
19 | .gnu.version_r : { *(.gnu.version_r) } | 19 | .gnu.version_r : { *(.gnu.version_r) } |
20 | 20 | ||
21 | .note : { *(.note.*) } :text :note | ||
22 | |||
21 | . = ALIGN (16); | 23 | . = ALIGN (16); |
22 | .text : | 24 | .text : |
23 | { | 25 | { |
24 | *(.text .stub .text.* .gnu.linkonce.t.*) | 26 | *(.text .stub .text.* .gnu.linkonce.t.*) |
25 | *(.sfpr .glink) | 27 | *(.sfpr .glink) |
26 | } | 28 | } :text |
27 | PROVIDE (__etext = .); | 29 | PROVIDE (__etext = .); |
28 | PROVIDE (_etext = .); | 30 | PROVIDE (_etext = .); |
29 | PROVIDE (etext = .); | 31 | PROVIDE (etext = .); |
@@ -88,6 +90,7 @@ SECTIONS | |||
88 | PHDRS | 90 | PHDRS |
89 | { | 91 | { |
90 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ | 92 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ |
93 | note PT_NOTE FLAGS(4); /* PF_R */ | ||
91 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 94 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
92 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ | 95 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ |
93 | } | 96 | } |
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S index 8c0156a37001..c23d46956dd9 100644 --- a/arch/ppc64/mm/hash_low.S +++ b/arch/ppc64/mm/hash_low.S | |||
@@ -85,7 +85,10 @@ _GLOBAL(__hash_page) | |||
85 | bne- htab_wrong_access | 85 | bne- htab_wrong_access |
86 | /* Check if PTE is busy */ | 86 | /* Check if PTE is busy */ |
87 | andi. r0,r31,_PAGE_BUSY | 87 | andi. r0,r31,_PAGE_BUSY |
88 | bne- 1b | 88 | /* If so, just bail out and refault if needed. Someone else |
89 | * is changing this PTE anyway and might hash it. | ||
90 | */ | ||
91 | bne- bail_ok | ||
89 | /* Prepare new PTE value (turn access RW into DIRTY, then | 92 | /* Prepare new PTE value (turn access RW into DIRTY, then |
90 | * add BUSY,HASHPTE and ACCESSED) | 93 | * add BUSY,HASHPTE and ACCESSED) |
91 | */ | 94 | */ |
@@ -215,6 +218,10 @@ _GLOBAL(htab_call_hpte_remove) | |||
215 | /* Try all again */ | 218 | /* Try all again */ |
216 | b htab_insert_pte | 219 | b htab_insert_pte |
217 | 220 | ||
221 | bail_ok: | ||
222 | li r3,0 | ||
223 | b bail | ||
224 | |||
218 | htab_pte_insert_ok: | 225 | htab_pte_insert_ok: |
219 | /* Insert slot number & secondary bit in PTE */ | 226 | /* Insert slot number & secondary bit in PTE */ |
220 | rldimi r30,r3,12,63-15 | 227 | rldimi r30,r3,12,63-15 |
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index 390296efe3e0..d3bf86a5c1ad 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c | |||
@@ -42,7 +42,7 @@ static inline int hugepgd_index(unsigned long addr) | |||
42 | return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT; | 42 | return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT; |
43 | } | 43 | } |
44 | 44 | ||
45 | static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) | 45 | static pud_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) |
46 | { | 46 | { |
47 | int index; | 47 | int index; |
48 | 48 | ||
@@ -52,21 +52,21 @@ static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) | |||
52 | 52 | ||
53 | index = hugepgd_index(addr); | 53 | index = hugepgd_index(addr); |
54 | BUG_ON(index >= PTRS_PER_HUGEPGD); | 54 | BUG_ON(index >= PTRS_PER_HUGEPGD); |
55 | return mm->context.huge_pgdir + index; | 55 | return (pud_t *)(mm->context.huge_pgdir + index); |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline pte_t *hugepte_offset(pgd_t *dir, unsigned long addr) | 58 | static inline pte_t *hugepte_offset(pud_t *dir, unsigned long addr) |
59 | { | 59 | { |
60 | int index; | 60 | int index; |
61 | 61 | ||
62 | if (pgd_none(*dir)) | 62 | if (pud_none(*dir)) |
63 | return NULL; | 63 | return NULL; |
64 | 64 | ||
65 | index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE; | 65 | index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE; |
66 | return (pte_t *)pgd_page(*dir) + index; | 66 | return (pte_t *)pud_page(*dir) + index; |
67 | } | 67 | } |
68 | 68 | ||
69 | static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) | 69 | static pud_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) |
70 | { | 70 | { |
71 | BUG_ON(! in_hugepage_area(mm->context, addr)); | 71 | BUG_ON(! in_hugepage_area(mm->context, addr)); |
72 | 72 | ||
@@ -90,10 +90,9 @@ static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) | |||
90 | return hugepgd_offset(mm, addr); | 90 | return hugepgd_offset(mm, addr); |
91 | } | 91 | } |
92 | 92 | ||
93 | static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | 93 | static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr) |
94 | unsigned long addr) | ||
95 | { | 94 | { |
96 | if (! pgd_present(*dir)) { | 95 | if (! pud_present(*dir)) { |
97 | pte_t *new; | 96 | pte_t *new; |
98 | 97 | ||
99 | spin_unlock(&mm->page_table_lock); | 98 | spin_unlock(&mm->page_table_lock); |
@@ -104,7 +103,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | |||
104 | * Because we dropped the lock, we should re-check the | 103 | * Because we dropped the lock, we should re-check the |
105 | * entry, as somebody else could have populated it.. | 104 | * entry, as somebody else could have populated it.. |
106 | */ | 105 | */ |
107 | if (pgd_present(*dir)) { | 106 | if (pud_present(*dir)) { |
108 | if (new) | 107 | if (new) |
109 | kmem_cache_free(zero_cache, new); | 108 | kmem_cache_free(zero_cache, new); |
110 | } else { | 109 | } else { |
@@ -115,7 +114,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | |||
115 | ptepage = virt_to_page(new); | 114 | ptepage = virt_to_page(new); |
116 | ptepage->mapping = (void *) mm; | 115 | ptepage->mapping = (void *) mm; |
117 | ptepage->index = addr & HUGEPGDIR_MASK; | 116 | ptepage->index = addr & HUGEPGDIR_MASK; |
118 | pgd_populate(mm, dir, new); | 117 | pud_populate(mm, dir, new); |
119 | } | 118 | } |
120 | } | 119 | } |
121 | 120 | ||
@@ -124,28 +123,28 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | |||
124 | 123 | ||
125 | static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | 124 | static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) |
126 | { | 125 | { |
127 | pgd_t *pgd; | 126 | pud_t *pud; |
128 | 127 | ||
129 | BUG_ON(! in_hugepage_area(mm->context, addr)); | 128 | BUG_ON(! in_hugepage_area(mm->context, addr)); |
130 | 129 | ||
131 | pgd = hugepgd_offset(mm, addr); | 130 | pud = hugepgd_offset(mm, addr); |
132 | if (! pgd) | 131 | if (! pud) |
133 | return NULL; | 132 | return NULL; |
134 | 133 | ||
135 | return hugepte_offset(pgd, addr); | 134 | return hugepte_offset(pud, addr); |
136 | } | 135 | } |
137 | 136 | ||
138 | static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) | 137 | static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) |
139 | { | 138 | { |
140 | pgd_t *pgd; | 139 | pud_t *pud; |
141 | 140 | ||
142 | BUG_ON(! in_hugepage_area(mm->context, addr)); | 141 | BUG_ON(! in_hugepage_area(mm->context, addr)); |
143 | 142 | ||
144 | pgd = hugepgd_alloc(mm, addr); | 143 | pud = hugepgd_alloc(mm, addr); |
145 | if (! pgd) | 144 | if (! pud) |
146 | return NULL; | 145 | return NULL; |
147 | 146 | ||
148 | return hugepte_alloc(mm, pgd, addr); | 147 | return hugepte_alloc(mm, pud, addr); |
149 | } | 148 | } |
150 | 149 | ||
151 | static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, | 150 | static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, |
@@ -709,10 +708,10 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm) | |||
709 | 708 | ||
710 | /* cleanup any hugepte pages leftover */ | 709 | /* cleanup any hugepte pages leftover */ |
711 | for (i = 0; i < PTRS_PER_HUGEPGD; i++) { | 710 | for (i = 0; i < PTRS_PER_HUGEPGD; i++) { |
712 | pgd_t *pgd = pgdir + i; | 711 | pud_t *pud = (pud_t *)(pgdir + i); |
713 | 712 | ||
714 | if (! pgd_none(*pgd)) { | 713 | if (! pud_none(*pud)) { |
715 | pte_t *pte = (pte_t *)pgd_page(*pgd); | 714 | pte_t *pte = (pte_t *)pud_page(*pud); |
716 | struct page *ptepage = virt_to_page(pte); | 715 | struct page *ptepage = virt_to_page(pte); |
717 | 716 | ||
718 | ptepage->mapping = NULL; | 717 | ptepage->mapping = NULL; |
@@ -720,7 +719,7 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm) | |||
720 | BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE)); | 719 | BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE)); |
721 | kmem_cache_free(zero_cache, pte); | 720 | kmem_cache_free(zero_cache, pte); |
722 | } | 721 | } |
723 | pgd_clear(pgd); | 722 | pud_clear(pud); |
724 | } | 723 | } |
725 | 724 | ||
726 | BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE)); | 725 | BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE)); |
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index a7149b9fc35c..cf33d7ec2e29 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c | |||
@@ -136,14 +136,78 @@ void iounmap(volatile void __iomem *addr) | |||
136 | 136 | ||
137 | #else | 137 | #else |
138 | 138 | ||
139 | static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr, | ||
140 | unsigned long end) | ||
141 | { | ||
142 | pte_t *pte; | ||
143 | |||
144 | pte = pte_offset_kernel(pmd, addr); | ||
145 | do { | ||
146 | pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte); | ||
147 | WARN_ON(!pte_none(ptent) && !pte_present(ptent)); | ||
148 | } while (pte++, addr += PAGE_SIZE, addr != end); | ||
149 | } | ||
150 | |||
151 | static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr, | ||
152 | unsigned long end) | ||
153 | { | ||
154 | pmd_t *pmd; | ||
155 | unsigned long next; | ||
156 | |||
157 | pmd = pmd_offset(pud, addr); | ||
158 | do { | ||
159 | next = pmd_addr_end(addr, end); | ||
160 | if (pmd_none_or_clear_bad(pmd)) | ||
161 | continue; | ||
162 | unmap_im_area_pte(pmd, addr, next); | ||
163 | } while (pmd++, addr = next, addr != end); | ||
164 | } | ||
165 | |||
166 | static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr, | ||
167 | unsigned long end) | ||
168 | { | ||
169 | pud_t *pud; | ||
170 | unsigned long next; | ||
171 | |||
172 | pud = pud_offset(pgd, addr); | ||
173 | do { | ||
174 | next = pud_addr_end(addr, end); | ||
175 | if (pud_none_or_clear_bad(pud)) | ||
176 | continue; | ||
177 | unmap_im_area_pmd(pud, addr, next); | ||
178 | } while (pud++, addr = next, addr != end); | ||
179 | } | ||
180 | |||
181 | static void unmap_im_area(unsigned long addr, unsigned long end) | ||
182 | { | ||
183 | struct mm_struct *mm = &ioremap_mm; | ||
184 | unsigned long next; | ||
185 | pgd_t *pgd; | ||
186 | |||
187 | spin_lock(&mm->page_table_lock); | ||
188 | |||
189 | pgd = pgd_offset_i(addr); | ||
190 | flush_cache_vunmap(addr, end); | ||
191 | do { | ||
192 | next = pgd_addr_end(addr, end); | ||
193 | if (pgd_none_or_clear_bad(pgd)) | ||
194 | continue; | ||
195 | unmap_im_area_pud(pgd, addr, next); | ||
196 | } while (pgd++, addr = next, addr != end); | ||
197 | flush_tlb_kernel_range(start, end); | ||
198 | |||
199 | spin_unlock(&mm->page_table_lock); | ||
200 | } | ||
201 | |||
139 | /* | 202 | /* |
140 | * map_io_page currently only called by __ioremap | 203 | * map_io_page currently only called by __ioremap |
141 | * map_io_page adds an entry to the ioremap page table | 204 | * map_io_page adds an entry to the ioremap page table |
142 | * and adds an entry to the HPT, possibly bolting it | 205 | * and adds an entry to the HPT, possibly bolting it |
143 | */ | 206 | */ |
144 | static void map_io_page(unsigned long ea, unsigned long pa, int flags) | 207 | static int map_io_page(unsigned long ea, unsigned long pa, int flags) |
145 | { | 208 | { |
146 | pgd_t *pgdp; | 209 | pgd_t *pgdp; |
210 | pud_t *pudp; | ||
147 | pmd_t *pmdp; | 211 | pmd_t *pmdp; |
148 | pte_t *ptep; | 212 | pte_t *ptep; |
149 | unsigned long vsid; | 213 | unsigned long vsid; |
@@ -151,9 +215,15 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags) | |||
151 | if (mem_init_done) { | 215 | if (mem_init_done) { |
152 | spin_lock(&ioremap_mm.page_table_lock); | 216 | spin_lock(&ioremap_mm.page_table_lock); |
153 | pgdp = pgd_offset_i(ea); | 217 | pgdp = pgd_offset_i(ea); |
154 | pmdp = pmd_alloc(&ioremap_mm, pgdp, ea); | 218 | pudp = pud_alloc(&ioremap_mm, pgdp, ea); |
219 | if (!pudp) | ||
220 | return -ENOMEM; | ||
221 | pmdp = pmd_alloc(&ioremap_mm, pudp, ea); | ||
222 | if (!pmdp) | ||
223 | return -ENOMEM; | ||
155 | ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); | 224 | ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); |
156 | 225 | if (!ptep) | |
226 | return -ENOMEM; | ||
157 | pa = abs_to_phys(pa); | 227 | pa = abs_to_phys(pa); |
158 | set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, | 228 | set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, |
159 | __pgprot(flags))); | 229 | __pgprot(flags))); |
@@ -181,6 +251,7 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags) | |||
181 | panic("map_io_page: could not insert mapping"); | 251 | panic("map_io_page: could not insert mapping"); |
182 | } | 252 | } |
183 | } | 253 | } |
254 | return 0; | ||
184 | } | 255 | } |
185 | 256 | ||
186 | 257 | ||
@@ -194,9 +265,14 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, | |||
194 | flags |= pgprot_val(PAGE_KERNEL); | 265 | flags |= pgprot_val(PAGE_KERNEL); |
195 | 266 | ||
196 | for (i = 0; i < size; i += PAGE_SIZE) | 267 | for (i = 0; i < size; i += PAGE_SIZE) |
197 | map_io_page(ea+i, pa+i, flags); | 268 | if (map_io_page(ea+i, pa+i, flags)) |
269 | goto failure; | ||
198 | 270 | ||
199 | return (void __iomem *) (ea + (addr & ~PAGE_MASK)); | 271 | return (void __iomem *) (ea + (addr & ~PAGE_MASK)); |
272 | failure: | ||
273 | if (mem_init_done) | ||
274 | unmap_im_area(ea, ea + size); | ||
275 | return NULL; | ||
200 | } | 276 | } |
201 | 277 | ||
202 | 278 | ||
@@ -206,10 +282,11 @@ ioremap(unsigned long addr, unsigned long size) | |||
206 | return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); | 282 | return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); |
207 | } | 283 | } |
208 | 284 | ||
209 | void __iomem * | 285 | void __iomem * __ioremap(unsigned long addr, unsigned long size, |
210 | __ioremap(unsigned long addr, unsigned long size, unsigned long flags) | 286 | unsigned long flags) |
211 | { | 287 | { |
212 | unsigned long pa, ea; | 288 | unsigned long pa, ea; |
289 | void __iomem *ret; | ||
213 | 290 | ||
214 | /* | 291 | /* |
215 | * Choose an address to map it to. | 292 | * Choose an address to map it to. |
@@ -232,12 +309,16 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) | |||
232 | if (area == NULL) | 309 | if (area == NULL) |
233 | return NULL; | 310 | return NULL; |
234 | ea = (unsigned long)(area->addr); | 311 | ea = (unsigned long)(area->addr); |
312 | ret = __ioremap_com(addr, pa, ea, size, flags); | ||
313 | if (!ret) | ||
314 | im_free(area->addr); | ||
235 | } else { | 315 | } else { |
236 | ea = ioremap_bot; | 316 | ea = ioremap_bot; |
237 | ioremap_bot += size; | 317 | ret = __ioremap_com(addr, pa, ea, size, flags); |
318 | if (ret) | ||
319 | ioremap_bot += size; | ||
238 | } | 320 | } |
239 | 321 | return ret; | |
240 | return __ioremap_com(addr, pa, ea, size, flags); | ||
241 | } | 322 | } |
242 | 323 | ||
243 | #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) | 324 | #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) |
@@ -246,6 +327,7 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, | |||
246 | unsigned long size, unsigned long flags) | 327 | unsigned long size, unsigned long flags) |
247 | { | 328 | { |
248 | struct vm_struct *area; | 329 | struct vm_struct *area; |
330 | void __iomem *ret; | ||
249 | 331 | ||
250 | /* For now, require page-aligned values for pa, ea, and size */ | 332 | /* For now, require page-aligned values for pa, ea, and size */ |
251 | if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) || | 333 | if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) || |
@@ -276,7 +358,12 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, | |||
276 | } | 358 | } |
277 | } | 359 | } |
278 | 360 | ||
279 | if (__ioremap_com(pa, pa, ea, size, flags) != (void *) ea) { | 361 | ret = __ioremap_com(pa, pa, ea, size, flags); |
362 | if (ret == NULL) { | ||
363 | printk(KERN_ERR "ioremap_explicit() allocation failure !\n"); | ||
364 | return 1; | ||
365 | } | ||
366 | if (ret != (void *) ea) { | ||
280 | printk(KERN_ERR "__ioremap_com() returned unexpected addr\n"); | 367 | printk(KERN_ERR "__ioremap_com() returned unexpected addr\n"); |
281 | return 1; | 368 | return 1; |
282 | } | 369 | } |
@@ -284,69 +371,6 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, | |||
284 | return 0; | 371 | return 0; |
285 | } | 372 | } |
286 | 373 | ||
287 | static void unmap_im_area_pte(pmd_t *pmd, unsigned long address, | ||
288 | unsigned long size) | ||
289 | { | ||
290 | unsigned long base, end; | ||
291 | pte_t *pte; | ||
292 | |||
293 | if (pmd_none(*pmd)) | ||
294 | return; | ||
295 | if (pmd_bad(*pmd)) { | ||
296 | pmd_ERROR(*pmd); | ||
297 | pmd_clear(pmd); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | pte = pte_offset_kernel(pmd, address); | ||
302 | base = address & PMD_MASK; | ||
303 | address &= ~PMD_MASK; | ||
304 | end = address + size; | ||
305 | if (end > PMD_SIZE) | ||
306 | end = PMD_SIZE; | ||
307 | |||
308 | do { | ||
309 | pte_t page; | ||
310 | page = ptep_get_and_clear(&ioremap_mm, base + address, pte); | ||
311 | address += PAGE_SIZE; | ||
312 | pte++; | ||
313 | if (pte_none(page)) | ||
314 | continue; | ||
315 | if (pte_present(page)) | ||
316 | continue; | ||
317 | printk(KERN_CRIT "Whee.. Swapped out page in kernel page" | ||
318 | " table\n"); | ||
319 | } while (address < end); | ||
320 | } | ||
321 | |||
322 | static void unmap_im_area_pmd(pgd_t *dir, unsigned long address, | ||
323 | unsigned long size) | ||
324 | { | ||
325 | unsigned long base, end; | ||
326 | pmd_t *pmd; | ||
327 | |||
328 | if (pgd_none(*dir)) | ||
329 | return; | ||
330 | if (pgd_bad(*dir)) { | ||
331 | pgd_ERROR(*dir); | ||
332 | pgd_clear(dir); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | pmd = pmd_offset(dir, address); | ||
337 | base = address & PGDIR_MASK; | ||
338 | address &= ~PGDIR_MASK; | ||
339 | end = address + size; | ||
340 | if (end > PGDIR_SIZE) | ||
341 | end = PGDIR_SIZE; | ||
342 | |||
343 | do { | ||
344 | unmap_im_area_pte(pmd, base + address, end - address); | ||
345 | address = (address + PMD_SIZE) & PMD_MASK; | ||
346 | pmd++; | ||
347 | } while (address < end); | ||
348 | } | ||
349 | |||
350 | /* | 374 | /* |
351 | * Unmap an IO region and remove it from imalloc'd list. | 375 | * Unmap an IO region and remove it from imalloc'd list. |
352 | * Access to IO memory should be serialized by driver. | 376 | * Access to IO memory should be serialized by driver. |
@@ -356,39 +380,19 @@ static void unmap_im_area_pmd(pgd_t *dir, unsigned long address, | |||
356 | */ | 380 | */ |
357 | void iounmap(volatile void __iomem *token) | 381 | void iounmap(volatile void __iomem *token) |
358 | { | 382 | { |
359 | unsigned long address, start, end, size; | 383 | unsigned long address, size; |
360 | struct mm_struct *mm; | ||
361 | pgd_t *dir; | ||
362 | void *addr; | 384 | void *addr; |
363 | 385 | ||
364 | if (!mem_init_done) { | 386 | if (!mem_init_done) |
365 | return; | 387 | return; |
366 | } | ||
367 | 388 | ||
368 | addr = (void *) ((unsigned long __force) token & PAGE_MASK); | 389 | addr = (void *) ((unsigned long __force) token & PAGE_MASK); |
369 | 390 | ||
370 | if ((size = im_free(addr)) == 0) { | 391 | if ((size = im_free(addr)) == 0) |
371 | return; | 392 | return; |
372 | } | ||
373 | 393 | ||
374 | address = (unsigned long)addr; | 394 | address = (unsigned long)addr; |
375 | start = address; | 395 | unmap_im_area(address, address + size); |
376 | end = address + size; | ||
377 | |||
378 | mm = &ioremap_mm; | ||
379 | spin_lock(&mm->page_table_lock); | ||
380 | |||
381 | dir = pgd_offset_i(address); | ||
382 | flush_cache_vunmap(address, end); | ||
383 | do { | ||
384 | unmap_im_area_pmd(dir, address, end - address); | ||
385 | address = (address + PGDIR_SIZE) & PGDIR_MASK; | ||
386 | dir++; | ||
387 | } while (address && (address < end)); | ||
388 | flush_tlb_kernel_range(start, end); | ||
389 | |||
390 | spin_unlock(&mm->page_table_lock); | ||
391 | return; | ||
392 | } | 396 | } |
393 | 397 | ||
394 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) | 398 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) |
diff --git a/arch/ppc64/mm/slb.c b/arch/ppc64/mm/slb.c index 6a20773f695d..244150a0bc18 100644 --- a/arch/ppc64/mm/slb.c +++ b/arch/ppc64/mm/slb.c | |||
@@ -33,8 +33,8 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags) | |||
33 | return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; | 33 | return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; |
34 | } | 34 | } |
35 | 35 | ||
36 | static inline void create_slbe(unsigned long ea, unsigned long vsid, | 36 | static inline void create_slbe(unsigned long ea, unsigned long flags, |
37 | unsigned long flags, unsigned long entry) | 37 | unsigned long entry) |
38 | { | 38 | { |
39 | asm volatile("slbmte %0,%1" : | 39 | asm volatile("slbmte %0,%1" : |
40 | : "r" (mk_vsid_data(ea, flags)), | 40 | : "r" (mk_vsid_data(ea, flags)), |
@@ -145,9 +145,8 @@ void slb_initialize(void) | |||
145 | asm volatile("isync":::"memory"); | 145 | asm volatile("isync":::"memory"); |
146 | asm volatile("slbmte %0,%0"::"r" (0) : "memory"); | 146 | asm volatile("slbmte %0,%0"::"r" (0) : "memory"); |
147 | asm volatile("isync; slbia; isync":::"memory"); | 147 | asm volatile("isync; slbia; isync":::"memory"); |
148 | create_slbe(KERNELBASE, get_kernel_vsid(KERNELBASE), flags, 0); | 148 | create_slbe(KERNELBASE, flags, 0); |
149 | create_slbe(VMALLOCBASE, get_kernel_vsid(KERNELBASE), | 149 | create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1); |
150 | SLB_VSID_KERNEL, 1); | ||
151 | /* We don't bolt the stack for the time being - we're in boot, | 150 | /* We don't bolt the stack for the time being - we're in boot, |
152 | * so the stack is in the bolted segment. By the time it goes | 151 | * so the stack is in the bolted segment. By the time it goes |
153 | * elsewhere, we'll call _switch() which will bolt in the new | 152 | * elsewhere, we'll call _switch() which will bolt in the new |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 1358b4201701..07fd0414a4bf 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11 | 3 | # Linux kernel version: 2.6.12-rc3 |
4 | # Wed Mar 2 16:57:55 2005 | 4 | # Fri Apr 22 15:30:58 2005 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
@@ -15,6 +15,7 @@ CONFIG_UID16=y | |||
15 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
16 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
17 | CONFIG_LOCK_KERNEL=y | 17 | CONFIG_LOCK_KERNEL=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
18 | 19 | ||
19 | # | 20 | # |
20 | # General setup | 21 | # General setup |
@@ -26,24 +27,25 @@ CONFIG_SYSVIPC=y | |||
26 | # CONFIG_BSD_PROCESS_ACCT is not set | 27 | # CONFIG_BSD_PROCESS_ACCT is not set |
27 | CONFIG_SYSCTL=y | 28 | CONFIG_SYSCTL=y |
28 | # CONFIG_AUDIT is not set | 29 | # CONFIG_AUDIT is not set |
29 | CONFIG_LOG_BUF_SHIFT=17 | ||
30 | CONFIG_HOTPLUG=y | 30 | CONFIG_HOTPLUG=y |
31 | CONFIG_KOBJECT_UEVENT=y | 31 | CONFIG_KOBJECT_UEVENT=y |
32 | CONFIG_IKCONFIG=y | 32 | CONFIG_IKCONFIG=y |
33 | CONFIG_IKCONFIG_PROC=y | 33 | CONFIG_IKCONFIG_PROC=y |
34 | # CONFIG_CPUSETS is not set | ||
34 | # CONFIG_EMBEDDED is not set | 35 | # CONFIG_EMBEDDED is not set |
35 | CONFIG_KALLSYMS=y | 36 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 37 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
39 | CONFIG_BASE_FULL=y | ||
38 | CONFIG_FUTEX=y | 40 | CONFIG_FUTEX=y |
39 | CONFIG_EPOLL=y | 41 | CONFIG_EPOLL=y |
40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
41 | CONFIG_SHMEM=y | 42 | CONFIG_SHMEM=y |
42 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 43 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
43 | CONFIG_CC_ALIGN_LABELS=0 | 44 | CONFIG_CC_ALIGN_LABELS=0 |
44 | CONFIG_CC_ALIGN_LOOPS=0 | 45 | CONFIG_CC_ALIGN_LOOPS=0 |
45 | CONFIG_CC_ALIGN_JUMPS=0 | 46 | CONFIG_CC_ALIGN_JUMPS=0 |
46 | # CONFIG_TINY_SHMEM is not set | 47 | # CONFIG_TINY_SHMEM is not set |
48 | CONFIG_BASE_SMALL=0 | ||
47 | 49 | ||
48 | # | 50 | # |
49 | # Loadable module support | 51 | # Loadable module support |
@@ -261,7 +263,6 @@ CONFIG_NET=y | |||
261 | # | 263 | # |
262 | CONFIG_PACKET=y | 264 | CONFIG_PACKET=y |
263 | # CONFIG_PACKET_MMAP is not set | 265 | # CONFIG_PACKET_MMAP is not set |
264 | # CONFIG_NETLINK_DEV is not set | ||
265 | CONFIG_UNIX=y | 266 | CONFIG_UNIX=y |
266 | CONFIG_NET_KEY=y | 267 | CONFIG_NET_KEY=y |
267 | CONFIG_INET=y | 268 | CONFIG_INET=y |
@@ -329,6 +330,7 @@ CONFIG_NET_SCH_DSMARK=m | |||
329 | CONFIG_NET_QOS=y | 330 | CONFIG_NET_QOS=y |
330 | CONFIG_NET_ESTIMATOR=y | 331 | CONFIG_NET_ESTIMATOR=y |
331 | CONFIG_NET_CLS=y | 332 | CONFIG_NET_CLS=y |
333 | # CONFIG_NET_CLS_BASIC is not set | ||
332 | CONFIG_NET_CLS_TCINDEX=m | 334 | CONFIG_NET_CLS_TCINDEX=m |
333 | CONFIG_NET_CLS_ROUTE4=m | 335 | CONFIG_NET_CLS_ROUTE4=m |
334 | CONFIG_NET_CLS_ROUTE=y | 336 | CONFIG_NET_CLS_ROUTE=y |
@@ -338,6 +340,7 @@ CONFIG_NET_CLS_U32=m | |||
338 | # CONFIG_NET_CLS_IND is not set | 340 | # CONFIG_NET_CLS_IND is not set |
339 | CONFIG_NET_CLS_RSVP=m | 341 | CONFIG_NET_CLS_RSVP=m |
340 | CONFIG_NET_CLS_RSVP6=m | 342 | CONFIG_NET_CLS_RSVP6=m |
343 | # CONFIG_NET_EMATCH is not set | ||
341 | # CONFIG_NET_CLS_ACT is not set | 344 | # CONFIG_NET_CLS_ACT is not set |
342 | CONFIG_NET_CLS_POLICE=y | 345 | CONFIG_NET_CLS_POLICE=y |
343 | 346 | ||
@@ -393,6 +396,8 @@ CONFIG_CTC=m | |||
393 | CONFIG_IUCV=m | 396 | CONFIG_IUCV=m |
394 | # CONFIG_NETIUCV is not set | 397 | # CONFIG_NETIUCV is not set |
395 | # CONFIG_SMSGIUCV is not set | 398 | # CONFIG_SMSGIUCV is not set |
399 | # CONFIG_CLAW is not set | ||
400 | # CONFIG_MPC is not set | ||
396 | CONFIG_QETH=y | 401 | CONFIG_QETH=y |
397 | 402 | ||
398 | # | 403 | # |
@@ -532,10 +537,13 @@ CONFIG_MSDOS_PARTITION=y | |||
532 | # | 537 | # |
533 | # Kernel hacking | 538 | # Kernel hacking |
534 | # | 539 | # |
540 | # CONFIG_PRINTK_TIME is not set | ||
535 | CONFIG_DEBUG_KERNEL=y | 541 | CONFIG_DEBUG_KERNEL=y |
536 | CONFIG_MAGIC_SYSRQ=y | 542 | CONFIG_MAGIC_SYSRQ=y |
543 | CONFIG_LOG_BUF_SHIFT=17 | ||
537 | # CONFIG_SCHEDSTATS is not set | 544 | # CONFIG_SCHEDSTATS is not set |
538 | # CONFIG_DEBUG_SLAB is not set | 545 | # CONFIG_DEBUG_SLAB is not set |
546 | # CONFIG_DEBUG_SPINLOCK is not set | ||
539 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 547 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
540 | # CONFIG_DEBUG_KOBJECT is not set | 548 | # CONFIG_DEBUG_KOBJECT is not set |
541 | # CONFIG_DEBUG_INFO is not set | 549 | # CONFIG_DEBUG_INFO is not set |
@@ -560,6 +568,7 @@ CONFIG_CRYPTO=y | |||
560 | # CONFIG_CRYPTO_SHA256 is not set | 568 | # CONFIG_CRYPTO_SHA256 is not set |
561 | # CONFIG_CRYPTO_SHA512 is not set | 569 | # CONFIG_CRYPTO_SHA512 is not set |
562 | # CONFIG_CRYPTO_WP512 is not set | 570 | # CONFIG_CRYPTO_WP512 is not set |
571 | # CONFIG_CRYPTO_TGR192 is not set | ||
563 | # CONFIG_CRYPTO_DES is not set | 572 | # CONFIG_CRYPTO_DES is not set |
564 | # CONFIG_CRYPTO_DES_Z990 is not set | 573 | # CONFIG_CRYPTO_DES_Z990 is not set |
565 | # CONFIG_CRYPTO_BLOWFISH is not set | 574 | # CONFIG_CRYPTO_BLOWFISH is not set |
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c index 96571ff7115d..03d03c6d3cbb 100644 --- a/arch/s390/kernel/compat_ioctl.c +++ b/arch/s390/kernel/compat_ioctl.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #define CODE | 16 | #define CODE |
17 | #include "../../../fs/compat_ioctl.c" | 17 | #include "../../../fs/compat_ioctl.c" |
18 | #include <asm/dasd.h> | 18 | #include <asm/dasd.h> |
19 | #include <asm/cmb.h> | ||
19 | #include <asm/tape390.h> | 20 | #include <asm/tape390.h> |
20 | 21 | ||
21 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, | 22 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, |
@@ -58,7 +59,11 @@ COMPATIBLE_IOCTL(BIODASDPRRD) | |||
58 | COMPATIBLE_IOCTL(BIODASDPSRD) | 59 | COMPATIBLE_IOCTL(BIODASDPSRD) |
59 | COMPATIBLE_IOCTL(BIODASDGATTR) | 60 | COMPATIBLE_IOCTL(BIODASDGATTR) |
60 | COMPATIBLE_IOCTL(BIODASDSATTR) | 61 | COMPATIBLE_IOCTL(BIODASDSATTR) |
61 | 62 | #if defined(CONFIG_DASD_CMB) || defined(CONFIG_DASD_CMB_MODULE) | |
63 | COMPATIBLE_IOCTL(BIODASDCMFENABLE) | ||
64 | COMPATIBLE_IOCTL(BIODASDCMFDISABLE) | ||
65 | COMPATIBLE_IOCTL(BIODASDREADALLCMB) | ||
66 | #endif | ||
62 | #endif | 67 | #endif |
63 | 68 | ||
64 | #if defined(CONFIG_S390_TAPE) || defined(CONFIG_S390_TAPE_MODULE) | 69 | #if defined(CONFIG_S390_TAPE) || defined(CONFIG_S390_TAPE_MODULE) |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 647233c02fc8..9f0d73e3f5f7 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/user.h> | 32 | #include <linux/user.h> |
33 | #include <linux/security.h> | 33 | #include <linux/security.h> |
34 | #include <linux/audit.h> | 34 | #include <linux/audit.h> |
35 | #include <linux/signal.h> | ||
35 | 36 | ||
36 | #include <asm/segment.h> | 37 | #include <asm/segment.h> |
37 | #include <asm/page.h> | 38 | #include <asm/page.h> |
@@ -609,7 +610,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) | |||
609 | /* continue and stop at next (return from) syscall */ | 610 | /* continue and stop at next (return from) syscall */ |
610 | case PTRACE_CONT: | 611 | case PTRACE_CONT: |
611 | /* restart after signal. */ | 612 | /* restart after signal. */ |
612 | if ((unsigned long) data >= _NSIG) | 613 | if (!valid_signal(data)) |
613 | return -EIO; | 614 | return -EIO; |
614 | if (request == PTRACE_SYSCALL) | 615 | if (request == PTRACE_SYSCALL) |
615 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 616 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -637,7 +638,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) | |||
637 | 638 | ||
638 | case PTRACE_SINGLESTEP: | 639 | case PTRACE_SINGLESTEP: |
639 | /* set the trap flag. */ | 640 | /* set the trap flag. */ |
640 | if ((unsigned long) data >= _NSIG) | 641 | if (!valid_signal(data)) |
641 | return -EIO; | 642 | return -EIO; |
642 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 643 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
643 | child->exit_code = data; | 644 | child->exit_code = data; |
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 11fd6d556d8f..bee654abb6d3 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c | |||
@@ -34,7 +34,6 @@ EXPORT_SYMBOL(__clear_user_asm); | |||
34 | EXPORT_SYMBOL(__strncpy_from_user_asm); | 34 | EXPORT_SYMBOL(__strncpy_from_user_asm); |
35 | EXPORT_SYMBOL(__strnlen_user_asm); | 35 | EXPORT_SYMBOL(__strnlen_user_asm); |
36 | EXPORT_SYMBOL(diag10); | 36 | EXPORT_SYMBOL(diag10); |
37 | EXPORT_SYMBOL(default_storage_key); | ||
38 | 37 | ||
39 | /* | 38 | /* |
40 | * semaphore ops | 39 | * semaphore ops |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index c879c40aa7a5..df83215beac3 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -44,6 +44,8 @@ | |||
44 | #include <asm/cpcmd.h> | 44 | #include <asm/cpcmd.h> |
45 | #include <asm/lowcore.h> | 45 | #include <asm/lowcore.h> |
46 | #include <asm/irq.h> | 46 | #include <asm/irq.h> |
47 | #include <asm/page.h> | ||
48 | #include <asm/ptrace.h> | ||
47 | 49 | ||
48 | /* | 50 | /* |
49 | * Machine setup.. | 51 | * Machine setup.. |
@@ -53,13 +55,14 @@ unsigned int console_devno = -1; | |||
53 | unsigned int console_irq = -1; | 55 | unsigned int console_irq = -1; |
54 | unsigned long memory_size = 0; | 56 | unsigned long memory_size = 0; |
55 | unsigned long machine_flags = 0; | 57 | unsigned long machine_flags = 0; |
56 | unsigned int default_storage_key = 0; | ||
57 | struct { | 58 | struct { |
58 | unsigned long addr, size, type; | 59 | unsigned long addr, size, type; |
59 | } memory_chunk[MEMORY_CHUNKS] = { { 0 } }; | 60 | } memory_chunk[MEMORY_CHUNKS] = { { 0 } }; |
60 | #define CHUNK_READ_WRITE 0 | 61 | #define CHUNK_READ_WRITE 0 |
61 | #define CHUNK_READ_ONLY 1 | 62 | #define CHUNK_READ_ONLY 1 |
62 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ | 63 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ |
64 | unsigned long __initdata zholes_size[MAX_NR_ZONES]; | ||
65 | static unsigned long __initdata memory_end; | ||
63 | 66 | ||
64 | /* | 67 | /* |
65 | * Setup options | 68 | * Setup options |
@@ -78,11 +81,15 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; | |||
78 | 81 | ||
79 | static struct resource code_resource = { | 82 | static struct resource code_resource = { |
80 | .name = "Kernel code", | 83 | .name = "Kernel code", |
84 | .start = (unsigned long) &_text, | ||
85 | .end = (unsigned long) &_etext - 1, | ||
81 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | 86 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, |
82 | }; | 87 | }; |
83 | 88 | ||
84 | static struct resource data_resource = { | 89 | static struct resource data_resource = { |
85 | .name = "Kernel data", | 90 | .name = "Kernel data", |
91 | .start = (unsigned long) &_etext, | ||
92 | .end = (unsigned long) &_edata - 1, | ||
86 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | 93 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, |
87 | }; | 94 | }; |
88 | 95 | ||
@@ -310,90 +317,50 @@ void machine_power_off(void) | |||
310 | 317 | ||
311 | EXPORT_SYMBOL(machine_power_off); | 318 | EXPORT_SYMBOL(machine_power_off); |
312 | 319 | ||
313 | /* | 320 | static void __init |
314 | * Setup function called from init/main.c just after the banner | 321 | add_memory_hole(unsigned long start, unsigned long end) |
315 | * was printed. | 322 | { |
316 | */ | 323 | unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; |
317 | extern char _pstart, _pend, _stext; | 324 | |
325 | if (end <= dma_pfn) | ||
326 | zholes_size[ZONE_DMA] += end - start + 1; | ||
327 | else if (start > dma_pfn) | ||
328 | zholes_size[ZONE_NORMAL] += end - start + 1; | ||
329 | else { | ||
330 | zholes_size[ZONE_DMA] += dma_pfn - start + 1; | ||
331 | zholes_size[ZONE_NORMAL] += end - dma_pfn; | ||
332 | } | ||
333 | } | ||
318 | 334 | ||
319 | void __init setup_arch(char **cmdline_p) | 335 | static void __init |
336 | parse_cmdline_early(char **cmdline_p) | ||
320 | { | 337 | { |
321 | unsigned long bootmap_size; | 338 | char c = ' ', cn, *to = command_line, *from = COMMAND_LINE; |
322 | unsigned long memory_start, memory_end; | 339 | unsigned long delay = 0; |
323 | char c = ' ', cn, *to = command_line, *from = COMMAND_LINE; | ||
324 | unsigned long start_pfn, end_pfn; | ||
325 | static unsigned int smptrap=0; | ||
326 | unsigned long delay = 0; | ||
327 | struct _lowcore *lc; | ||
328 | int i; | ||
329 | 340 | ||
330 | if (smptrap) | 341 | /* Save unparsed command line copy for /proc/cmdline */ |
331 | return; | 342 | memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); |
332 | smptrap=1; | 343 | saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; |
333 | 344 | ||
334 | /* | 345 | for (;;) { |
335 | * print what head.S has found out about the machine | 346 | /* |
336 | */ | 347 | * "mem=XXX[kKmM]" sets memsize |
337 | #ifndef CONFIG_ARCH_S390X | 348 | */ |
338 | printk((MACHINE_IS_VM) ? | 349 | if (c == ' ' && strncmp(from, "mem=", 4) == 0) { |
339 | "We are running under VM (31 bit mode)\n" : | 350 | memory_end = simple_strtoul(from+4, &from, 0); |
340 | "We are running native (31 bit mode)\n"); | 351 | if ( *from == 'K' || *from == 'k' ) { |
341 | printk((MACHINE_HAS_IEEE) ? | 352 | memory_end = memory_end << 10; |
342 | "This machine has an IEEE fpu\n" : | 353 | from++; |
343 | "This machine has no IEEE fpu\n"); | 354 | } else if ( *from == 'M' || *from == 'm' ) { |
344 | #else /* CONFIG_ARCH_S390X */ | 355 | memory_end = memory_end << 20; |
345 | printk((MACHINE_IS_VM) ? | 356 | from++; |
346 | "We are running under VM (64 bit mode)\n" : | 357 | } |
347 | "We are running native (64 bit mode)\n"); | 358 | } |
348 | #endif /* CONFIG_ARCH_S390X */ | 359 | /* |
349 | 360 | * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes | |
350 | ROOT_DEV = Root_RAM0; | 361 | */ |
351 | memory_start = (unsigned long) &_end; /* fixit if use $CODELO etc*/ | 362 | if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) { |
352 | #ifndef CONFIG_ARCH_S390X | 363 | delay = simple_strtoul(from+9, &from, 0); |
353 | memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */ | ||
354 | /* | ||
355 | * We need some free virtual space to be able to do vmalloc. | ||
356 | * On a machine with 2GB memory we make sure that we have at | ||
357 | * least 128 MB free space for vmalloc. | ||
358 | */ | ||
359 | if (memory_end > 1920*1024*1024) | ||
360 | memory_end = 1920*1024*1024; | ||
361 | #else /* CONFIG_ARCH_S390X */ | ||
362 | memory_end = memory_size & ~0x200000UL; /* detected in head.s */ | ||
363 | #endif /* CONFIG_ARCH_S390X */ | ||
364 | init_mm.start_code = PAGE_OFFSET; | ||
365 | init_mm.end_code = (unsigned long) &_etext; | ||
366 | init_mm.end_data = (unsigned long) &_edata; | ||
367 | init_mm.brk = (unsigned long) &_end; | ||
368 | |||
369 | code_resource.start = (unsigned long) &_text; | ||
370 | code_resource.end = (unsigned long) &_etext - 1; | ||
371 | data_resource.start = (unsigned long) &_etext; | ||
372 | data_resource.end = (unsigned long) &_edata - 1; | ||
373 | |||
374 | /* Save unparsed command line copy for /proc/cmdline */ | ||
375 | memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); | ||
376 | saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; | ||
377 | |||
378 | for (;;) { | ||
379 | /* | ||
380 | * "mem=XXX[kKmM]" sets memsize | ||
381 | */ | ||
382 | if (c == ' ' && strncmp(from, "mem=", 4) == 0) { | ||
383 | memory_end = simple_strtoul(from+4, &from, 0); | ||
384 | if ( *from == 'K' || *from == 'k' ) { | ||
385 | memory_end = memory_end << 10; | ||
386 | from++; | ||
387 | } else if ( *from == 'M' || *from == 'm' ) { | ||
388 | memory_end = memory_end << 20; | ||
389 | from++; | ||
390 | } | ||
391 | } | ||
392 | /* | ||
393 | * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes | ||
394 | */ | ||
395 | if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) { | ||
396 | delay = simple_strtoul(from+9, &from, 0); | ||
397 | if (*from == 's' || *from == 'S') { | 364 | if (*from == 's' || *from == 'S') { |
398 | delay = delay*1000000; | 365 | delay = delay*1000000; |
399 | from++; | 366 | from++; |
@@ -403,24 +370,110 @@ void __init setup_arch(char **cmdline_p) | |||
403 | } | 370 | } |
404 | /* now wait for the requested amount of time */ | 371 | /* now wait for the requested amount of time */ |
405 | udelay(delay); | 372 | udelay(delay); |
406 | } | 373 | } |
407 | cn = *(from++); | 374 | cn = *(from++); |
408 | if (!cn) | 375 | if (!cn) |
409 | break; | 376 | break; |
410 | if (cn == '\n') | 377 | if (cn == '\n') |
411 | cn = ' '; /* replace newlines with space */ | 378 | cn = ' '; /* replace newlines with space */ |
412 | if (cn == 0x0d) | 379 | if (cn == 0x0d) |
413 | cn = ' '; /* replace 0x0d with space */ | 380 | cn = ' '; /* replace 0x0d with space */ |
414 | if (cn == ' ' && c == ' ') | 381 | if (cn == ' ' && c == ' ') |
415 | continue; /* remove additional spaces */ | 382 | continue; /* remove additional spaces */ |
416 | c = cn; | 383 | c = cn; |
417 | if (to - command_line >= COMMAND_LINE_SIZE) | 384 | if (to - command_line >= COMMAND_LINE_SIZE) |
418 | break; | 385 | break; |
419 | *(to++) = c; | 386 | *(to++) = c; |
420 | } | 387 | } |
421 | if (c == ' ' && to > command_line) to--; | 388 | if (c == ' ' && to > command_line) to--; |
422 | *to = '\0'; | 389 | *to = '\0'; |
423 | *cmdline_p = command_line; | 390 | *cmdline_p = command_line; |
391 | } | ||
392 | |||
393 | static void __init | ||
394 | setup_lowcore(void) | ||
395 | { | ||
396 | struct _lowcore *lc; | ||
397 | int lc_pages; | ||
398 | |||
399 | /* | ||
400 | * Setup lowcore for boot cpu | ||
401 | */ | ||
402 | lc_pages = sizeof(void *) == 8 ? 2 : 1; | ||
403 | lc = (struct _lowcore *) | ||
404 | __alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0); | ||
405 | memset(lc, 0, lc_pages * PAGE_SIZE); | ||
406 | lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; | ||
407 | lc->restart_psw.addr = | ||
408 | PSW_ADDR_AMODE | (unsigned long) restart_int_handler; | ||
409 | lc->external_new_psw.mask = PSW_KERNEL_BITS; | ||
410 | lc->external_new_psw.addr = | ||
411 | PSW_ADDR_AMODE | (unsigned long) ext_int_handler; | ||
412 | lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT; | ||
413 | lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; | ||
414 | lc->program_new_psw.mask = PSW_KERNEL_BITS; | ||
415 | lc->program_new_psw.addr = | ||
416 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; | ||
417 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | ||
418 | lc->mcck_new_psw.addr = | ||
419 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; | ||
420 | lc->io_new_psw.mask = PSW_KERNEL_BITS; | ||
421 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; | ||
422 | lc->ipl_device = S390_lowcore.ipl_device; | ||
423 | lc->jiffy_timer = -1LL; | ||
424 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | ||
425 | lc->async_stack = (unsigned long) | ||
426 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | ||
427 | #ifdef CONFIG_CHECK_STACK | ||
428 | lc->panic_stack = (unsigned long) | ||
429 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; | ||
430 | #endif | ||
431 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; | ||
432 | lc->thread_info = (unsigned long) &init_thread_union; | ||
433 | #ifdef CONFIG_ARCH_S390X | ||
434 | if (MACHINE_HAS_DIAG44) | ||
435 | lc->diag44_opcode = 0x83000044; | ||
436 | else | ||
437 | lc->diag44_opcode = 0x07000700; | ||
438 | #endif /* CONFIG_ARCH_S390X */ | ||
439 | set_prefix((u32)(unsigned long) lc); | ||
440 | } | ||
441 | |||
442 | static void __init | ||
443 | setup_resources(void) | ||
444 | { | ||
445 | struct resource *res; | ||
446 | int i; | ||
447 | |||
448 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { | ||
449 | res = alloc_bootmem_low(sizeof(struct resource)); | ||
450 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | ||
451 | switch (memory_chunk[i].type) { | ||
452 | case CHUNK_READ_WRITE: | ||
453 | res->name = "System RAM"; | ||
454 | break; | ||
455 | case CHUNK_READ_ONLY: | ||
456 | res->name = "System ROM"; | ||
457 | res->flags |= IORESOURCE_READONLY; | ||
458 | break; | ||
459 | default: | ||
460 | res->name = "reserved"; | ||
461 | } | ||
462 | res->start = memory_chunk[i].addr; | ||
463 | res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; | ||
464 | request_resource(&iomem_resource, res); | ||
465 | request_resource(res, &code_resource); | ||
466 | request_resource(res, &data_resource); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | static void __init | ||
471 | setup_memory(void) | ||
472 | { | ||
473 | unsigned long bootmap_size; | ||
474 | unsigned long start_pfn, end_pfn, init_pfn; | ||
475 | unsigned long last_rw_end; | ||
476 | int i; | ||
424 | 477 | ||
425 | /* | 478 | /* |
426 | * partially used pages are not usable - thus | 479 | * partially used pages are not usable - thus |
@@ -429,6 +482,10 @@ void __init setup_arch(char **cmdline_p) | |||
429 | start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT; | 482 | start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT; |
430 | end_pfn = max_pfn = memory_end >> PAGE_SHIFT; | 483 | end_pfn = max_pfn = memory_end >> PAGE_SHIFT; |
431 | 484 | ||
485 | /* Initialize storage key for kernel pages */ | ||
486 | for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++) | ||
487 | page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); | ||
488 | |||
432 | /* | 489 | /* |
433 | * Initialize the boot-time allocator (with low memory only): | 490 | * Initialize the boot-time allocator (with low memory only): |
434 | */ | 491 | */ |
@@ -437,7 +494,9 @@ void __init setup_arch(char **cmdline_p) | |||
437 | /* | 494 | /* |
438 | * Register RAM areas with the bootmem allocator. | 495 | * Register RAM areas with the bootmem allocator. |
439 | */ | 496 | */ |
440 | for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { | 497 | last_rw_end = start_pfn; |
498 | |||
499 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { | ||
441 | unsigned long start_chunk, end_chunk; | 500 | unsigned long start_chunk, end_chunk; |
442 | 501 | ||
443 | if (memory_chunk[i].type != CHUNK_READ_WRITE) | 502 | if (memory_chunk[i].type != CHUNK_READ_WRITE) |
@@ -450,102 +509,98 @@ void __init setup_arch(char **cmdline_p) | |||
450 | start_chunk = start_pfn; | 509 | start_chunk = start_pfn; |
451 | if (end_chunk > end_pfn) | 510 | if (end_chunk > end_pfn) |
452 | end_chunk = end_pfn; | 511 | end_chunk = end_pfn; |
453 | if (start_chunk < end_chunk) | 512 | if (start_chunk < end_chunk) { |
513 | /* Initialize storage key for RAM pages */ | ||
514 | for (init_pfn = start_chunk ; init_pfn < end_chunk; | ||
515 | init_pfn++) | ||
516 | page_set_storage_key(init_pfn << PAGE_SHIFT, | ||
517 | PAGE_DEFAULT_KEY); | ||
454 | free_bootmem(start_chunk << PAGE_SHIFT, | 518 | free_bootmem(start_chunk << PAGE_SHIFT, |
455 | (end_chunk - start_chunk) << PAGE_SHIFT); | 519 | (end_chunk - start_chunk) << PAGE_SHIFT); |
520 | if (last_rw_end < start_chunk) | ||
521 | add_memory_hole(last_rw_end, start_chunk - 1); | ||
522 | last_rw_end = end_chunk; | ||
523 | } | ||
456 | } | 524 | } |
457 | 525 | ||
458 | /* | 526 | psw_set_key(PAGE_DEFAULT_KEY); |
459 | * Reserve the bootmem bitmap itself as well. We do this in two | 527 | |
460 | * steps (first step was init_bootmem()) because this catches | 528 | if (last_rw_end < end_pfn - 1) |
461 | * the (very unlikely) case of us accidentally initializing the | 529 | add_memory_hole(last_rw_end, end_pfn - 1); |
462 | * bootmem allocator with an invalid RAM area. | 530 | |
463 | */ | 531 | /* |
464 | reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); | 532 | * Reserve the bootmem bitmap itself as well. We do this in two |
533 | * steps (first step was init_bootmem()) because this catches | ||
534 | * the (very unlikely) case of us accidentally initializing the | ||
535 | * bootmem allocator with an invalid RAM area. | ||
536 | */ | ||
537 | reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); | ||
465 | 538 | ||
466 | #ifdef CONFIG_BLK_DEV_INITRD | 539 | #ifdef CONFIG_BLK_DEV_INITRD |
467 | if (INITRD_START) { | 540 | if (INITRD_START) { |
468 | if (INITRD_START + INITRD_SIZE <= memory_end) { | 541 | if (INITRD_START + INITRD_SIZE <= memory_end) { |
469 | reserve_bootmem(INITRD_START, INITRD_SIZE); | 542 | reserve_bootmem(INITRD_START, INITRD_SIZE); |
470 | initrd_start = INITRD_START; | 543 | initrd_start = INITRD_START; |
471 | initrd_end = initrd_start + INITRD_SIZE; | 544 | initrd_end = initrd_start + INITRD_SIZE; |
472 | } else { | 545 | } else { |
473 | printk("initrd extends beyond end of memory " | 546 | printk("initrd extends beyond end of memory " |
474 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", | 547 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", |
475 | initrd_start + INITRD_SIZE, memory_end); | 548 | initrd_start + INITRD_SIZE, memory_end); |
476 | initrd_start = initrd_end = 0; | 549 | initrd_start = initrd_end = 0; |
477 | } | 550 | } |
478 | } | 551 | } |
479 | #endif | 552 | #endif |
553 | } | ||
480 | 554 | ||
481 | for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { | 555 | /* |
482 | struct resource *res; | 556 | * Setup function called from init/main.c just after the banner |
483 | 557 | * was printed. | |
484 | res = alloc_bootmem_low(sizeof(struct resource)); | 558 | */ |
485 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | ||
486 | |||
487 | switch (memory_chunk[i].type) { | ||
488 | case CHUNK_READ_WRITE: | ||
489 | res->name = "System RAM"; | ||
490 | break; | ||
491 | case CHUNK_READ_ONLY: | ||
492 | res->name = "System ROM"; | ||
493 | res->flags |= IORESOURCE_READONLY; | ||
494 | break; | ||
495 | default: | ||
496 | res->name = "reserved"; | ||
497 | } | ||
498 | res->start = memory_chunk[i].addr; | ||
499 | res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; | ||
500 | request_resource(&iomem_resource, res); | ||
501 | request_resource(res, &code_resource); | ||
502 | request_resource(res, &data_resource); | ||
503 | } | ||
504 | 559 | ||
560 | void __init | ||
561 | setup_arch(char **cmdline_p) | ||
562 | { | ||
505 | /* | 563 | /* |
506 | * Setup lowcore for boot cpu | 564 | * print what head.S has found out about the machine |
507 | */ | 565 | */ |
508 | #ifndef CONFIG_ARCH_S390X | 566 | #ifndef CONFIG_ARCH_S390X |
509 | lc = (struct _lowcore *) __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); | 567 | printk((MACHINE_IS_VM) ? |
510 | memset(lc, 0, PAGE_SIZE); | 568 | "We are running under VM (31 bit mode)\n" : |
569 | "We are running native (31 bit mode)\n"); | ||
570 | printk((MACHINE_HAS_IEEE) ? | ||
571 | "This machine has an IEEE fpu\n" : | ||
572 | "This machine has no IEEE fpu\n"); | ||
511 | #else /* CONFIG_ARCH_S390X */ | 573 | #else /* CONFIG_ARCH_S390X */ |
512 | lc = (struct _lowcore *) __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0); | 574 | printk((MACHINE_IS_VM) ? |
513 | memset(lc, 0, 2*PAGE_SIZE); | 575 | "We are running under VM (64 bit mode)\n" : |
576 | "We are running native (64 bit mode)\n"); | ||
514 | #endif /* CONFIG_ARCH_S390X */ | 577 | #endif /* CONFIG_ARCH_S390X */ |
515 | lc->restart_psw.mask = PSW_BASE_BITS; | 578 | |
516 | lc->restart_psw.addr = | 579 | ROOT_DEV = Root_RAM0; |
517 | PSW_ADDR_AMODE | (unsigned long) restart_int_handler; | 580 | #ifndef CONFIG_ARCH_S390X |
518 | lc->external_new_psw.mask = PSW_KERNEL_BITS; | 581 | memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */ |
519 | lc->external_new_psw.addr = | 582 | /* |
520 | PSW_ADDR_AMODE | (unsigned long) ext_int_handler; | 583 | * We need some free virtual space to be able to do vmalloc. |
521 | lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT; | 584 | * On a machine with 2GB memory we make sure that we have at |
522 | lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; | 585 | * least 128 MB free space for vmalloc. |
523 | lc->program_new_psw.mask = PSW_KERNEL_BITS; | 586 | */ |
524 | lc->program_new_psw.addr = | 587 | if (memory_end > 1920*1024*1024) |
525 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; | 588 | memory_end = 1920*1024*1024; |
526 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | 589 | #else /* CONFIG_ARCH_S390X */ |
527 | lc->mcck_new_psw.addr = | 590 | memory_end = memory_size & ~0x200000UL; /* detected in head.s */ |
528 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; | ||
529 | lc->io_new_psw.mask = PSW_KERNEL_BITS; | ||
530 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; | ||
531 | lc->ipl_device = S390_lowcore.ipl_device; | ||
532 | lc->jiffy_timer = -1LL; | ||
533 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | ||
534 | lc->async_stack = (unsigned long) | ||
535 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | ||
536 | #ifdef CONFIG_CHECK_STACK | ||
537 | lc->panic_stack = (unsigned long) | ||
538 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; | ||
539 | #endif | ||
540 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; | ||
541 | lc->thread_info = (unsigned long) &init_thread_union; | ||
542 | #ifdef CONFIG_ARCH_S390X | ||
543 | if (MACHINE_HAS_DIAG44) | ||
544 | lc->diag44_opcode = 0x83000044; | ||
545 | else | ||
546 | lc->diag44_opcode = 0x07000700; | ||
547 | #endif /* CONFIG_ARCH_S390X */ | 591 | #endif /* CONFIG_ARCH_S390X */ |
548 | set_prefix((u32)(unsigned long) lc); | 592 | |
593 | init_mm.start_code = PAGE_OFFSET; | ||
594 | init_mm.end_code = (unsigned long) &_etext; | ||
595 | init_mm.end_data = (unsigned long) &_edata; | ||
596 | init_mm.brk = (unsigned long) &_end; | ||
597 | |||
598 | parse_cmdline_early(cmdline_p); | ||
599 | |||
600 | setup_memory(); | ||
601 | setup_resources(); | ||
602 | setup_lowcore(); | ||
603 | |||
549 | cpu_init(); | 604 | cpu_init(); |
550 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; | 605 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; |
551 | 606 | ||
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 061e81138dc2..8ca485676780 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -244,7 +244,7 @@ int sysctl_hz_timer = 1; | |||
244 | */ | 244 | */ |
245 | static inline void stop_hz_timer(void) | 245 | static inline void stop_hz_timer(void) |
246 | { | 246 | { |
247 | __u64 timer; | 247 | __u64 timer, todval; |
248 | 248 | ||
249 | if (sysctl_hz_timer != 0) | 249 | if (sysctl_hz_timer != 0) |
250 | return; | 250 | return; |
@@ -265,8 +265,14 @@ static inline void stop_hz_timer(void) | |||
265 | * for the next event. | 265 | * for the next event. |
266 | */ | 266 | */ |
267 | timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; | 267 | timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; |
268 | timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY; | 268 | todval = -1ULL; |
269 | asm volatile ("SCKC %0" : : "m" (timer)); | 269 | /* Be careful about overflows. */ |
270 | if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) { | ||
271 | timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY; | ||
272 | if (timer >= jiffies_timer_cc) | ||
273 | todval = timer; | ||
274 | } | ||
275 | asm volatile ("SCKC %0" : : "m" (todval)); | ||
270 | } | 276 | } |
271 | 277 | ||
272 | /* | 278 | /* |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index bb6cf02418a2..fa0726507b3d 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
@@ -122,12 +122,17 @@ static void start_cpu_timer(void) | |||
122 | struct vtimer_queue *vt_list; | 122 | struct vtimer_queue *vt_list; |
123 | 123 | ||
124 | vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); | 124 | vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); |
125 | set_vtimer(vt_list->idle); | 125 | |
126 | /* CPU timer interrupt is pending, don't reprogramm it */ | ||
127 | if (vt_list->idle & 1LL<<63) | ||
128 | return; | ||
129 | |||
130 | if (!list_empty(&vt_list->list)) | ||
131 | set_vtimer(vt_list->idle); | ||
126 | } | 132 | } |
127 | 133 | ||
128 | static void stop_cpu_timer(void) | 134 | static void stop_cpu_timer(void) |
129 | { | 135 | { |
130 | __u64 done; | ||
131 | struct vtimer_queue *vt_list; | 136 | struct vtimer_queue *vt_list; |
132 | 137 | ||
133 | vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); | 138 | vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); |
@@ -138,21 +143,17 @@ static void stop_cpu_timer(void) | |||
138 | goto fire; | 143 | goto fire; |
139 | } | 144 | } |
140 | 145 | ||
141 | /* store progress */ | 146 | /* store the actual expire value */ |
142 | asm volatile ("STPT %0" : "=m" (done)); | 147 | asm volatile ("STPT %0" : "=m" (vt_list->idle)); |
143 | 148 | ||
144 | /* | 149 | /* |
145 | * If done is negative we do not stop the CPU timer | 150 | * If the CPU timer is negative we don't reprogramm |
146 | * because we will get instantly an interrupt that | 151 | * it because we will get instantly an interrupt. |
147 | * will start the CPU timer again. | ||
148 | */ | 152 | */ |
149 | if (done & 1LL<<63) | 153 | if (vt_list->idle & 1LL<<63) |
150 | return; | 154 | return; |
151 | else | ||
152 | vt_list->offset += vt_list->to_expire - done; | ||
153 | 155 | ||
154 | /* save the actual expire value */ | 156 | vt_list->offset += vt_list->to_expire - vt_list->idle; |
155 | vt_list->idle = done; | ||
156 | 157 | ||
157 | /* | 158 | /* |
158 | * We cannot halt the CPU timer, we just write a value that | 159 | * We cannot halt the CPU timer, we just write a value that |
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index d30cdb4248a9..f5a5bc09b8fa 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c | |||
@@ -20,6 +20,11 @@ | |||
20 | #include <asm/pgalloc.h> | 20 | #include <asm/pgalloc.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | 22 | ||
23 | static char *sender = "VMRMSVM"; | ||
24 | module_param(sender, charp, 0); | ||
25 | MODULE_PARM_DESC(sender, | ||
26 | "Guest name that may send SMSG messages (default VMRMSVM)"); | ||
27 | |||
23 | #include "../../../drivers/s390/net/smsgiucv.h" | 28 | #include "../../../drivers/s390/net/smsgiucv.h" |
24 | 29 | ||
25 | #define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2) | 30 | #define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2) |
@@ -367,10 +372,12 @@ static struct ctl_table cmm_dir_table[] = { | |||
367 | #ifdef CONFIG_CMM_IUCV | 372 | #ifdef CONFIG_CMM_IUCV |
368 | #define SMSG_PREFIX "CMM" | 373 | #define SMSG_PREFIX "CMM" |
369 | static void | 374 | static void |
370 | cmm_smsg_target(char *msg) | 375 | cmm_smsg_target(char *from, char *msg) |
371 | { | 376 | { |
372 | long pages, seconds; | 377 | long pages, seconds; |
373 | 378 | ||
379 | if (strlen(sender) > 0 && strcmp(from, sender) != 0) | ||
380 | return; | ||
374 | if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg)) | 381 | if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg)) |
375 | return; | 382 | return; |
376 | if (strncmp(msg, "SHRINK", 6) == 0) { | 383 | if (strncmp(msg, "SHRINK", 6) == 0) { |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 8e723bc7f795..6ec5cd981e74 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -101,6 +101,7 @@ extern unsigned long _end; | |||
101 | extern unsigned long __init_begin; | 101 | extern unsigned long __init_begin; |
102 | extern unsigned long __init_end; | 102 | extern unsigned long __init_end; |
103 | 103 | ||
104 | extern unsigned long __initdata zholes_size[]; | ||
104 | /* | 105 | /* |
105 | * paging_init() sets up the page tables | 106 | * paging_init() sets up the page tables |
106 | */ | 107 | */ |
@@ -163,10 +164,13 @@ void __init paging_init(void) | |||
163 | local_flush_tlb(); | 164 | local_flush_tlb(); |
164 | 165 | ||
165 | { | 166 | { |
166 | unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0}; | 167 | unsigned long zones_size[MAX_NR_ZONES]; |
167 | 168 | ||
169 | memset(zones_size, 0, sizeof(zones_size)); | ||
168 | zones_size[ZONE_DMA] = max_low_pfn; | 170 | zones_size[ZONE_DMA] = max_low_pfn; |
169 | free_area_init(zones_size); | 171 | free_area_init_node(0, &contig_page_data, zones_size, |
172 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, | ||
173 | zholes_size); | ||
170 | } | 174 | } |
171 | return; | 175 | return; |
172 | } | 176 | } |
@@ -184,9 +188,10 @@ void __init paging_init(void) | |||
184 | _KERN_REGION_TABLE; | 188 | _KERN_REGION_TABLE; |
185 | static const int ssm_mask = 0x04000000L; | 189 | static const int ssm_mask = 0x04000000L; |
186 | 190 | ||
187 | unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; | 191 | unsigned long zones_size[MAX_NR_ZONES]; |
188 | unsigned long dma_pfn, high_pfn; | 192 | unsigned long dma_pfn, high_pfn; |
189 | 193 | ||
194 | memset(zones_size, 0, sizeof(zones_size)); | ||
190 | dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; | 195 | dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; |
191 | high_pfn = max_low_pfn; | 196 | high_pfn = max_low_pfn; |
192 | 197 | ||
@@ -198,8 +203,8 @@ void __init paging_init(void) | |||
198 | } | 203 | } |
199 | 204 | ||
200 | /* Initialize mem_map[]. */ | 205 | /* Initialize mem_map[]. */ |
201 | free_area_init(zones_size); | 206 | free_area_init_node(0, &contig_page_data, zones_size, |
202 | 207 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); | |
203 | 208 | ||
204 | /* | 209 | /* |
205 | * map whole physical memory to virtual memory (identity mapping) | 210 | * map whole physical memory to virtual memory (identity mapping) |
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 1b0dfb4d8ea4..b28919b65682 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/user.h> | 20 | #include <linux/user.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/security.h> | 22 | #include <linux/security.h> |
23 | #include <linux/signal.h> | ||
23 | 24 | ||
24 | #include <asm/io.h> | 25 | #include <asm/io.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
@@ -197,7 +198,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
197 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 198 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
198 | case PTRACE_CONT: { /* restart after signal. */ | 199 | case PTRACE_CONT: { /* restart after signal. */ |
199 | ret = -EIO; | 200 | ret = -EIO; |
200 | if ((unsigned long) data > _NSIG) | 201 | if (!valid_signal(data)) |
201 | break; | 202 | break; |
202 | if (request == PTRACE_SYSCALL) | 203 | if (request == PTRACE_SYSCALL) |
203 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 204 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -228,7 +229,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
228 | struct pt_regs *dummy = NULL; | 229 | struct pt_regs *dummy = NULL; |
229 | 230 | ||
230 | ret = -EIO; | 231 | ret = -EIO; |
231 | if ((unsigned long) data > _NSIG) | 232 | if (!valid_signal(data)) |
232 | break; | 233 | break; |
233 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 234 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
234 | if ((child->ptrace & PT_DTRACE) == 0) { | 235 | if ((child->ptrace & PT_DTRACE) == 0) { |
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c index 800288c1562b..fd2000956dae 100644 --- a/arch/sh64/kernel/ptrace.c +++ b/arch/sh64/kernel/ptrace.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/ptrace.h> | 28 | #include <linux/ptrace.h> |
29 | #include <linux/user.h> | 29 | #include <linux/user.h> |
30 | #include <linux/signal.h> | ||
30 | 31 | ||
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
@@ -255,7 +256,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
255 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 256 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
256 | case PTRACE_CONT: { /* restart after signal. */ | 257 | case PTRACE_CONT: { /* restart after signal. */ |
257 | ret = -EIO; | 258 | ret = -EIO; |
258 | if ((unsigned long) data > _NSIG) | 259 | if (!valid_signal(data)) |
259 | break; | 260 | break; |
260 | if (request == PTRACE_SYSCALL) | 261 | if (request == PTRACE_SYSCALL) |
261 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 262 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
@@ -285,7 +286,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
285 | struct pt_regs *regs; | 286 | struct pt_regs *regs; |
286 | 287 | ||
287 | ret = -EIO; | 288 | ret = -EIO; |
288 | if ((unsigned long) data > _NSIG) | 289 | if (!valid_signal(data)) |
289 | break; | 290 | break; |
290 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 291 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
291 | if ((child->ptrace & PT_DTRACE) == 0) { | 292 | if ((child->ptrace & PT_DTRACE) == 0) { |
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c index 4546845b9caf..58ff7d522d81 100644 --- a/arch/sh64/kernel/sys_sh64.c +++ b/arch/sh64/kernel/sys_sh64.c | |||
@@ -283,18 +283,3 @@ asmlinkage int sys_uname(struct old_utsname * name) | |||
283 | up_read(&uts_sem); | 283 | up_read(&uts_sem); |
284 | return err?-EFAULT:0; | 284 | return err?-EFAULT:0; |
285 | } | 285 | } |
286 | |||
287 | /* Copy from mips version */ | ||
288 | asmlinkage long sys_shmatcall(int shmid, char __user *shmaddr, | ||
289 | int shmflg) | ||
290 | { | ||
291 | unsigned long raddr; | ||
292 | int err; | ||
293 | |||
294 | err = do_shmat(shmid, shmaddr, shmflg, &raddr); | ||
295 | if (err) | ||
296 | return err; | ||
297 | |||
298 | err = raddr; | ||
299 | return err; | ||
300 | } | ||
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S index 8ed417df3dc6..6aabc63e4518 100644 --- a/arch/sh64/kernel/syscalls.S +++ b/arch/sh64/kernel/syscalls.S | |||
@@ -268,7 +268,7 @@ sys_call_table: | |||
268 | .long sys_msgrcv | 268 | .long sys_msgrcv |
269 | .long sys_msgget | 269 | .long sys_msgget |
270 | .long sys_msgctl | 270 | .long sys_msgctl |
271 | .long sys_shmatcall | 271 | .long sys_shmat |
272 | .long sys_shmdt /* 245 */ | 272 | .long sys_shmdt /* 245 */ |
273 | .long sys_shmget | 273 | .long sys_shmget |
274 | .long sys_shmctl | 274 | .long sys_shmctl |
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index c4f93bd2daf2..475c4c13462c 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
20 | #include <linux/security.h> | 20 | #include <linux/security.h> |
21 | #include <linux/signal.h> | ||
21 | 22 | ||
22 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
23 | #include <asm/system.h> | 24 | #include <asm/system.h> |
@@ -526,7 +527,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) | |||
526 | addr = 1; | 527 | addr = 1; |
527 | 528 | ||
528 | case PTRACE_CONT: { /* restart after signal. */ | 529 | case PTRACE_CONT: { /* restart after signal. */ |
529 | if (data > _NSIG) { | 530 | if (!valid_signal(data)) { |
530 | pt_error_return(regs, EIO); | 531 | pt_error_return(regs, EIO); |
531 | goto out_tsk; | 532 | goto out_tsk; |
532 | } | 533 | } |
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 5f080cf04b33..80a76e2ad732 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
21 | #include <linux/security.h> | 21 | #include <linux/security.h> |
22 | #include <linux/signal.h> | ||
22 | 23 | ||
23 | #include <asm/asi.h> | 24 | #include <asm/asi.h> |
24 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
@@ -559,7 +560,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) | |||
559 | addr = 1; | 560 | addr = 1; |
560 | 561 | ||
561 | case PTRACE_CONT: { /* restart after signal. */ | 562 | case PTRACE_CONT: { /* restart after signal. */ |
562 | if (data > _NSIG) { | 563 | if (!valid_signal(data)) { |
563 | pt_error_return(regs, EIO); | 564 | pt_error_return(regs, EIO); |
564 | goto out_tsk; | 565 | goto out_tsk; |
565 | } | 566 | } |
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 9a23df182123..c5292181a664 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig | |||
@@ -244,6 +244,7 @@ config KERNEL_HALF_GIGS | |||
244 | 244 | ||
245 | config HIGHMEM | 245 | config HIGHMEM |
246 | bool "Highmem support" | 246 | bool "Highmem support" |
247 | depends on !64BIT | ||
247 | 248 | ||
248 | config KERNEL_STACK_ORDER | 249 | config KERNEL_STACK_ORDER |
249 | int "Kernel stack size order" | 250 | int "Kernel stack size order" |
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386 index 203c242201b6..e41f3748d30f 100644 --- a/arch/um/Kconfig_i386 +++ b/arch/um/Kconfig_i386 | |||
@@ -1,4 +1,8 @@ | |||
1 | config 64_BIT | 1 | config UML_X86 |
2 | bool | ||
3 | default y | ||
4 | |||
5 | config 64BIT | ||
2 | bool | 6 | bool |
3 | default n | 7 | default n |
4 | 8 | ||
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64 index 768dc6626a8d..fd8d7e8982b1 100644 --- a/arch/um/Kconfig_x86_64 +++ b/arch/um/Kconfig_x86_64 | |||
@@ -1,4 +1,8 @@ | |||
1 | config 64_BIT | 1 | config UML_X86 |
2 | bool | ||
3 | default y | ||
4 | |||
5 | config 64BIT | ||
2 | bool | 6 | bool |
3 | default y | 7 | default y |
4 | 8 | ||
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index 97b223bfa78e..f9e3c0f06541 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 | |||
@@ -1,4 +1,4 @@ | |||
1 | SUBARCH_CORE := arch/um/sys-i386/ | 1 | SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/ |
2 | 2 | ||
3 | TOP_ADDR := $(CONFIG_TOP_ADDR) | 3 | TOP_ADDR := $(CONFIG_TOP_ADDR) |
4 | 4 | ||
diff --git a/arch/um/defconfig b/arch/um/defconfig index fc3075c589d8..4067c3aa5b60 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.12-rc1-bk1 | 3 | # Linux kernel version: 2.6.12-rc3-skas3-v9-pre2 |
4 | # Sun Mar 20 16:53:00 2005 | 4 | # Sun Apr 24 19:46:10 2005 |
5 | # | 5 | # |
6 | CONFIG_GENERIC_HARDIRQS=y | 6 | CONFIG_GENERIC_HARDIRQS=y |
7 | CONFIG_UML=y | 7 | CONFIG_UML=y |
@@ -15,7 +15,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y | |||
15 | # | 15 | # |
16 | CONFIG_MODE_TT=y | 16 | CONFIG_MODE_TT=y |
17 | CONFIG_MODE_SKAS=y | 17 | CONFIG_MODE_SKAS=y |
18 | # CONFIG_64_BIT is not set | 18 | CONFIG_UML_X86=y |
19 | # CONFIG_64BIT is not set | ||
19 | CONFIG_TOP_ADDR=0xc0000000 | 20 | CONFIG_TOP_ADDR=0xc0000000 |
20 | # CONFIG_3_LEVEL_PGTABLES is not set | 21 | # CONFIG_3_LEVEL_PGTABLES is not set |
21 | CONFIG_ARCH_HAS_SC_SIGNALS=y | 22 | CONFIG_ARCH_HAS_SC_SIGNALS=y |
@@ -41,6 +42,7 @@ CONFIG_UML_REAL_TIME_CLOCK=y | |||
41 | CONFIG_EXPERIMENTAL=y | 42 | CONFIG_EXPERIMENTAL=y |
42 | CONFIG_CLEAN_COMPILE=y | 43 | CONFIG_CLEAN_COMPILE=y |
43 | CONFIG_BROKEN_ON_SMP=y | 44 | CONFIG_BROKEN_ON_SMP=y |
45 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
44 | 46 | ||
45 | # | 47 | # |
46 | # General setup | 48 | # General setup |
@@ -158,7 +160,6 @@ CONFIG_UML_NET_SLIRP=y | |||
158 | # | 160 | # |
159 | CONFIG_PACKET=y | 161 | CONFIG_PACKET=y |
160 | CONFIG_PACKET_MMAP=y | 162 | CONFIG_PACKET_MMAP=y |
161 | # CONFIG_NETLINK_DEV is not set | ||
162 | CONFIG_UNIX=y | 163 | CONFIG_UNIX=y |
163 | # CONFIG_NET_KEY is not set | 164 | # CONFIG_NET_KEY is not set |
164 | CONFIG_INET=y | 165 | CONFIG_INET=y |
@@ -412,6 +413,5 @@ CONFIG_DEBUG_INFO=y | |||
412 | # CONFIG_DEBUG_FS is not set | 413 | # CONFIG_DEBUG_FS is not set |
413 | CONFIG_FRAME_POINTER=y | 414 | CONFIG_FRAME_POINTER=y |
414 | CONFIG_PT_PROXY=y | 415 | CONFIG_PT_PROXY=y |
415 | # CONFIG_GPROF is not set | ||
416 | # CONFIG_GCOV is not set | 416 | # CONFIG_GCOV is not set |
417 | # CONFIG_SYSCALL_DEBUG is not set | 417 | # CONFIG_SYSCALL_DEBUG is not set |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 1f77deb3fd23..0150038af795 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #ifdef CONFIG_NOCONFIG_CHAN | 22 | #ifdef CONFIG_NOCONFIG_CHAN |
23 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) | 23 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) |
24 | { | 24 | { |
25 | printk(KERN_ERR "Using a channel type which is configured out of " | 25 | printf(KERN_ERR "Using a channel type which is configured out of " |
26 | "UML\n"); | 26 | "UML\n"); |
27 | return(NULL); | 27 | return(NULL); |
28 | } | 28 | } |
@@ -30,27 +30,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts) | |||
30 | static int not_configged_open(int input, int output, int primary, void *data, | 30 | static int not_configged_open(int input, int output, int primary, void *data, |
31 | char **dev_out) | 31 | char **dev_out) |
32 | { | 32 | { |
33 | printk(KERN_ERR "Using a channel type which is configured out of " | 33 | printf(KERN_ERR "Using a channel type which is configured out of " |
34 | "UML\n"); | 34 | "UML\n"); |
35 | return(-ENODEV); | 35 | return(-ENODEV); |
36 | } | 36 | } |
37 | 37 | ||
38 | static void not_configged_close(int fd, void *data) | 38 | static void not_configged_close(int fd, void *data) |
39 | { | 39 | { |
40 | printk(KERN_ERR "Using a channel type which is configured out of " | 40 | printf(KERN_ERR "Using a channel type which is configured out of " |
41 | "UML\n"); | 41 | "UML\n"); |
42 | } | 42 | } |
43 | 43 | ||
44 | static int not_configged_read(int fd, char *c_out, void *data) | 44 | static int not_configged_read(int fd, char *c_out, void *data) |
45 | { | 45 | { |
46 | printk(KERN_ERR "Using a channel type which is configured out of " | 46 | printf(KERN_ERR "Using a channel type which is configured out of " |
47 | "UML\n"); | 47 | "UML\n"); |
48 | return(-EIO); | 48 | return(-EIO); |
49 | } | 49 | } |
50 | 50 | ||
51 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 51 | static int not_configged_write(int fd, const char *buf, int len, void *data) |
52 | { | 52 | { |
53 | printk(KERN_ERR "Using a channel type which is configured out of " | 53 | printf(KERN_ERR "Using a channel type which is configured out of " |
54 | "UML\n"); | 54 | "UML\n"); |
55 | return(-EIO); | 55 | return(-EIO); |
56 | } | 56 | } |
@@ -58,7 +58,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data) | |||
58 | static int not_configged_console_write(int fd, const char *buf, int len, | 58 | static int not_configged_console_write(int fd, const char *buf, int len, |
59 | void *data) | 59 | void *data) |
60 | { | 60 | { |
61 | printk(KERN_ERR "Using a channel type which is configured out of " | 61 | printf(KERN_ERR "Using a channel type which is configured out of " |
62 | "UML\n"); | 62 | "UML\n"); |
63 | return(-EIO); | 63 | return(-EIO); |
64 | } | 64 | } |
@@ -66,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len, | |||
66 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 66 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, |
67 | unsigned short *cols) | 67 | unsigned short *cols) |
68 | { | 68 | { |
69 | printk(KERN_ERR "Using a channel type which is configured out of " | 69 | printf(KERN_ERR "Using a channel type which is configured out of " |
70 | "UML\n"); | 70 | "UML\n"); |
71 | return(-ENODEV); | 71 | return(-ENODEV); |
72 | } | 72 | } |
73 | 73 | ||
74 | static void not_configged_free(void *data) | 74 | static void not_configged_free(void *data) |
75 | { | 75 | { |
76 | printk(KERN_ERR "Using a channel type which is configured out of " | 76 | printf(KERN_ERR "Using a channel type which is configured out of " |
77 | "UML\n"); | 77 | "UML\n"); |
78 | } | 78 | } |
79 | 79 | ||
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 6924f273ced9..d0f97127adf6 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -39,19 +39,69 @@ static void line_timer_cb(void *arg) | |||
39 | line_interrupt(line->driver->read_irq, arg, NULL); | 39 | line_interrupt(line->driver->read_irq, arg, NULL); |
40 | } | 40 | } |
41 | 41 | ||
42 | static int write_room(struct line *dev) | 42 | /* Returns the free space inside the ring buffer of this line. |
43 | * | ||
44 | * Should be called while holding line->lock (this does not modify datas). | ||
45 | */ | ||
46 | static int write_room(struct line *line) | ||
43 | { | 47 | { |
44 | int n; | 48 | int n; |
45 | 49 | ||
46 | if (dev->buffer == NULL) | 50 | if (line->buffer == NULL) |
47 | return (LINE_BUFSIZE - 1); | 51 | return LINE_BUFSIZE - 1; |
52 | |||
53 | /* This is for the case where the buffer is wrapped! */ | ||
54 | n = line->head - line->tail; | ||
48 | 55 | ||
49 | n = dev->head - dev->tail; | ||
50 | if (n <= 0) | 56 | if (n <= 0) |
51 | n = LINE_BUFSIZE + n; | 57 | n = LINE_BUFSIZE + n; /* The other case */ |
52 | return (n - 1); | 58 | return n - 1; |
59 | } | ||
60 | |||
61 | int line_write_room(struct tty_struct *tty) | ||
62 | { | ||
63 | struct line *line = tty->driver_data; | ||
64 | unsigned long flags; | ||
65 | int room; | ||
66 | |||
67 | if (tty->stopped) | ||
68 | return 0; | ||
69 | |||
70 | spin_lock_irqsave(&line->lock, flags); | ||
71 | room = write_room(line); | ||
72 | spin_unlock_irqrestore(&line->lock, flags); | ||
73 | |||
74 | /*XXX: Warning to remove */ | ||
75 | if (0 == room) | ||
76 | printk(KERN_DEBUG "%s: %s: no room left in buffer\n", | ||
77 | __FUNCTION__,tty->name); | ||
78 | return room; | ||
53 | } | 79 | } |
54 | 80 | ||
81 | int line_chars_in_buffer(struct tty_struct *tty) | ||
82 | { | ||
83 | struct line *line = tty->driver_data; | ||
84 | unsigned long flags; | ||
85 | int ret; | ||
86 | |||
87 | spin_lock_irqsave(&line->lock, flags); | ||
88 | |||
89 | /*write_room subtracts 1 for the needed NULL, so we readd it.*/ | ||
90 | ret = LINE_BUFSIZE - (write_room(line) + 1); | ||
91 | spin_unlock_irqrestore(&line->lock, flags); | ||
92 | |||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * This copies the content of buf into the circular buffer associated with | ||
98 | * this line. | ||
99 | * The return value is the number of characters actually copied, i.e. the ones | ||
100 | * for which there was space: this function is not supposed to ever flush out | ||
101 | * the circular buffer. | ||
102 | * | ||
103 | * Must be called while holding line->lock! | ||
104 | */ | ||
55 | static int buffer_data(struct line *line, const char *buf, int len) | 105 | static int buffer_data(struct line *line, const char *buf, int len) |
56 | { | 106 | { |
57 | int end, room; | 107 | int end, room; |
@@ -70,48 +120,95 @@ static int buffer_data(struct line *line, const char *buf, int len) | |||
70 | len = (len > room) ? room : len; | 120 | len = (len > room) ? room : len; |
71 | 121 | ||
72 | end = line->buffer + LINE_BUFSIZE - line->tail; | 122 | end = line->buffer + LINE_BUFSIZE - line->tail; |
73 | if(len < end){ | 123 | |
124 | if (len < end){ | ||
74 | memcpy(line->tail, buf, len); | 125 | memcpy(line->tail, buf, len); |
75 | line->tail += len; | 126 | line->tail += len; |
76 | } | 127 | } else { |
77 | else { | 128 | /* The circular buffer is wrapping */ |
78 | memcpy(line->tail, buf, end); | 129 | memcpy(line->tail, buf, end); |
79 | buf += end; | 130 | buf += end; |
80 | memcpy(line->buffer, buf, len - end); | 131 | memcpy(line->buffer, buf, len - end); |
81 | line->tail = line->buffer + len - end; | 132 | line->tail = line->buffer + len - end; |
82 | } | 133 | } |
83 | 134 | ||
84 | return(len); | 135 | return len; |
85 | } | 136 | } |
86 | 137 | ||
138 | /* | ||
139 | * Flushes the ring buffer to the output channels. That is, write_chan is | ||
140 | * called, passing it line->head as buffer, and an appropriate count. | ||
141 | * | ||
142 | * On exit, returns 1 when the buffer is empty, | ||
143 | * 0 when the buffer is not empty on exit, | ||
144 | * and -errno when an error occurred. | ||
145 | * | ||
146 | * Must be called while holding line->lock!*/ | ||
87 | static int flush_buffer(struct line *line) | 147 | static int flush_buffer(struct line *line) |
88 | { | 148 | { |
89 | int n, count; | 149 | int n, count; |
90 | 150 | ||
91 | if ((line->buffer == NULL) || (line->head == line->tail)) | 151 | if ((line->buffer == NULL) || (line->head == line->tail)) |
92 | return(1); | 152 | return 1; |
93 | 153 | ||
94 | if (line->tail < line->head) { | 154 | if (line->tail < line->head) { |
155 | /* line->buffer + LINE_BUFSIZE is the end of the buffer! */ | ||
95 | count = line->buffer + LINE_BUFSIZE - line->head; | 156 | count = line->buffer + LINE_BUFSIZE - line->head; |
157 | |||
96 | n = write_chan(&line->chan_list, line->head, count, | 158 | n = write_chan(&line->chan_list, line->head, count, |
97 | line->driver->write_irq); | 159 | line->driver->write_irq); |
98 | if (n < 0) | 160 | if (n < 0) |
99 | return(n); | 161 | return n; |
100 | if (n == count) | 162 | if (n == count) { |
163 | /* We have flushed from ->head to buffer end, now we | ||
164 | * must flush only from the beginning to ->tail.*/ | ||
101 | line->head = line->buffer; | 165 | line->head = line->buffer; |
102 | else { | 166 | } else { |
103 | line->head += n; | 167 | line->head += n; |
104 | return(0); | 168 | return 0; |
105 | } | 169 | } |
106 | } | 170 | } |
107 | 171 | ||
108 | count = line->tail - line->head; | 172 | count = line->tail - line->head; |
109 | n = write_chan(&line->chan_list, line->head, count, | 173 | n = write_chan(&line->chan_list, line->head, count, |
110 | line->driver->write_irq); | 174 | line->driver->write_irq); |
111 | if(n < 0) return(n); | 175 | |
176 | if(n < 0) | ||
177 | return n; | ||
112 | 178 | ||
113 | line->head += n; | 179 | line->head += n; |
114 | return(line->head == line->tail); | 180 | return line->head == line->tail; |
181 | } | ||
182 | |||
183 | void line_flush_buffer(struct tty_struct *tty) | ||
184 | { | ||
185 | struct line *line = tty->driver_data; | ||
186 | unsigned long flags; | ||
187 | int err; | ||
188 | |||
189 | /*XXX: copied from line_write, verify if it is correct!*/ | ||
190 | if(tty->stopped) | ||
191 | return; | ||
192 | //return 0; | ||
193 | |||
194 | spin_lock_irqsave(&line->lock, flags); | ||
195 | err = flush_buffer(line); | ||
196 | /*if (err == 1) | ||
197 | err = 0;*/ | ||
198 | spin_unlock_irqrestore(&line->lock, flags); | ||
199 | //return err; | ||
200 | } | ||
201 | |||
202 | /* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer | ||
203 | * and ->write. Hope it's not that bad.*/ | ||
204 | void line_flush_chars(struct tty_struct *tty) | ||
205 | { | ||
206 | line_flush_buffer(tty); | ||
207 | } | ||
208 | |||
209 | void line_put_char(struct tty_struct *tty, unsigned char ch) | ||
210 | { | ||
211 | line_write(tty, &ch, sizeof(ch)); | ||
115 | } | 212 | } |
116 | 213 | ||
117 | int line_write(struct tty_struct *tty, const unsigned char *buf, int len) | 214 | int line_write(struct tty_struct *tty, const unsigned char *buf, int len) |
@@ -120,38 +217,31 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len) | |||
120 | unsigned long flags; | 217 | unsigned long flags; |
121 | int n, err, ret = 0; | 218 | int n, err, ret = 0; |
122 | 219 | ||
123 | if(tty->stopped) return 0; | 220 | if(tty->stopped) |
221 | return 0; | ||
124 | 222 | ||
125 | down(&line->sem); | 223 | spin_lock_irqsave(&line->lock, flags); |
126 | if(line->head != line->tail){ | 224 | if (line->head != line->tail) { |
127 | local_irq_save(flags); | ||
128 | ret = buffer_data(line, buf, len); | 225 | ret = buffer_data(line, buf, len); |
129 | err = flush_buffer(line); | 226 | err = flush_buffer(line); |
130 | local_irq_restore(flags); | 227 | if (err <= 0 && (err != -EAGAIN || !ret)) |
131 | if(err <= 0 && (err != -EAGAIN || !ret)) | ||
132 | ret = err; | 228 | ret = err; |
133 | } | 229 | } else { |
134 | else { | ||
135 | n = write_chan(&line->chan_list, buf, len, | 230 | n = write_chan(&line->chan_list, buf, len, |
136 | line->driver->write_irq); | 231 | line->driver->write_irq); |
137 | if(n < 0){ | 232 | if (n < 0) { |
138 | ret = n; | 233 | ret = n; |
139 | goto out_up; | 234 | goto out_up; |
140 | } | 235 | } |
141 | 236 | ||
142 | len -= n; | 237 | len -= n; |
143 | ret += n; | 238 | ret += n; |
144 | if(len > 0) | 239 | if (len > 0) |
145 | ret += buffer_data(line, buf + n, len); | 240 | ret += buffer_data(line, buf + n, len); |
146 | } | 241 | } |
147 | out_up: | 242 | out_up: |
148 | up(&line->sem); | 243 | spin_unlock_irqrestore(&line->lock, flags); |
149 | return(ret); | 244 | return ret; |
150 | } | ||
151 | |||
152 | void line_put_char(struct tty_struct *tty, unsigned char ch) | ||
153 | { | ||
154 | line_write(tty, &ch, sizeof(ch)); | ||
155 | } | 245 | } |
156 | 246 | ||
157 | void line_set_termios(struct tty_struct *tty, struct termios * old) | 247 | void line_set_termios(struct tty_struct *tty, struct termios * old) |
@@ -159,11 +249,6 @@ void line_set_termios(struct tty_struct *tty, struct termios * old) | |||
159 | /* nothing */ | 249 | /* nothing */ |
160 | } | 250 | } |
161 | 251 | ||
162 | int line_chars_in_buffer(struct tty_struct *tty) | ||
163 | { | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static struct { | 252 | static struct { |
168 | int cmd; | 253 | int cmd; |
169 | char *level; | 254 | char *level; |
@@ -250,7 +335,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file, | |||
250 | ret = -ENOIOCTLCMD; | 335 | ret = -ENOIOCTLCMD; |
251 | break; | 336 | break; |
252 | } | 337 | } |
253 | return(ret); | 338 | return ret; |
254 | } | 339 | } |
255 | 340 | ||
256 | static irqreturn_t line_write_interrupt(int irq, void *data, | 341 | static irqreturn_t line_write_interrupt(int irq, void *data, |
@@ -260,18 +345,23 @@ static irqreturn_t line_write_interrupt(int irq, void *data, | |||
260 | struct line *line = tty->driver_data; | 345 | struct line *line = tty->driver_data; |
261 | int err; | 346 | int err; |
262 | 347 | ||
348 | /* Interrupts are enabled here because we registered the interrupt with | ||
349 | * SA_INTERRUPT (see line_setup_irq).*/ | ||
350 | |||
351 | spin_lock_irq(&line->lock); | ||
263 | err = flush_buffer(line); | 352 | err = flush_buffer(line); |
264 | if(err == 0) | 353 | if (err == 0) { |
265 | return(IRQ_NONE); | 354 | return IRQ_NONE; |
266 | else if(err < 0){ | 355 | } else if(err < 0) { |
267 | line->head = line->buffer; | 356 | line->head = line->buffer; |
268 | line->tail = line->buffer; | 357 | line->tail = line->buffer; |
269 | } | 358 | } |
359 | spin_unlock_irq(&line->lock); | ||
270 | 360 | ||
271 | if(tty == NULL) | 361 | if(tty == NULL) |
272 | return(IRQ_NONE); | 362 | return IRQ_NONE; |
273 | 363 | ||
274 | if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && | 364 | if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && |
275 | (tty->ldisc.write_wakeup != NULL)) | 365 | (tty->ldisc.write_wakeup != NULL)) |
276 | (tty->ldisc.write_wakeup)(tty); | 366 | (tty->ldisc.write_wakeup)(tty); |
277 | 367 | ||
@@ -281,9 +371,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data, | |||
281 | * writes. | 371 | * writes. |
282 | */ | 372 | */ |
283 | 373 | ||
284 | if(waitqueue_active(&tty->write_wait)) | 374 | if (waitqueue_active(&tty->write_wait)) |
285 | wake_up_interruptible(&tty->write_wait); | 375 | wake_up_interruptible(&tty->write_wait); |
286 | return(IRQ_HANDLED); | 376 | return IRQ_HANDLED; |
287 | } | 377 | } |
288 | 378 | ||
289 | int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) | 379 | int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) |
@@ -292,15 +382,18 @@ int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) | |||
292 | struct line_driver *driver = line->driver; | 382 | struct line_driver *driver = line->driver; |
293 | int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; | 383 | int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; |
294 | 384 | ||
295 | if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, | 385 | if (input) |
386 | err = um_request_irq(driver->read_irq, fd, IRQ_READ, | ||
296 | line_interrupt, flags, | 387 | line_interrupt, flags, |
297 | driver->read_irq_name, tty); | 388 | driver->read_irq_name, tty); |
298 | if(err) return(err); | 389 | if (err) |
299 | if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, | 390 | return err; |
391 | if (output) | ||
392 | err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, | ||
300 | line_write_interrupt, flags, | 393 | line_write_interrupt, flags, |
301 | driver->write_irq_name, tty); | 394 | driver->write_irq_name, tty); |
302 | line->have_irq = 1; | 395 | line->have_irq = 1; |
303 | return(err); | 396 | return err; |
304 | } | 397 | } |
305 | 398 | ||
306 | void line_disable(struct tty_struct *tty, int current_irq) | 399 | void line_disable(struct tty_struct *tty, int current_irq) |
@@ -336,7 +429,9 @@ int line_open(struct line *lines, struct tty_struct *tty, | |||
336 | line = &lines[tty->index]; | 429 | line = &lines[tty->index]; |
337 | tty->driver_data = line; | 430 | tty->driver_data = line; |
338 | 431 | ||
339 | down(&line->sem); | 432 | /* The IRQ which takes this lock is not yet enabled and won't be run |
433 | * before the end, so we don't need to use spin_lock_irq.*/ | ||
434 | spin_lock(&line->lock); | ||
340 | if (tty->count == 1) { | 435 | if (tty->count == 1) { |
341 | if (!line->valid) { | 436 | if (!line->valid) { |
342 | err = -ENODEV; | 437 | err = -ENODEV; |
@@ -349,6 +444,7 @@ int line_open(struct line *lines, struct tty_struct *tty, | |||
349 | err = open_chan(&line->chan_list); | 444 | err = open_chan(&line->chan_list); |
350 | if(err) goto out; | 445 | if(err) goto out; |
351 | } | 446 | } |
447 | /* Here the interrupt is registered.*/ | ||
352 | enable_chan(&line->chan_list, tty); | 448 | enable_chan(&line->chan_list, tty); |
353 | INIT_WORK(&line->task, line_timer_cb, tty); | 449 | INIT_WORK(&line->task, line_timer_cb, tty); |
354 | } | 450 | } |
@@ -362,21 +458,27 @@ int line_open(struct line *lines, struct tty_struct *tty, | |||
362 | line->count++; | 458 | line->count++; |
363 | 459 | ||
364 | out: | 460 | out: |
365 | up(&line->sem); | 461 | spin_unlock(&line->lock); |
366 | return(err); | 462 | return err; |
367 | } | 463 | } |
368 | 464 | ||
369 | void line_close(struct tty_struct *tty, struct file * filp) | 465 | void line_close(struct tty_struct *tty, struct file * filp) |
370 | { | 466 | { |
371 | struct line *line = tty->driver_data; | 467 | struct line *line = tty->driver_data; |
372 | 468 | ||
373 | down(&line->sem); | 469 | /* XXX: I assume this should be called in process context, not with interrupt |
470 | * disabled!*/ | ||
471 | spin_lock_irq(&line->lock); | ||
472 | |||
473 | /* We ignore the error anyway! */ | ||
474 | flush_buffer(line); | ||
475 | |||
374 | line->count--; | 476 | line->count--; |
375 | if (tty->count == 1) { | 477 | if (tty->count == 1) { |
376 | line_disable(tty, -1); | 478 | line_disable(tty, -1); |
377 | tty->driver_data = NULL; | 479 | tty->driver_data = NULL; |
378 | } | 480 | } |
379 | up(&line->sem); | 481 | spin_unlock_irq(&line->lock); |
380 | } | 482 | } |
381 | 483 | ||
382 | void close_lines(struct line *lines, int nlines) | 484 | void close_lines(struct line *lines, int nlines) |
@@ -387,31 +489,41 @@ void close_lines(struct line *lines, int nlines) | |||
387 | close_chan(&lines[i].chan_list); | 489 | close_chan(&lines[i].chan_list); |
388 | } | 490 | } |
389 | 491 | ||
390 | int line_setup(struct line *lines, int num, char *init, int all_allowed) | 492 | /* Common setup code for both startup command line and mconsole initialization. |
493 | * @lines contains the the array (of size @num) to modify; | ||
494 | * @init is the setup string; | ||
495 | * @all_allowed is a boolean saying if we can setup the whole @lines | ||
496 | * at once. For instance, it will be usually true for startup init. (where we | ||
497 | * can use con=xterm) and false for mconsole.*/ | ||
498 | |||
499 | int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed) | ||
391 | { | 500 | { |
392 | int i, n; | 501 | int i, n; |
393 | char *end; | 502 | char *end; |
394 | 503 | ||
395 | if(*init == '=') n = -1; | 504 | if(*init == '=') { |
396 | else { | 505 | /* We said con=/ssl= instead of con#=, so we are configuring all |
506 | * consoles at once.*/ | ||
507 | n = -1; | ||
508 | } else { | ||
397 | n = simple_strtoul(init, &end, 0); | 509 | n = simple_strtoul(init, &end, 0); |
398 | if(*end != '='){ | 510 | if(*end != '='){ |
399 | printk(KERN_ERR "line_setup failed to parse \"%s\"\n", | 511 | printk(KERN_ERR "line_setup failed to parse \"%s\"\n", |
400 | init); | 512 | init); |
401 | return(0); | 513 | return 0; |
402 | } | 514 | } |
403 | init = end; | 515 | init = end; |
404 | } | 516 | } |
405 | init++; | 517 | init++; |
406 | if((n >= 0) && (n >= num)){ | 518 | |
519 | if (n >= (signed int) num) { | ||
407 | printk("line_setup - %d out of range ((0 ... %d) allowed)\n", | 520 | printk("line_setup - %d out of range ((0 ... %d) allowed)\n", |
408 | n, num - 1); | 521 | n, num - 1); |
409 | return(0); | 522 | return 0; |
410 | } | 523 | } else if (n >= 0){ |
411 | else if (n >= 0){ | ||
412 | if (lines[n].count > 0) { | 524 | if (lines[n].count > 0) { |
413 | printk("line_setup - device %d is open\n", n); | 525 | printk("line_setup - device %d is open\n", n); |
414 | return(0); | 526 | return 0; |
415 | } | 527 | } |
416 | if (lines[n].init_pri <= INIT_ONE){ | 528 | if (lines[n].init_pri <= INIT_ONE){ |
417 | lines[n].init_pri = INIT_ONE; | 529 | lines[n].init_pri = INIT_ONE; |
@@ -422,13 +534,11 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed) | |||
422 | lines[n].valid = 1; | 534 | lines[n].valid = 1; |
423 | } | 535 | } |
424 | } | 536 | } |
425 | } | 537 | } else if(!all_allowed){ |
426 | else if(!all_allowed){ | ||
427 | printk("line_setup - can't configure all devices from " | 538 | printk("line_setup - can't configure all devices from " |
428 | "mconsole\n"); | 539 | "mconsole\n"); |
429 | return(0); | 540 | return 0; |
430 | } | 541 | } else { |
431 | else { | ||
432 | for(i = 0; i < num; i++){ | 542 | for(i = 0; i < num; i++){ |
433 | if(lines[i].init_pri <= INIT_ALL){ | 543 | if(lines[i].init_pri <= INIT_ALL){ |
434 | lines[i].init_pri = INIT_ALL; | 544 | lines[i].init_pri = INIT_ALL; |
@@ -440,21 +550,21 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed) | |||
440 | } | 550 | } |
441 | } | 551 | } |
442 | } | 552 | } |
443 | return(1); | 553 | return 1; |
444 | } | 554 | } |
445 | 555 | ||
446 | int line_config(struct line *lines, int num, char *str) | 556 | int line_config(struct line *lines, unsigned int num, char *str) |
447 | { | 557 | { |
448 | char *new = uml_strdup(str); | 558 | char *new = uml_strdup(str); |
449 | 559 | ||
450 | if(new == NULL){ | 560 | if(new == NULL){ |
451 | printk("line_config - uml_strdup failed\n"); | 561 | printk("line_config - uml_strdup failed\n"); |
452 | return(-ENOMEM); | 562 | return -ENOMEM; |
453 | } | 563 | } |
454 | return(!line_setup(lines, num, new, 0)); | 564 | return !line_setup(lines, num, new, 0); |
455 | } | 565 | } |
456 | 566 | ||
457 | int line_get_config(char *name, struct line *lines, int num, char *str, | 567 | int line_get_config(char *name, struct line *lines, unsigned int num, char *str, |
458 | int size, char **error_out) | 568 | int size, char **error_out) |
459 | { | 569 | { |
460 | struct line *line; | 570 | struct line *line; |
@@ -464,47 +574,33 @@ int line_get_config(char *name, struct line *lines, int num, char *str, | |||
464 | dev = simple_strtoul(name, &end, 0); | 574 | dev = simple_strtoul(name, &end, 0); |
465 | if((*end != '\0') || (end == name)){ | 575 | if((*end != '\0') || (end == name)){ |
466 | *error_out = "line_get_config failed to parse device number"; | 576 | *error_out = "line_get_config failed to parse device number"; |
467 | return(0); | 577 | return 0; |
468 | } | 578 | } |
469 | 579 | ||
470 | if((dev < 0) || (dev >= num)){ | 580 | if((dev < 0) || (dev >= num)){ |
471 | *error_out = "device number of of range"; | 581 | *error_out = "device number out of range"; |
472 | return(0); | 582 | return 0; |
473 | } | 583 | } |
474 | 584 | ||
475 | line = &lines[dev]; | 585 | line = &lines[dev]; |
476 | 586 | ||
477 | down(&line->sem); | 587 | spin_lock(&line->lock); |
478 | if(!line->valid) | 588 | if(!line->valid) |
479 | CONFIG_CHUNK(str, size, n, "none", 1); | 589 | CONFIG_CHUNK(str, size, n, "none", 1); |
480 | else if(line->count == 0) | 590 | else if(line->count == 0) |
481 | CONFIG_CHUNK(str, size, n, line->init_str, 1); | 591 | CONFIG_CHUNK(str, size, n, line->init_str, 1); |
482 | else n = chan_config_string(&line->chan_list, str, size, error_out); | 592 | else n = chan_config_string(&line->chan_list, str, size, error_out); |
483 | up(&line->sem); | 593 | spin_unlock(&line->lock); |
484 | 594 | ||
485 | return(n); | 595 | return n; |
486 | } | 596 | } |
487 | 597 | ||
488 | int line_remove(struct line *lines, int num, char *str) | 598 | int line_remove(struct line *lines, unsigned int num, char *str) |
489 | { | 599 | { |
490 | char config[sizeof("conxxxx=none\0")]; | 600 | char config[sizeof("conxxxx=none\0")]; |
491 | 601 | ||
492 | sprintf(config, "%s=none", str); | 602 | sprintf(config, "%s=none", str); |
493 | return(!line_setup(lines, num, config, 0)); | 603 | return !line_setup(lines, num, config, 0); |
494 | } | ||
495 | |||
496 | int line_write_room(struct tty_struct *tty) | ||
497 | { | ||
498 | struct line *dev = tty->driver_data; | ||
499 | int room; | ||
500 | |||
501 | if (tty->stopped) | ||
502 | return 0; | ||
503 | room = write_room(dev); | ||
504 | if (0 == room) | ||
505 | printk(KERN_DEBUG "%s: %s: no room left in buffer\n", | ||
506 | __FUNCTION__,tty->name); | ||
507 | return room; | ||
508 | } | 604 | } |
509 | 605 | ||
510 | struct tty_driver *line_register_devfs(struct lines *set, | 606 | struct tty_driver *line_register_devfs(struct lines *set, |
@@ -553,7 +649,7 @@ void lines_init(struct line *lines, int nlines) | |||
553 | for(i = 0; i < nlines; i++){ | 649 | for(i = 0; i < nlines; i++){ |
554 | line = &lines[i]; | 650 | line = &lines[i]; |
555 | INIT_LIST_HEAD(&line->chan_list); | 651 | INIT_LIST_HEAD(&line->chan_list); |
556 | sema_init(&line->sem, 1); | 652 | spin_lock_init(&line->lock); |
557 | if(line->init_str != NULL){ | 653 | if(line->init_str != NULL){ |
558 | line->init_str = uml_strdup(line->init_str); | 654 | line->init_str = uml_strdup(line->init_str); |
559 | if(line->init_str == NULL) | 655 | if(line->init_str == NULL) |
@@ -587,7 +683,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused) | |||
587 | "errno = %d\n", -err); | 683 | "errno = %d\n", -err); |
588 | printk("fd %d is losing SIGWINCH support\n", | 684 | printk("fd %d is losing SIGWINCH support\n", |
589 | winch->tty_fd); | 685 | winch->tty_fd); |
590 | return(IRQ_HANDLED); | 686 | return IRQ_HANDLED; |
591 | } | 687 | } |
592 | goto out; | 688 | goto out; |
593 | } | 689 | } |
@@ -603,7 +699,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused) | |||
603 | out: | 699 | out: |
604 | if(winch->fd != -1) | 700 | if(winch->fd != -1) |
605 | reactivate_fd(winch->fd, WINCH_IRQ); | 701 | reactivate_fd(winch->fd, WINCH_IRQ); |
606 | return(IRQ_HANDLED); | 702 | return IRQ_HANDLED; |
607 | } | 703 | } |
608 | 704 | ||
609 | DECLARE_MUTEX(winch_handler_sem); | 705 | DECLARE_MUTEX(winch_handler_sem); |
@@ -625,7 +721,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) | |||
625 | .pid = pid, | 721 | .pid = pid, |
626 | .tty = tty }); | 722 | .tty = tty }); |
627 | list_add(&winch->list, &winch_handlers); | 723 | list_add(&winch->list, &winch_handlers); |
628 | if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, | 724 | if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, |
629 | SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, | 725 | SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, |
630 | "winch", winch) < 0) | 726 | "winch", winch) < 0) |
631 | printk("register_winch_irq - failed to register IRQ\n"); | 727 | printk("register_winch_irq - failed to register IRQ\n"); |
@@ -656,26 +752,16 @@ char *add_xterm_umid(char *base) | |||
656 | int len; | 752 | int len; |
657 | 753 | ||
658 | umid = get_umid(1); | 754 | umid = get_umid(1); |
659 | if(umid == NULL) return(base); | 755 | if(umid == NULL) |
756 | return base; | ||
660 | 757 | ||
661 | len = strlen(base) + strlen(" ()") + strlen(umid) + 1; | 758 | len = strlen(base) + strlen(" ()") + strlen(umid) + 1; |
662 | title = kmalloc(len, GFP_KERNEL); | 759 | title = kmalloc(len, GFP_KERNEL); |
663 | if(title == NULL){ | 760 | if(title == NULL){ |
664 | printk("Failed to allocate buffer for xterm title\n"); | 761 | printk("Failed to allocate buffer for xterm title\n"); |
665 | return(base); | 762 | return base; |
666 | } | 763 | } |
667 | 764 | ||
668 | snprintf(title, len, "%s (%s)", base, umid); | 765 | snprintf(title, len, "%s (%s)", base, umid); |
669 | return(title); | 766 | return title; |
670 | } | 767 | } |
671 | |||
672 | /* | ||
673 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
674 | * Emacs will notice this stuff at the end of the file and automatically | ||
675 | * adjust the settings for this buffer only. This must remain at the end | ||
676 | * of the file. | ||
677 | * --------------------------------------------------------------------------- | ||
678 | * Local variables: | ||
679 | * c-file-style: "linux" | ||
680 | * End: | ||
681 | */ | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index c5839c3141f8..a2bac429f3d4 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -107,11 +107,6 @@ int ssl_open(struct tty_struct *tty, struct file *filp) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | #if 0 | 109 | #if 0 |
110 | static int ssl_chars_in_buffer(struct tty_struct *tty) | ||
111 | { | ||
112 | return(0); | ||
113 | } | ||
114 | |||
115 | static void ssl_flush_buffer(struct tty_struct *tty) | 110 | static void ssl_flush_buffer(struct tty_struct *tty) |
116 | { | 111 | { |
117 | return; | 112 | return; |
@@ -149,11 +144,11 @@ static struct tty_operations ssl_ops = { | |||
149 | .put_char = line_put_char, | 144 | .put_char = line_put_char, |
150 | .write_room = line_write_room, | 145 | .write_room = line_write_room, |
151 | .chars_in_buffer = line_chars_in_buffer, | 146 | .chars_in_buffer = line_chars_in_buffer, |
147 | .flush_buffer = line_flush_buffer, | ||
148 | .flush_chars = line_flush_chars, | ||
152 | .set_termios = line_set_termios, | 149 | .set_termios = line_set_termios, |
153 | .ioctl = line_ioctl, | 150 | .ioctl = line_ioctl, |
154 | #if 0 | 151 | #if 0 |
155 | .flush_chars = ssl_flush_chars, | ||
156 | .flush_buffer = ssl_flush_buffer, | ||
157 | .throttle = ssl_throttle, | 152 | .throttle = ssl_throttle, |
158 | .unthrottle = ssl_unthrottle, | 153 | .unthrottle = ssl_unthrottle, |
159 | .stop = ssl_stop, | 154 | .stop = ssl_stop, |
@@ -171,10 +166,11 @@ static void ssl_console_write(struct console *c, const char *string, | |||
171 | unsigned len) | 166 | unsigned len) |
172 | { | 167 | { |
173 | struct line *line = &serial_lines[c->index]; | 168 | struct line *line = &serial_lines[c->index]; |
169 | unsigned long flags; | ||
174 | 170 | ||
175 | down(&line->sem); | 171 | spin_lock_irqsave(&line->lock, flags); |
176 | console_write_chan(&line->chan_list, string, len); | 172 | console_write_chan(&line->chan_list, string, len); |
177 | up(&line->sem); | 173 | spin_unlock_irqrestore(&line->lock, flags); |
178 | } | 174 | } |
179 | 175 | ||
180 | static struct tty_driver *ssl_console_device(struct console *c, int *index) | 176 | static struct tty_driver *ssl_console_device(struct console *c, int *index) |
@@ -238,14 +234,3 @@ static int ssl_chan_setup(char *str) | |||
238 | 234 | ||
239 | __setup("ssl", ssl_chan_setup); | 235 | __setup("ssl", ssl_chan_setup); |
240 | __channel_help(ssl_chan_setup, "ssl"); | 236 | __channel_help(ssl_chan_setup, "ssl"); |
241 | |||
242 | /* | ||
243 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
244 | * Emacs will notice this stuff at the end of the file and automatically | ||
245 | * adjust the settings for this buffer only. This must remain at the end | ||
246 | * of the file. | ||
247 | * --------------------------------------------------------------------------- | ||
248 | * Local variables: | ||
249 | * c-file-style: "linux" | ||
250 | * End: | ||
251 | */ | ||
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index e604d7c87695..361d0be342b3 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -116,8 +116,11 @@ static struct tty_operations console_ops = { | |||
116 | .open = con_open, | 116 | .open = con_open, |
117 | .close = line_close, | 117 | .close = line_close, |
118 | .write = line_write, | 118 | .write = line_write, |
119 | .put_char = line_put_char, | ||
119 | .write_room = line_write_room, | 120 | .write_room = line_write_room, |
120 | .chars_in_buffer = line_chars_in_buffer, | 121 | .chars_in_buffer = line_chars_in_buffer, |
122 | .flush_buffer = line_flush_buffer, | ||
123 | .flush_chars = line_flush_chars, | ||
121 | .set_termios = line_set_termios, | 124 | .set_termios = line_set_termios, |
122 | .ioctl = line_ioctl, | 125 | .ioctl = line_ioctl, |
123 | }; | 126 | }; |
@@ -126,10 +129,11 @@ static void uml_console_write(struct console *console, const char *string, | |||
126 | unsigned len) | 129 | unsigned len) |
127 | { | 130 | { |
128 | struct line *line = &vts[console->index]; | 131 | struct line *line = &vts[console->index]; |
132 | unsigned long flags; | ||
129 | 133 | ||
130 | down(&line->sem); | 134 | spin_lock_irqsave(&line->lock, flags); |
131 | console_write_chan(&line->chan_list, string, len); | 135 | console_write_chan(&line->chan_list, string, len); |
132 | up(&line->sem); | 136 | spin_unlock_irqrestore(&line->lock, flags); |
133 | } | 137 | } |
134 | 138 | ||
135 | static struct tty_driver *uml_console_device(struct console *c, int *index) | 139 | static struct tty_driver *uml_console_device(struct console *c, int *index) |
@@ -192,14 +196,3 @@ static int console_chan_setup(char *str) | |||
192 | } | 196 | } |
193 | __setup("con", console_chan_setup); | 197 | __setup("con", console_chan_setup); |
194 | __channel_help(console_chan_setup, "con"); | 198 | __channel_help(console_chan_setup, "con"); |
195 | |||
196 | /* | ||
197 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
198 | * Emacs will notice this stuff at the end of the file and automatically | ||
199 | * adjust the settings for this buffer only. This must remain at the end | ||
200 | * of the file. | ||
201 | * --------------------------------------------------------------------------- | ||
202 | * Local variables: | ||
203 | * c-file-style: "linux" | ||
204 | * End: | ||
205 | */ | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 4d8b165bfa48..9a56ff94308d 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -156,6 +156,7 @@ static struct gendisk *fake_gendisk[MAX_DEV]; | |||
156 | static struct openflags global_openflags = OPEN_FLAGS; | 156 | static struct openflags global_openflags = OPEN_FLAGS; |
157 | 157 | ||
158 | struct cow { | 158 | struct cow { |
159 | /* This is the backing file, actually */ | ||
159 | char *file; | 160 | char *file; |
160 | int fd; | 161 | int fd; |
161 | unsigned long *bitmap; | 162 | unsigned long *bitmap; |
@@ -927,10 +928,14 @@ static int ubd_open(struct inode *inode, struct file *filp) | |||
927 | } | 928 | } |
928 | } | 929 | } |
929 | dev->count++; | 930 | dev->count++; |
930 | if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ | 931 | set_disk_ro(disk, !dev->openflags.w); |
932 | |||
933 | /* This should no more be needed. And it didn't work anyway to exclude | ||
934 | * read-write remounting of filesystems.*/ | ||
935 | /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ | ||
931 | if(--dev->count == 0) ubd_close(dev); | 936 | if(--dev->count == 0) ubd_close(dev); |
932 | err = -EROFS; | 937 | err = -EROFS; |
933 | } | 938 | }*/ |
934 | out: | 939 | out: |
935 | return(err); | 940 | return(err); |
936 | } | 941 | } |
@@ -1096,6 +1101,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) | |||
1096 | 1101 | ||
1097 | if(req->rq_status == RQ_INACTIVE) return(1); | 1102 | if(req->rq_status == RQ_INACTIVE) return(1); |
1098 | 1103 | ||
1104 | /* This should be impossible now */ | ||
1099 | if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ | 1105 | if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ |
1100 | printk("Write attempted on readonly ubd device %s\n", | 1106 | printk("Write attempted on readonly ubd device %s\n", |
1101 | disk->disk_name); | 1107 | disk->disk_name); |
@@ -1243,6 +1249,7 @@ static int ubd_check_remapped(int fd, unsigned long address, int is_write, | |||
1243 | 1249 | ||
1244 | /* It's a write to a ubd device */ | 1250 | /* It's a write to a ubd device */ |
1245 | 1251 | ||
1252 | /* This should be impossible now */ | ||
1246 | if(!dev->openflags.w){ | 1253 | if(!dev->openflags.w){ |
1247 | /* It's a write access on a read-only device - probably | 1254 | /* It's a write access on a read-only device - probably |
1248 | * shouldn't happen. If the kernel is trying to change | 1255 | * shouldn't happen. If the kernel is trying to change |
@@ -1605,8 +1612,7 @@ void do_io(struct io_thread_req *req) | |||
1605 | } | 1612 | } |
1606 | } while((n < len) && (n != 0)); | 1613 | } while((n < len) && (n != 0)); |
1607 | if (n < len) memset(&buf[n], 0, len - n); | 1614 | if (n < len) memset(&buf[n], 0, len - n); |
1608 | } | 1615 | } else { |
1609 | else { | ||
1610 | n = os_write_file(req->fds[bit], buf, len); | 1616 | n = os_write_file(req->fds[bit], buf, len); |
1611 | if(n != len){ | 1617 | if(n != len){ |
1612 | printk("do_io - write failed err = %d " | 1618 | printk("do_io - write failed err = %d " |
diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 6d81ecc17be5..4c5e92c04ccb 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "linux/workqueue.h" | 10 | #include "linux/workqueue.h" |
11 | #include "linux/tty.h" | 11 | #include "linux/tty.h" |
12 | #include "linux/interrupt.h" | 12 | #include "linux/interrupt.h" |
13 | #include "asm/semaphore.h" | 13 | #include "linux/spinlock.h" |
14 | #include "chan_user.h" | 14 | #include "chan_user.h" |
15 | #include "mconsole_kern.h" | 15 | #include "mconsole_kern.h" |
16 | 16 | ||
@@ -37,10 +37,18 @@ struct line { | |||
37 | struct list_head chan_list; | 37 | struct list_head chan_list; |
38 | int valid; | 38 | int valid; |
39 | int count; | 39 | int count; |
40 | struct semaphore sem; | 40 | /*This lock is actually, mostly, local to*/ |
41 | spinlock_t lock; | ||
42 | |||
43 | /* Yes, this is a real circular buffer. | ||
44 | * XXX: And this should become a struct kfifo! | ||
45 | * | ||
46 | * buffer points to a buffer allocated on demand, of length | ||
47 | * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/ | ||
41 | char *buffer; | 48 | char *buffer; |
42 | char *head; | 49 | char *head; |
43 | char *tail; | 50 | char *tail; |
51 | |||
44 | int sigio; | 52 | int sigio; |
45 | struct work_struct task; | 53 | struct work_struct task; |
46 | struct line_driver *driver; | 54 | struct line_driver *driver; |
@@ -52,7 +60,6 @@ struct line { | |||
52 | init_pri : INIT_STATIC, \ | 60 | init_pri : INIT_STATIC, \ |
53 | chan_list : { }, \ | 61 | chan_list : { }, \ |
54 | valid : 1, \ | 62 | valid : 1, \ |
55 | sem : { }, \ | ||
56 | buffer : NULL, \ | 63 | buffer : NULL, \ |
57 | head : NULL, \ | 64 | head : NULL, \ |
58 | tail : NULL, \ | 65 | tail : NULL, \ |
@@ -69,15 +76,18 @@ struct lines { | |||
69 | extern void line_close(struct tty_struct *tty, struct file * filp); | 76 | extern void line_close(struct tty_struct *tty, struct file * filp); |
70 | extern int line_open(struct line *lines, struct tty_struct *tty, | 77 | extern int line_open(struct line *lines, struct tty_struct *tty, |
71 | struct chan_opts *opts); | 78 | struct chan_opts *opts); |
72 | extern int line_setup(struct line *lines, int num, char *init, | 79 | extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, |
73 | int all_allowed); | 80 | int all_allowed); |
74 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); | 81 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); |
75 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); | 82 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); |
76 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); | 83 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); |
77 | extern int line_chars_in_buffer(struct tty_struct *tty); | 84 | extern int line_chars_in_buffer(struct tty_struct *tty); |
85 | extern void line_flush_buffer(struct tty_struct *tty); | ||
86 | extern void line_flush_chars(struct tty_struct *tty); | ||
78 | extern int line_write_room(struct tty_struct *tty); | 87 | extern int line_write_room(struct tty_struct *tty); |
79 | extern int line_ioctl(struct tty_struct *tty, struct file * file, | 88 | extern int line_ioctl(struct tty_struct *tty, struct file * file, |
80 | unsigned int cmd, unsigned long arg); | 89 | unsigned int cmd, unsigned long arg); |
90 | |||
81 | extern char *add_xterm_umid(char *base); | 91 | extern char *add_xterm_umid(char *base); |
82 | extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); | 92 | extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); |
83 | extern void line_close_chan(struct line *line); | 93 | extern void line_close_chan(struct line *line); |
@@ -89,20 +99,10 @@ extern struct tty_driver * line_register_devfs(struct lines *set, | |||
89 | int nlines); | 99 | int nlines); |
90 | extern void lines_init(struct line *lines, int nlines); | 100 | extern void lines_init(struct line *lines, int nlines); |
91 | extern void close_lines(struct line *lines, int nlines); | 101 | extern void close_lines(struct line *lines, int nlines); |
92 | extern int line_config(struct line *lines, int num, char *str); | 102 | |
93 | extern int line_remove(struct line *lines, int num, char *str); | 103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); |
94 | extern int line_get_config(char *dev, struct line *lines, int num, char *str, | 104 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str); |
105 | extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, | ||
95 | int size, char **error_out); | 106 | int size, char **error_out); |
96 | 107 | ||
97 | #endif | 108 | #endif |
98 | |||
99 | /* | ||
100 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
101 | * Emacs will notice this stuff at the end of the file and automatically | ||
102 | * adjust the settings for this buffer only. This must remain at the end | ||
103 | * of the file. | ||
104 | * --------------------------------------------------------------------------- | ||
105 | * Local variables: | ||
106 | * c-file-style: "linux" | ||
107 | * End: | ||
108 | */ | ||
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h index 5db81ec9087d..be0a3e3469eb 100644 --- a/arch/um/include/sysdep-i386/syscalls.h +++ b/arch/um/include/sysdep-i386/syscalls.h | |||
@@ -22,102 +22,3 @@ extern syscall_handler_t old_mmap_i386; | |||
22 | extern long sys_mmap2(unsigned long addr, unsigned long len, | 22 | extern long sys_mmap2(unsigned long addr, unsigned long len, |
23 | unsigned long prot, unsigned long flags, | 23 | unsigned long prot, unsigned long flags, |
24 | unsigned long fd, unsigned long pgoff); | 24 | unsigned long fd, unsigned long pgoff); |
25 | |||
26 | /* On i386 they choose a meaningless naming.*/ | ||
27 | #define __NR_kexec_load __NR_sys_kexec_load | ||
28 | |||
29 | #define ARCH_SYSCALLS \ | ||
30 | [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \ | ||
31 | [ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
32 | [ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \ | ||
33 | [ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \ | ||
34 | [ __NR_stime ] = um_stime, \ | ||
35 | [ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \ | ||
36 | [ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
37 | [ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
38 | [ __NR_nice ] = (syscall_handler_t *) sys_nice, \ | ||
39 | [ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
40 | [ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
41 | [ __NR_signal ] = (syscall_handler_t *) sys_signal, \ | ||
42 | [ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
43 | [ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
44 | [ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
45 | [ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \ | ||
46 | [ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \ | ||
47 | [ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \ | ||
48 | [ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \ | ||
49 | [ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \ | ||
50 | [ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \ | ||
51 | [ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \ | ||
52 | [ __NR_readdir ] = old_readdir, \ | ||
53 | [ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
54 | [ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \ | ||
55 | [ __NR_olduname ] = (syscall_handler_t *) sys_uname, \ | ||
56 | [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
57 | [ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
58 | [ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \ | ||
59 | [ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \ | ||
60 | [ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \ | ||
61 | [ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \ | ||
62 | [ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \ | ||
63 | [ __NR__newselect ] = (syscall_handler_t *) sys_select, \ | ||
64 | [ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
65 | [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \ | ||
66 | [ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \ | ||
67 | [ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \ | ||
68 | [ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \ | ||
69 | [ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \ | ||
70 | [ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \ | ||
71 | [ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \ | ||
72 | [ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \ | ||
73 | [ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \ | ||
74 | [ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \ | ||
75 | [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \ | ||
76 | [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \ | ||
77 | [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \ | ||
78 | [ __NR_select ] = (syscall_handler_t *) old_select, \ | ||
79 | [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
80 | [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \ | ||
81 | [ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \ | ||
82 | [ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \ | ||
83 | [ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \ | ||
84 | [ __NR_geteuid32 ] = (syscall_handler_t *) sys_geteuid, \ | ||
85 | [ __NR_getegid32 ] = (syscall_handler_t *) sys_getegid, \ | ||
86 | [ __NR_setreuid32 ] = (syscall_handler_t *) sys_setreuid, \ | ||
87 | [ __NR_setregid32 ] = (syscall_handler_t *) sys_setregid, \ | ||
88 | [ __NR_getgroups32 ] = (syscall_handler_t *) sys_getgroups, \ | ||
89 | [ __NR_setgroups32 ] = (syscall_handler_t *) sys_setgroups, \ | ||
90 | [ __NR_fchown32 ] = (syscall_handler_t *) sys_fchown, \ | ||
91 | [ __NR_setresuid32 ] = (syscall_handler_t *) sys_setresuid, \ | ||
92 | [ __NR_getresuid32 ] = (syscall_handler_t *) sys_getresuid, \ | ||
93 | [ __NR_setresgid32 ] = (syscall_handler_t *) sys_setresgid, \ | ||
94 | [ __NR_getresgid32 ] = (syscall_handler_t *) sys_getresgid, \ | ||
95 | [ __NR_chown32 ] = (syscall_handler_t *) sys_chown, \ | ||
96 | [ __NR_setuid32 ] = (syscall_handler_t *) sys_setuid, \ | ||
97 | [ __NR_setgid32 ] = (syscall_handler_t *) sys_setgid, \ | ||
98 | [ __NR_setfsuid32 ] = (syscall_handler_t *) sys_setfsuid, \ | ||
99 | [ __NR_setfsgid32 ] = (syscall_handler_t *) sys_setfsgid, \ | ||
100 | [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \ | ||
101 | [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \ | ||
102 | [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \ | ||
103 | [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
104 | [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
105 | [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
106 | [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
107 | [ 251 ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
108 | [ 285 ] = (syscall_handler_t *) sys_ni_syscall, | ||
109 | |||
110 | /* 222 doesn't yet have a name in include/asm-i386/unistd.h */ | ||
111 | |||
112 | #define LAST_ARCH_SYSCALL 285 | ||
113 | |||
114 | /* | ||
115 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
116 | * Emacs will notice this stuff at the end of the file and automatically | ||
117 | * adjust the settings for this buffer only. This must remain at the end | ||
118 | * of the file. | ||
119 | * --------------------------------------------------------------------------- | ||
120 | * Local variables: | ||
121 | * c-file-style: "linux" | ||
122 | * End: | ||
123 | */ | ||
diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h index b187a4157ff3..67923cca5691 100644 --- a/arch/um/include/sysdep-x86_64/syscalls.h +++ b/arch/um/include/sysdep-x86_64/syscalls.h | |||
@@ -26,66 +26,9 @@ extern syscall_handler_t *ia32_sys_call_table[]; | |||
26 | extern long old_mmap(unsigned long addr, unsigned long len, | 26 | extern long old_mmap(unsigned long addr, unsigned long len, |
27 | unsigned long prot, unsigned long flags, | 27 | unsigned long prot, unsigned long flags, |
28 | unsigned long fd, unsigned long pgoff); | 28 | unsigned long fd, unsigned long pgoff); |
29 | extern syscall_handler_t wrap_sys_shmat; | ||
30 | extern syscall_handler_t sys_modify_ldt; | 29 | extern syscall_handler_t sys_modify_ldt; |
31 | extern syscall_handler_t sys_arch_prctl; | 30 | extern syscall_handler_t sys_arch_prctl; |
32 | 31 | ||
33 | #define ARCH_SYSCALLS \ | 32 | #define NR_syscalls (__NR_syscall_max + 1) |
34 | [ __NR_mmap ] = (syscall_handler_t *) old_mmap, \ | ||
35 | [ __NR_select ] = (syscall_handler_t *) sys_select, \ | ||
36 | [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \ | ||
37 | [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \ | ||
38 | [ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \ | ||
39 | [ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \ | ||
40 | [ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \ | ||
41 | [ __NR_semop ] = (syscall_handler_t *) sys_semop, \ | ||
42 | [ __NR_semget ] = (syscall_handler_t *) sys_semget, \ | ||
43 | [ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \ | ||
44 | [ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \ | ||
45 | [ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \ | ||
46 | [ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \ | ||
47 | [ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \ | ||
48 | [ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \ | ||
49 | [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \ | ||
50 | [ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
51 | [ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
52 | [ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
53 | [ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
54 | [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \ | ||
55 | [ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \ | ||
56 | [ __NR_socket ] = (syscall_handler_t *) sys_socket, \ | ||
57 | [ __NR_connect ] = (syscall_handler_t *) sys_connect, \ | ||
58 | [ __NR_accept ] = (syscall_handler_t *) sys_accept, \ | ||
59 | [ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \ | ||
60 | [ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \ | ||
61 | [ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \ | ||
62 | [ __NR_bind ] = (syscall_handler_t *) sys_bind, \ | ||
63 | [ __NR_listen ] = (syscall_handler_t *) sys_listen, \ | ||
64 | [ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \ | ||
65 | [ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \ | ||
66 | [ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \ | ||
67 | [ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \ | ||
68 | [ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \ | ||
69 | [ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \ | ||
70 | [ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \ | ||
71 | [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
72 | [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
73 | [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \ | ||
74 | [ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \ | ||
75 | [ 251 ] = (syscall_handler_t *) sys_ni_syscall, | ||
76 | |||
77 | #define LAST_ARCH_SYSCALL 251 | ||
78 | #define NR_syscalls 1024 | ||
79 | 33 | ||
80 | #endif | 34 | #endif |
81 | |||
82 | /* | ||
83 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
84 | * Emacs will notice this stuff at the end of the file and automatically | ||
85 | * adjust the settings for this buffer only. This must remain at the end | ||
86 | * of the file. | ||
87 | * --------------------------------------------------------------------------- | ||
88 | * Local variables: | ||
89 | * c-file-style: "linux" | ||
90 | * End: | ||
91 | */ | ||
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index dc796c1bf39e..246f0e7fb4cc 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -10,7 +10,7 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o \ | |||
10 | helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ | 10 | helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ |
11 | physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ | 11 | physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ |
12 | sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ | 12 | sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ |
13 | syscall_kern.o sysrq.o sys_call_table.o tempfile.o time.o time_kern.o \ | 13 | syscall_kern.o sysrq.o tempfile.o time.o time_kern.o \ |
14 | tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ | 14 | tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ |
15 | user_util.o | 15 | user_util.o |
16 | 16 | ||
@@ -53,6 +53,7 @@ quiet_cmd_quote2 = QUOTE $@ | |||
53 | cmd_quote2 = sed -e '/CONFIG/{' \ | 53 | cmd_quote2 = sed -e '/CONFIG/{' \ |
54 | -e 's/"CONFIG"\;/""/' \ | 54 | -e 's/"CONFIG"\;/""/' \ |
55 | -e 'r $(obj)/config.tmp' \ | 55 | -e 'r $(obj)/config.tmp' \ |
56 | -e 'a""\;' \ | 56 | -e 'a \' \ |
57 | -e '""\;' \ | ||
57 | -e '}' \ | 58 | -e '}' \ |
58 | $< > $@ | 59 | $< > $@ |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 1d719d5b4bb9..7a943696f950 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -161,10 +161,6 @@ void *get_current(void) | |||
161 | return(current); | 161 | return(current); |
162 | } | 162 | } |
163 | 163 | ||
164 | void prepare_to_copy(struct task_struct *tsk) | ||
165 | { | ||
166 | } | ||
167 | |||
168 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | 164 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, |
169 | unsigned long stack_top, struct task_struct * p, | 165 | unsigned long stack_top, struct task_struct * p, |
170 | struct pt_regs *regs) | 166 | struct pt_regs *regs) |
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 3a99ee6d94eb..e50e60ff5d27 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -143,7 +143,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
143 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 143 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
144 | case PTRACE_CONT: { /* restart after signal. */ | 144 | case PTRACE_CONT: { /* restart after signal. */ |
145 | ret = -EIO; | 145 | ret = -EIO; |
146 | if ((unsigned long) data > _NSIG) | 146 | if (!valid_signal(data)) |
147 | break; | 147 | break; |
148 | 148 | ||
149 | child->ptrace &= ~PT_DTRACE; | 149 | child->ptrace &= ~PT_DTRACE; |
@@ -179,7 +179,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
179 | 179 | ||
180 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 180 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
181 | ret = -EIO; | 181 | ret = -EIO; |
182 | if ((unsigned long) data > _NSIG) | 182 | if (!valid_signal(data)) |
183 | break; | 183 | break; |
184 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 184 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
185 | child->ptrace |= PT_DTRACE; | 185 | child->ptrace |= PT_DTRACE; |
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h index 11986c9b9ddf..c35620385da0 100644 --- a/arch/um/kernel/skas/include/uaccess-skas.h +++ b/arch/um/kernel/skas/include/uaccess-skas.h | |||
@@ -18,7 +18,7 @@ | |||
18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ | 18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ |
19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) | 19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) |
20 | 20 | ||
21 | static inline int verify_area_skas(int type, const void * addr, | 21 | static inline int __deprecated verify_area_skas(int type, const void * addr, |
22 | unsigned long size) | 22 | unsigned long size) |
23 | { | 23 | { |
24 | return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); | 24 | return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); |
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 7575ec489b63..f7da9d027672 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/compiler.h" | ||
6 | #include "linux/stddef.h" | 7 | #include "linux/stddef.h" |
7 | #include "linux/kernel.h" | 8 | #include "linux/kernel.h" |
8 | #include "linux/string.h" | 9 | #include "linux/string.h" |
@@ -61,8 +62,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) | |||
61 | void *arg; | 62 | void *arg; |
62 | int *res; | 63 | int *res; |
63 | 64 | ||
64 | /* Some old gccs recognize __va_copy, but not va_copy */ | 65 | va_copy(args, *(va_list *)arg_ptr); |
65 | __va_copy(args, *(va_list *)arg_ptr); | ||
66 | addr = va_arg(args, unsigned long); | 66 | addr = va_arg(args, unsigned long); |
67 | len = va_arg(args, int); | 67 | len = va_arg(args, int); |
68 | is_write = va_arg(args, int); | 68 | is_write = va_arg(args, int); |
diff --git a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c deleted file mode 100644 index 7fc06c85b29d..000000000000 --- a/arch/um/kernel/sys_call_table.c +++ /dev/null | |||
@@ -1,276 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) | ||
3 | * Copyright 2003 PathScale, Inc. | ||
4 | * Licensed under the GPL | ||
5 | */ | ||
6 | |||
7 | #include "linux/config.h" | ||
8 | #include "linux/unistd.h" | ||
9 | #include "linux/sys.h" | ||
10 | #include "linux/swap.h" | ||
11 | #include "linux/syscalls.h" | ||
12 | #include "linux/sysctl.h" | ||
13 | #include "asm/signal.h" | ||
14 | #include "sysdep/syscalls.h" | ||
15 | #include "kern_util.h" | ||
16 | |||
17 | #ifdef CONFIG_NFSD | ||
18 | #define NFSSERVCTL sys_nfsservctl | ||
19 | #else | ||
20 | #define NFSSERVCTL sys_ni_syscall | ||
21 | #endif | ||
22 | |||
23 | #define LAST_GENERIC_SYSCALL __NR_keyctl | ||
24 | |||
25 | #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL | ||
26 | #define LAST_SYSCALL LAST_GENERIC_SYSCALL | ||
27 | #else | ||
28 | #define LAST_SYSCALL LAST_ARCH_SYSCALL | ||
29 | #endif | ||
30 | |||
31 | extern syscall_handler_t sys_fork; | ||
32 | extern syscall_handler_t sys_execve; | ||
33 | extern syscall_handler_t um_time; | ||
34 | extern syscall_handler_t um_stime; | ||
35 | extern syscall_handler_t sys_pipe; | ||
36 | extern syscall_handler_t sys_olduname; | ||
37 | extern syscall_handler_t sys_sigaction; | ||
38 | extern syscall_handler_t sys_sigsuspend; | ||
39 | extern syscall_handler_t old_readdir; | ||
40 | extern syscall_handler_t sys_uname; | ||
41 | extern syscall_handler_t sys_ipc; | ||
42 | extern syscall_handler_t sys_sigreturn; | ||
43 | extern syscall_handler_t sys_clone; | ||
44 | extern syscall_handler_t sys_rt_sigreturn; | ||
45 | extern syscall_handler_t sys_sigaltstack; | ||
46 | extern syscall_handler_t sys_vfork; | ||
47 | extern syscall_handler_t old_select; | ||
48 | extern syscall_handler_t sys_modify_ldt; | ||
49 | extern syscall_handler_t sys_rt_sigsuspend; | ||
50 | extern syscall_handler_t sys_mbind; | ||
51 | extern syscall_handler_t sys_get_mempolicy; | ||
52 | extern syscall_handler_t sys_set_mempolicy; | ||
53 | extern syscall_handler_t sys_sys_setaltroot; | ||
54 | |||
55 | syscall_handler_t *sys_call_table[] = { | ||
56 | [ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall, | ||
57 | [ __NR_exit ] = (syscall_handler_t *) sys_exit, | ||
58 | [ __NR_fork ] = (syscall_handler_t *) sys_fork, | ||
59 | [ __NR_read ] = (syscall_handler_t *) sys_read, | ||
60 | [ __NR_write ] = (syscall_handler_t *) sys_write, | ||
61 | |||
62 | /* These three are declared differently in asm/unistd.h */ | ||
63 | [ __NR_open ] = (syscall_handler_t *) sys_open, | ||
64 | [ __NR_close ] = (syscall_handler_t *) sys_close, | ||
65 | [ __NR_creat ] = (syscall_handler_t *) sys_creat, | ||
66 | [ __NR_link ] = (syscall_handler_t *) sys_link, | ||
67 | [ __NR_unlink ] = (syscall_handler_t *) sys_unlink, | ||
68 | [ __NR_execve ] = (syscall_handler_t *) sys_execve, | ||
69 | |||
70 | /* declared differently in kern_util.h */ | ||
71 | [ __NR_chdir ] = (syscall_handler_t *) sys_chdir, | ||
72 | [ __NR_time ] = um_time, | ||
73 | [ __NR_mknod ] = (syscall_handler_t *) sys_mknod, | ||
74 | [ __NR_chmod ] = (syscall_handler_t *) sys_chmod, | ||
75 | [ __NR_lchown ] = (syscall_handler_t *) sys_lchown16, | ||
76 | [ __NR_lseek ] = (syscall_handler_t *) sys_lseek, | ||
77 | [ __NR_getpid ] = (syscall_handler_t *) sys_getpid, | ||
78 | [ __NR_mount ] = (syscall_handler_t *) sys_mount, | ||
79 | [ __NR_setuid ] = (syscall_handler_t *) sys_setuid16, | ||
80 | [ __NR_getuid ] = (syscall_handler_t *) sys_getuid16, | ||
81 | [ __NR_ptrace ] = (syscall_handler_t *) sys_ptrace, | ||
82 | [ __NR_alarm ] = (syscall_handler_t *) sys_alarm, | ||
83 | [ __NR_pause ] = (syscall_handler_t *) sys_pause, | ||
84 | [ __NR_utime ] = (syscall_handler_t *) sys_utime, | ||
85 | [ __NR_access ] = (syscall_handler_t *) sys_access, | ||
86 | [ __NR_sync ] = (syscall_handler_t *) sys_sync, | ||
87 | [ __NR_kill ] = (syscall_handler_t *) sys_kill, | ||
88 | [ __NR_rename ] = (syscall_handler_t *) sys_rename, | ||
89 | [ __NR_mkdir ] = (syscall_handler_t *) sys_mkdir, | ||
90 | [ __NR_rmdir ] = (syscall_handler_t *) sys_rmdir, | ||
91 | |||
92 | /* Declared differently in asm/unistd.h */ | ||
93 | [ __NR_dup ] = (syscall_handler_t *) sys_dup, | ||
94 | [ __NR_pipe ] = (syscall_handler_t *) sys_pipe, | ||
95 | [ __NR_times ] = (syscall_handler_t *) sys_times, | ||
96 | [ __NR_brk ] = (syscall_handler_t *) sys_brk, | ||
97 | [ __NR_setgid ] = (syscall_handler_t *) sys_setgid16, | ||
98 | [ __NR_getgid ] = (syscall_handler_t *) sys_getgid16, | ||
99 | [ __NR_geteuid ] = (syscall_handler_t *) sys_geteuid16, | ||
100 | [ __NR_getegid ] = (syscall_handler_t *) sys_getegid16, | ||
101 | [ __NR_acct ] = (syscall_handler_t *) sys_acct, | ||
102 | [ __NR_umount2 ] = (syscall_handler_t *) sys_umount, | ||
103 | [ __NR_ioctl ] = (syscall_handler_t *) sys_ioctl, | ||
104 | [ __NR_fcntl ] = (syscall_handler_t *) sys_fcntl, | ||
105 | [ __NR_setpgid ] = (syscall_handler_t *) sys_setpgid, | ||
106 | [ __NR_umask ] = (syscall_handler_t *) sys_umask, | ||
107 | [ __NR_chroot ] = (syscall_handler_t *) sys_chroot, | ||
108 | [ __NR_ustat ] = (syscall_handler_t *) sys_ustat, | ||
109 | [ __NR_dup2 ] = (syscall_handler_t *) sys_dup2, | ||
110 | [ __NR_getppid ] = (syscall_handler_t *) sys_getppid, | ||
111 | [ __NR_getpgrp ] = (syscall_handler_t *) sys_getpgrp, | ||
112 | [ __NR_setsid ] = (syscall_handler_t *) sys_setsid, | ||
113 | [ __NR_setreuid ] = (syscall_handler_t *) sys_setreuid16, | ||
114 | [ __NR_setregid ] = (syscall_handler_t *) sys_setregid16, | ||
115 | [ __NR_sethostname ] = (syscall_handler_t *) sys_sethostname, | ||
116 | [ __NR_setrlimit ] = (syscall_handler_t *) sys_setrlimit, | ||
117 | [ __NR_getrlimit ] = (syscall_handler_t *) sys_old_getrlimit, | ||
118 | [ __NR_getrusage ] = (syscall_handler_t *) sys_getrusage, | ||
119 | [ __NR_gettimeofday ] = (syscall_handler_t *) sys_gettimeofday, | ||
120 | [ __NR_settimeofday ] = (syscall_handler_t *) sys_settimeofday, | ||
121 | [ __NR_getgroups ] = (syscall_handler_t *) sys_getgroups16, | ||
122 | [ __NR_setgroups ] = (syscall_handler_t *) sys_setgroups16, | ||
123 | [ __NR_symlink ] = (syscall_handler_t *) sys_symlink, | ||
124 | [ __NR_readlink ] = (syscall_handler_t *) sys_readlink, | ||
125 | [ __NR_uselib ] = (syscall_handler_t *) sys_uselib, | ||
126 | [ __NR_swapon ] = (syscall_handler_t *) sys_swapon, | ||
127 | [ __NR_reboot ] = (syscall_handler_t *) sys_reboot, | ||
128 | [ __NR_munmap ] = (syscall_handler_t *) sys_munmap, | ||
129 | [ __NR_truncate ] = (syscall_handler_t *) sys_truncate, | ||
130 | [ __NR_ftruncate ] = (syscall_handler_t *) sys_ftruncate, | ||
131 | [ __NR_fchmod ] = (syscall_handler_t *) sys_fchmod, | ||
132 | [ __NR_fchown ] = (syscall_handler_t *) sys_fchown16, | ||
133 | [ __NR_getpriority ] = (syscall_handler_t *) sys_getpriority, | ||
134 | [ __NR_setpriority ] = (syscall_handler_t *) sys_setpriority, | ||
135 | [ __NR_statfs ] = (syscall_handler_t *) sys_statfs, | ||
136 | [ __NR_fstatfs ] = (syscall_handler_t *) sys_fstatfs, | ||
137 | [ __NR_ioperm ] = (syscall_handler_t *) sys_ni_syscall, | ||
138 | [ __NR_syslog ] = (syscall_handler_t *) sys_syslog, | ||
139 | [ __NR_setitimer ] = (syscall_handler_t *) sys_setitimer, | ||
140 | [ __NR_getitimer ] = (syscall_handler_t *) sys_getitimer, | ||
141 | [ __NR_stat ] = (syscall_handler_t *) sys_newstat, | ||
142 | [ __NR_lstat ] = (syscall_handler_t *) sys_newlstat, | ||
143 | [ __NR_fstat ] = (syscall_handler_t *) sys_newfstat, | ||
144 | [ __NR_vhangup ] = (syscall_handler_t *) sys_vhangup, | ||
145 | [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4, | ||
146 | [ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff, | ||
147 | [ __NR_sysinfo ] = (syscall_handler_t *) sys_sysinfo, | ||
148 | [ __NR_fsync ] = (syscall_handler_t *) sys_fsync, | ||
149 | [ __NR_clone ] = (syscall_handler_t *) sys_clone, | ||
150 | [ __NR_setdomainname ] = (syscall_handler_t *) sys_setdomainname, | ||
151 | [ __NR_uname ] = (syscall_handler_t *) sys_newuname, | ||
152 | [ __NR_adjtimex ] = (syscall_handler_t *) sys_adjtimex, | ||
153 | [ __NR_mprotect ] = (syscall_handler_t *) sys_mprotect, | ||
154 | [ __NR_create_module ] = (syscall_handler_t *) sys_ni_syscall, | ||
155 | [ __NR_init_module ] = (syscall_handler_t *) sys_init_module, | ||
156 | [ __NR_delete_module ] = (syscall_handler_t *) sys_delete_module, | ||
157 | [ __NR_get_kernel_syms ] = (syscall_handler_t *) sys_ni_syscall, | ||
158 | [ __NR_quotactl ] = (syscall_handler_t *) sys_quotactl, | ||
159 | [ __NR_getpgid ] = (syscall_handler_t *) sys_getpgid, | ||
160 | [ __NR_fchdir ] = (syscall_handler_t *) sys_fchdir, | ||
161 | [ __NR_sysfs ] = (syscall_handler_t *) sys_sysfs, | ||
162 | [ __NR_personality ] = (syscall_handler_t *) sys_personality, | ||
163 | [ __NR_afs_syscall ] = (syscall_handler_t *) sys_ni_syscall, | ||
164 | [ __NR_setfsuid ] = (syscall_handler_t *) sys_setfsuid16, | ||
165 | [ __NR_setfsgid ] = (syscall_handler_t *) sys_setfsgid16, | ||
166 | [ __NR_getdents ] = (syscall_handler_t *) sys_getdents, | ||
167 | [ __NR_flock ] = (syscall_handler_t *) sys_flock, | ||
168 | [ __NR_msync ] = (syscall_handler_t *) sys_msync, | ||
169 | [ __NR_readv ] = (syscall_handler_t *) sys_readv, | ||
170 | [ __NR_writev ] = (syscall_handler_t *) sys_writev, | ||
171 | [ __NR_getsid ] = (syscall_handler_t *) sys_getsid, | ||
172 | [ __NR_fdatasync ] = (syscall_handler_t *) sys_fdatasync, | ||
173 | [ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl, | ||
174 | [ __NR_mlock ] = (syscall_handler_t *) sys_mlock, | ||
175 | [ __NR_munlock ] = (syscall_handler_t *) sys_munlock, | ||
176 | [ __NR_mlockall ] = (syscall_handler_t *) sys_mlockall, | ||
177 | [ __NR_munlockall ] = (syscall_handler_t *) sys_munlockall, | ||
178 | [ __NR_sched_setparam ] = (syscall_handler_t *) sys_sched_setparam, | ||
179 | [ __NR_sched_getparam ] = (syscall_handler_t *) sys_sched_getparam, | ||
180 | [ __NR_sched_setscheduler ] = (syscall_handler_t *) sys_sched_setscheduler, | ||
181 | [ __NR_sched_getscheduler ] = (syscall_handler_t *) sys_sched_getscheduler, | ||
182 | [ __NR_sched_yield ] = (syscall_handler_t *) yield, | ||
183 | [ __NR_sched_get_priority_max ] = (syscall_handler_t *) sys_sched_get_priority_max, | ||
184 | [ __NR_sched_get_priority_min ] = (syscall_handler_t *) sys_sched_get_priority_min, | ||
185 | [ __NR_sched_rr_get_interval ] = (syscall_handler_t *) sys_sched_rr_get_interval, | ||
186 | [ __NR_nanosleep ] = (syscall_handler_t *) sys_nanosleep, | ||
187 | [ __NR_mremap ] = (syscall_handler_t *) sys_mremap, | ||
188 | [ __NR_setresuid ] = (syscall_handler_t *) sys_setresuid16, | ||
189 | [ __NR_getresuid ] = (syscall_handler_t *) sys_getresuid16, | ||
190 | [ __NR_query_module ] = (syscall_handler_t *) sys_ni_syscall, | ||
191 | [ __NR_poll ] = (syscall_handler_t *) sys_poll, | ||
192 | [ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL, | ||
193 | [ __NR_setresgid ] = (syscall_handler_t *) sys_setresgid16, | ||
194 | [ __NR_getresgid ] = (syscall_handler_t *) sys_getresgid16, | ||
195 | [ __NR_prctl ] = (syscall_handler_t *) sys_prctl, | ||
196 | [ __NR_rt_sigreturn ] = (syscall_handler_t *) sys_rt_sigreturn, | ||
197 | [ __NR_rt_sigaction ] = (syscall_handler_t *) sys_rt_sigaction, | ||
198 | [ __NR_rt_sigprocmask ] = (syscall_handler_t *) sys_rt_sigprocmask, | ||
199 | [ __NR_rt_sigpending ] = (syscall_handler_t *) sys_rt_sigpending, | ||
200 | [ __NR_rt_sigtimedwait ] = (syscall_handler_t *) sys_rt_sigtimedwait, | ||
201 | [ __NR_rt_sigqueueinfo ] = (syscall_handler_t *) sys_rt_sigqueueinfo, | ||
202 | [ __NR_rt_sigsuspend ] = (syscall_handler_t *) sys_rt_sigsuspend, | ||
203 | [ __NR_pread64 ] = (syscall_handler_t *) sys_pread64, | ||
204 | [ __NR_pwrite64 ] = (syscall_handler_t *) sys_pwrite64, | ||
205 | [ __NR_chown ] = (syscall_handler_t *) sys_chown16, | ||
206 | [ __NR_getcwd ] = (syscall_handler_t *) sys_getcwd, | ||
207 | [ __NR_capget ] = (syscall_handler_t *) sys_capget, | ||
208 | [ __NR_capset ] = (syscall_handler_t *) sys_capset, | ||
209 | [ __NR_sigaltstack ] = (syscall_handler_t *) sys_sigaltstack, | ||
210 | [ __NR_sendfile ] = (syscall_handler_t *) sys_sendfile, | ||
211 | [ __NR_getpmsg ] = (syscall_handler_t *) sys_ni_syscall, | ||
212 | [ __NR_putpmsg ] = (syscall_handler_t *) sys_ni_syscall, | ||
213 | [ __NR_vfork ] = (syscall_handler_t *) sys_vfork, | ||
214 | [ __NR_getdents64 ] = (syscall_handler_t *) sys_getdents64, | ||
215 | [ __NR_gettid ] = (syscall_handler_t *) sys_gettid, | ||
216 | [ __NR_readahead ] = (syscall_handler_t *) sys_readahead, | ||
217 | [ __NR_setxattr ] = (syscall_handler_t *) sys_setxattr, | ||
218 | [ __NR_lsetxattr ] = (syscall_handler_t *) sys_lsetxattr, | ||
219 | [ __NR_fsetxattr ] = (syscall_handler_t *) sys_fsetxattr, | ||
220 | [ __NR_getxattr ] = (syscall_handler_t *) sys_getxattr, | ||
221 | [ __NR_lgetxattr ] = (syscall_handler_t *) sys_lgetxattr, | ||
222 | [ __NR_fgetxattr ] = (syscall_handler_t *) sys_fgetxattr, | ||
223 | [ __NR_listxattr ] = (syscall_handler_t *) sys_listxattr, | ||
224 | [ __NR_llistxattr ] = (syscall_handler_t *) sys_llistxattr, | ||
225 | [ __NR_flistxattr ] = (syscall_handler_t *) sys_flistxattr, | ||
226 | [ __NR_removexattr ] = (syscall_handler_t *) sys_removexattr, | ||
227 | [ __NR_lremovexattr ] = (syscall_handler_t *) sys_lremovexattr, | ||
228 | [ __NR_fremovexattr ] = (syscall_handler_t *) sys_fremovexattr, | ||
229 | [ __NR_tkill ] = (syscall_handler_t *) sys_tkill, | ||
230 | [ __NR_futex ] = (syscall_handler_t *) sys_futex, | ||
231 | [ __NR_sched_setaffinity ] = (syscall_handler_t *) sys_sched_setaffinity, | ||
232 | [ __NR_sched_getaffinity ] = (syscall_handler_t *) sys_sched_getaffinity, | ||
233 | [ __NR_io_setup ] = (syscall_handler_t *) sys_io_setup, | ||
234 | [ __NR_io_destroy ] = (syscall_handler_t *) sys_io_destroy, | ||
235 | [ __NR_io_getevents ] = (syscall_handler_t *) sys_io_getevents, | ||
236 | [ __NR_io_submit ] = (syscall_handler_t *) sys_io_submit, | ||
237 | [ __NR_io_cancel ] = (syscall_handler_t *) sys_io_cancel, | ||
238 | [ __NR_exit_group ] = (syscall_handler_t *) sys_exit_group, | ||
239 | [ __NR_lookup_dcookie ] = (syscall_handler_t *) sys_lookup_dcookie, | ||
240 | [ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create, | ||
241 | [ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl, | ||
242 | [ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait, | ||
243 | [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, | ||
244 | [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address, | ||
245 | [ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create, | ||
246 | [ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime, | ||
247 | [ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime, | ||
248 | [ __NR_timer_getoverrun ] = (syscall_handler_t *) sys_timer_getoverrun, | ||
249 | [ __NR_timer_delete ] = (syscall_handler_t *) sys_timer_delete, | ||
250 | [ __NR_clock_settime ] = (syscall_handler_t *) sys_clock_settime, | ||
251 | [ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime, | ||
252 | [ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres, | ||
253 | [ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep, | ||
254 | [ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill, | ||
255 | [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, | ||
256 | [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, | ||
257 | [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, | ||
258 | [ __NR_mbind ] = (syscall_handler_t *) sys_mbind, | ||
259 | [ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy, | ||
260 | [ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy, | ||
261 | [ __NR_mq_open ] = (syscall_handler_t *) sys_mq_open, | ||
262 | [ __NR_mq_unlink ] = (syscall_handler_t *) sys_mq_unlink, | ||
263 | [ __NR_mq_timedsend ] = (syscall_handler_t *) sys_mq_timedsend, | ||
264 | [ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive, | ||
265 | [ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify, | ||
266 | [ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr, | ||
267 | [ __NR_kexec_load ] = (syscall_handler_t *) sys_ni_syscall, | ||
268 | [ __NR_waitid ] = (syscall_handler_t *) sys_waitid, | ||
269 | [ __NR_add_key ] = (syscall_handler_t *) sys_add_key, | ||
270 | [ __NR_request_key ] = (syscall_handler_t *) sys_request_key, | ||
271 | [ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl, | ||
272 | |||
273 | ARCH_SYSCALLS | ||
274 | [ LAST_SYSCALL + 1 ... NR_syscalls ] = | ||
275 | (syscall_handler_t *) sys_ni_syscall | ||
276 | }; | ||
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h index f0bad010cebd..bb69d6b7d022 100644 --- a/arch/um/kernel/tt/include/uaccess-tt.h +++ b/arch/um/kernel/tt/include/uaccess-tt.h | |||
@@ -33,7 +33,7 @@ extern unsigned long uml_physmem; | |||
33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ | 33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ |
34 | (under_task_size(addr, size) || is_stack(addr, size)))) | 34 | (under_task_size(addr, size) || is_stack(addr, size)))) |
35 | 35 | ||
36 | static inline int verify_area_tt(int type, const void * addr, | 36 | static inline int __deprecated verify_area_tt(int type, const void * addr, |
37 | unsigned long size) | 37 | unsigned long size) |
38 | { | 38 | { |
39 | return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); | 39 | return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); |
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 148645b14480..9a0ad094d926 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c | |||
@@ -105,14 +105,15 @@ void init_registers(int pid) | |||
105 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", | 105 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", |
106 | err); | 106 | err); |
107 | 107 | ||
108 | errno = 0; | ||
108 | err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); | 109 | err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); |
109 | if(!err) | 110 | if(!err) |
110 | return; | 111 | return; |
112 | if(errno != EIO) | ||
113 | panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", | ||
114 | errno); | ||
111 | 115 | ||
112 | have_fpx_regs = 0; | 116 | have_fpx_regs = 0; |
113 | if(err != EIO) | ||
114 | panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", | ||
115 | err); | ||
116 | 117 | ||
117 | err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); | 118 | err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); |
118 | if(err) | 119 | if(err) |
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 71b47e618605..950781e354de 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | 1 | obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ |
2 | ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o | 2 | ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ |
3 | sys_call_table.o | ||
3 | 4 | ||
4 | obj-$(CONFIG_HIGHMEM) += highmem.o | 5 | obj-$(CONFIG_HIGHMEM) += highmem.o |
5 | obj-$(CONFIG_MODULES) += module.o | 6 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S new file mode 100644 index 000000000000..ad75c27afe38 --- /dev/null +++ b/arch/um/sys-i386/sys_call_table.S | |||
@@ -0,0 +1,16 @@ | |||
1 | #include <linux/linkage.h> | ||
2 | /* Steal i386 syscall table for our purposes, but with some slight changes.*/ | ||
3 | |||
4 | #define sys_iopl sys_ni_syscall | ||
5 | #define sys_ioperm sys_ni_syscall | ||
6 | |||
7 | #define sys_vm86old sys_ni_syscall | ||
8 | #define sys_vm86 sys_ni_syscall | ||
9 | #define sys_set_thread_area sys_ni_syscall | ||
10 | #define sys_get_thread_area sys_ni_syscall | ||
11 | |||
12 | #define sys_stime um_stime | ||
13 | #define sys_time um_time | ||
14 | #define old_mmap old_mmap_i386 | ||
15 | |||
16 | #include "../../i386/kernel/syscall_table.S" | ||
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 2129e3143559..d7ed2f7908df 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ | 7 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ |
8 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ | 8 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ |
9 | syscalls.o sysrq.o thunk.o | 9 | syscalls.o sysrq.o thunk.o syscall_table.o |
10 | 10 | ||
11 | USER_OBJS := ptrace_user.o sigcontext.o | 11 | USER_OBJS := ptrace_user.o sigcontext.o |
12 | 12 | ||
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c new file mode 100644 index 000000000000..34b2e842864f --- /dev/null +++ b/arch/um/sys-x86_64/syscall_table.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c | ||
2 | * with some changes for UML. */ | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | #include <linux/sys.h> | ||
6 | #include <linux/cache.h> | ||
7 | #include <linux/config.h> | ||
8 | |||
9 | #define __NO_STUBS | ||
10 | |||
11 | /* Below you can see, in terms of #define's, the differences between the x86-64 | ||
12 | * and the UML syscall table. */ | ||
13 | |||
14 | /* Not going to be implemented by UML, since we have no hardware. */ | ||
15 | #define stub_iopl sys_ni_syscall | ||
16 | #define sys_ioperm sys_ni_syscall | ||
17 | |||
18 | /* The UML TLS problem. Note that x86_64 does not implement this, so the below | ||
19 | * is needed only for the ia32 compatibility. */ | ||
20 | /*#define sys_set_thread_area sys_ni_syscall | ||
21 | #define sys_get_thread_area sys_ni_syscall*/ | ||
22 | |||
23 | /* For __NR_time. The x86-64 name hopefully will change from sys_time64 to | ||
24 | * sys_time (since the current situation is bogus). I've sent a patch to cleanup | ||
25 | * this. Remove below the obsoleted line. */ | ||
26 | #define sys_time64 um_time | ||
27 | #define sys_time um_time | ||
28 | |||
29 | /* On UML we call it this way ("old" means it's not mmap2) */ | ||
30 | #define sys_mmap old_mmap | ||
31 | /* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick. | ||
32 | * See arch/x86_64/kernel/sys_x86_64.c */ | ||
33 | #define sys_uname sys_uname64 | ||
34 | |||
35 | #define stub_clone sys_clone | ||
36 | #define stub_fork sys_fork | ||
37 | #define stub_vfork sys_vfork | ||
38 | #define stub_execve sys_execve | ||
39 | #define stub_rt_sigsuspend sys_rt_sigsuspend | ||
40 | #define stub_sigaltstack sys_sigaltstack | ||
41 | #define stub_rt_sigreturn sys_rt_sigreturn | ||
42 | |||
43 | #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; | ||
44 | #undef _ASM_X86_64_UNISTD_H_ | ||
45 | #include <asm-x86_64/unistd.h> | ||
46 | |||
47 | #undef __SYSCALL | ||
48 | #define __SYSCALL(nr, sym) [ nr ] = sym, | ||
49 | #undef _ASM_X86_64_UNISTD_H_ | ||
50 | |||
51 | typedef void (*sys_call_ptr_t)(void); | ||
52 | |||
53 | extern void sys_ni_syscall(void); | ||
54 | |||
55 | sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = { | ||
56 | /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ | ||
57 | [0 ... __NR_syscall_max] = &sys_ni_syscall, | ||
58 | #include <asm-x86_64/unistd.h> | ||
59 | }; | ||
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 68205a03364c..ab4b0abf8af3 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c | |||
@@ -14,11 +14,15 @@ | |||
14 | #include "asm/prctl.h" /* XXX This should get the constants from libc */ | 14 | #include "asm/prctl.h" /* XXX This should get the constants from libc */ |
15 | #include "choose-mode.h" | 15 | #include "choose-mode.h" |
16 | 16 | ||
17 | asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) | 17 | asmlinkage long sys_uname64(struct new_utsname __user * name) |
18 | { | 18 | { |
19 | unsigned long raddr; | 19 | int err; |
20 | 20 | down_read(&uts_sem); | |
21 | return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr; | 21 | err = copy_to_user(name, &system_utsname, sizeof (*name)); |
22 | up_read(&uts_sem); | ||
23 | if (personality(current->personality) == PER_LINUX32) | ||
24 | err |= copy_to_user(&name->machine, "i686", 5); | ||
25 | return err ? -EFAULT : 0; | ||
22 | } | 26 | } |
23 | 27 | ||
24 | #ifdef CONFIG_MODE_TT | 28 | #ifdef CONFIG_MODE_TT |
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c index 8fa780757dcd..4726b87f5e5a 100644 --- a/arch/v850/kernel/ptrace.c +++ b/arch/v850/kernel/ptrace.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/smp_lock.h> | 24 | #include <linux/smp_lock.h> |
25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
26 | #include <linux/signal.h> | ||
26 | 27 | ||
27 | #include <asm/errno.h> | 28 | #include <asm/errno.h> |
28 | #include <asm/ptrace.h> | 29 | #include <asm/ptrace.h> |
@@ -208,7 +209,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
208 | /* Execute a single instruction. */ | 209 | /* Execute a single instruction. */ |
209 | case PTRACE_SINGLESTEP: | 210 | case PTRACE_SINGLESTEP: |
210 | rval = -EIO; | 211 | rval = -EIO; |
211 | if ((unsigned long) data > _NSIG) | 212 | if (!valid_signal(data)) |
212 | break; | 213 | break; |
213 | 214 | ||
214 | /* Turn CHILD's single-step flag on or off. */ | 215 | /* Turn CHILD's single-step flag on or off. */ |
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index 3e838be9dbe7..75d4d2ad93b3 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S | |||
@@ -160,7 +160,7 @@ ramdisk_max: .long 0xffffffff | |||
160 | trampoline: call start_of_setup | 160 | trampoline: call start_of_setup |
161 | .align 16 | 161 | .align 16 |
162 | # The offset at this point is 0x240 | 162 | # The offset at this point is 0x240 |
163 | .space (0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff) | 163 | .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff) |
164 | # End of setup header ##################################################### | 164 | # End of setup header ##################################################### |
165 | 165 | ||
166 | start_of_setup: | 166 | start_of_setup: |
@@ -412,9 +412,9 @@ jmpe820: | |||
412 | # sizeof(e820rec). | 412 | # sizeof(e820rec). |
413 | # | 413 | # |
414 | good820: | 414 | good820: |
415 | movb (E820NR), %al # up to 32 entries | 415 | movb (E820NR), %al # up to 128 entries |
416 | cmpb $E820MAX, %al | 416 | cmpb $E820MAX, %al |
417 | jnl bail820 | 417 | jae bail820 |
418 | 418 | ||
419 | incb (E820NR) | 419 | incb (E820NR) |
420 | movw %di, %ax | 420 | movw %di, %ax |
diff --git a/arch/x86_64/ia32/vsyscall.lds b/arch/x86_64/ia32/vsyscall.lds index fa4b4dd4a9ff..f2e75ed4c6c7 100644 --- a/arch/x86_64/ia32/vsyscall.lds +++ b/arch/x86_64/ia32/vsyscall.lds | |||
@@ -36,6 +36,7 @@ SECTIONS | |||
36 | 36 | ||
37 | .text.rtsigreturn : { *(.text.rtsigreturn) } :text =0x90909090 | 37 | .text.rtsigreturn : { *(.text.rtsigreturn) } :text =0x90909090 |
38 | 38 | ||
39 | .note : { *(.note.*) } :text :note | ||
39 | .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr | 40 | .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr |
40 | .eh_frame : { KEEP (*(.eh_frame)) } :text | 41 | .eh_frame : { KEEP (*(.eh_frame)) } :text |
41 | .dynamic : { *(.dynamic) } :text :dynamic | 42 | .dynamic : { *(.dynamic) } :text :dynamic |
@@ -55,6 +56,7 @@ PHDRS | |||
55 | { | 56 | { |
56 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ | 57 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ |
57 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 58 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
59 | note PT_NOTE FLAGS(4); /* PF_R */ | ||
58 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ | 60 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ |
59 | } | 61 | } |
60 | 62 | ||
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 56516ac92e5d..7c154dfff64a 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -2,6 +2,12 @@ | |||
2 | * Handle the memory map. | 2 | * Handle the memory map. |
3 | * The functions here do the job until bootmem takes over. | 3 | * The functions here do the job until bootmem takes over. |
4 | * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $ | 4 | * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $ |
5 | * | ||
6 | * Getting sanitize_e820_map() in sync with i386 version by applying change: | ||
7 | * - Provisions for empty E820 memory regions (reported by certain BIOSes). | ||
8 | * Alex Achenbach <xela@slit.de>, December 2002. | ||
9 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
10 | * | ||
5 | */ | 11 | */ |
6 | #include <linux/config.h> | 12 | #include <linux/config.h> |
7 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
@@ -277,7 +283,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) | |||
277 | int chgidx, still_changing; | 283 | int chgidx, still_changing; |
278 | int overlap_entries; | 284 | int overlap_entries; |
279 | int new_bios_entry; | 285 | int new_bios_entry; |
280 | int old_nr, new_nr; | 286 | int old_nr, new_nr, chg_nr; |
281 | int i; | 287 | int i; |
282 | 288 | ||
283 | /* | 289 | /* |
@@ -331,20 +337,24 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) | |||
331 | for (i=0; i < 2*old_nr; i++) | 337 | for (i=0; i < 2*old_nr; i++) |
332 | change_point[i] = &change_point_list[i]; | 338 | change_point[i] = &change_point_list[i]; |
333 | 339 | ||
334 | /* record all known change-points (starting and ending addresses) */ | 340 | /* record all known change-points (starting and ending addresses), |
341 | omitting those that are for empty memory regions */ | ||
335 | chgidx = 0; | 342 | chgidx = 0; |
336 | for (i=0; i < old_nr; i++) { | 343 | for (i=0; i < old_nr; i++) { |
337 | change_point[chgidx]->addr = biosmap[i].addr; | 344 | if (biosmap[i].size != 0) { |
338 | change_point[chgidx++]->pbios = &biosmap[i]; | 345 | change_point[chgidx]->addr = biosmap[i].addr; |
339 | change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; | 346 | change_point[chgidx++]->pbios = &biosmap[i]; |
340 | change_point[chgidx++]->pbios = &biosmap[i]; | 347 | change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; |
348 | change_point[chgidx++]->pbios = &biosmap[i]; | ||
349 | } | ||
341 | } | 350 | } |
351 | chg_nr = chgidx; | ||
342 | 352 | ||
343 | /* sort change-point list by memory addresses (low -> high) */ | 353 | /* sort change-point list by memory addresses (low -> high) */ |
344 | still_changing = 1; | 354 | still_changing = 1; |
345 | while (still_changing) { | 355 | while (still_changing) { |
346 | still_changing = 0; | 356 | still_changing = 0; |
347 | for (i=1; i < 2*old_nr; i++) { | 357 | for (i=1; i < chg_nr; i++) { |
348 | /* if <current_addr> > <last_addr>, swap */ | 358 | /* if <current_addr> > <last_addr>, swap */ |
349 | /* or, if current=<start_addr> & last=<end_addr>, swap */ | 359 | /* or, if current=<start_addr> & last=<end_addr>, swap */ |
350 | if ((change_point[i]->addr < change_point[i-1]->addr) || | 360 | if ((change_point[i]->addr < change_point[i-1]->addr) || |
@@ -367,7 +377,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) | |||
367 | last_type = 0; /* start with undefined memory type */ | 377 | last_type = 0; /* start with undefined memory type */ |
368 | last_addr = 0; /* start with 0 as last starting address */ | 378 | last_addr = 0; /* start with 0 as last starting address */ |
369 | /* loop through change-points, determining affect on the new bios map */ | 379 | /* loop through change-points, determining affect on the new bios map */ |
370 | for (chgidx=0; chgidx < 2*old_nr; chgidx++) | 380 | for (chgidx=0; chgidx < chg_nr; chgidx++) |
371 | { | 381 | { |
372 | /* keep track of all overlapping bios entries */ | 382 | /* keep track of all overlapping bios entries */ |
373 | if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) | 383 | if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) |
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c index 750bcd0655dc..e3a19e8ebbf8 100644 --- a/arch/x86_64/kernel/early_printk.c +++ b/arch/x86_64/kernel/early_printk.c | |||
@@ -60,7 +60,7 @@ static struct console early_vga_console = { | |||
60 | 60 | ||
61 | /* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ | 61 | /* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ |
62 | 62 | ||
63 | int early_serial_base = 0x3f8; /* ttyS0 */ | 63 | static int early_serial_base = 0x3f8; /* ttyS0 */ |
64 | 64 | ||
65 | #define XMTRDY 0x20 | 65 | #define XMTRDY 0x20 |
66 | 66 | ||
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 3233a15cc4e0..1086b5fcac21 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -296,6 +296,7 @@ int_very_careful: | |||
296 | call syscall_trace_leave | 296 | call syscall_trace_leave |
297 | popq %rdi | 297 | popq %rdi |
298 | andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi | 298 | andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi |
299 | cli | ||
299 | jmp int_restore_rest | 300 | jmp int_restore_rest |
300 | 301 | ||
301 | int_signal: | 302 | int_signal: |
@@ -307,6 +308,7 @@ int_signal: | |||
307 | 1: movl $_TIF_NEED_RESCHED,%edi | 308 | 1: movl $_TIF_NEED_RESCHED,%edi |
308 | int_restore_rest: | 309 | int_restore_rest: |
309 | RESTORE_REST | 310 | RESTORE_REST |
311 | cli | ||
310 | jmp int_with_check | 312 | jmp int_with_check |
311 | CFI_ENDPROC | 313 | CFI_ENDPROC |
312 | 314 | ||
@@ -490,7 +492,8 @@ retint_signal: | |||
490 | call do_notify_resume | 492 | call do_notify_resume |
491 | RESTORE_REST | 493 | RESTORE_REST |
492 | cli | 494 | cli |
493 | GET_THREAD_INFO(%rcx) | 495 | GET_THREAD_INFO(%rcx) |
496 | movl $_TIF_WORK_MASK,%edi | ||
494 | jmp retint_check | 497 | jmp retint_check |
495 | 498 | ||
496 | #ifdef CONFIG_PREEMPT | 499 | #ifdef CONFIG_PREEMPT |
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 6cad46c98a23..0f8c78dcd38c 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c | |||
@@ -29,8 +29,6 @@ static void __init clear_bss(void) | |||
29 | (unsigned long) __bss_end - (unsigned long) __bss_start); | 29 | (unsigned long) __bss_end - (unsigned long) __bss_start); |
30 | } | 30 | } |
31 | 31 | ||
32 | extern char x86_boot_params[2048]; | ||
33 | |||
34 | #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ | 32 | #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ |
35 | #define OLD_CL_MAGIC_ADDR 0x90020 | 33 | #define OLD_CL_MAGIC_ADDR 0x90020 |
36 | #define OLD_CL_MAGIC 0xA33F | 34 | #define OLD_CL_MAGIC 0xA33F |
@@ -44,7 +42,7 @@ static void __init copy_bootdata(char *real_mode_data) | |||
44 | int new_data; | 42 | int new_data; |
45 | char * command_line; | 43 | char * command_line; |
46 | 44 | ||
47 | memcpy(x86_boot_params, real_mode_data, 2048); | 45 | memcpy(x86_boot_params, real_mode_data, BOOT_PARAM_SIZE); |
48 | new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); | 46 | new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); |
49 | if (!new_data) { | 47 | if (!new_data) { |
50 | if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { | 48 | if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { |
@@ -93,9 +91,6 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
93 | #ifdef CONFIG_SMP | 91 | #ifdef CONFIG_SMP |
94 | cpu_set(0, cpu_online_map); | 92 | cpu_set(0, cpu_online_map); |
95 | #endif | 93 | #endif |
96 | /* default console: */ | ||
97 | if (!strstr(saved_command_line, "console=")) | ||
98 | strcat(saved_command_line, " console=tty0"); | ||
99 | s = strstr(saved_command_line, "earlyprintk="); | 94 | s = strstr(saved_command_line, "earlyprintk="); |
100 | if (s != NULL) | 95 | if (s != NULL) |
101 | setup_early_printk(s); | 96 | setup_early_printk(s); |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 29a257295484..60be58617eb9 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -1607,7 +1607,6 @@ static inline void check_timer(void) | |||
1607 | disable_8259A_irq(0); | 1607 | disable_8259A_irq(0); |
1608 | setup_nmi(); | 1608 | setup_nmi(); |
1609 | enable_8259A_irq(0); | 1609 | enable_8259A_irq(0); |
1610 | check_nmi_watchdog(); | ||
1611 | } | 1610 | } |
1612 | return; | 1611 | return; |
1613 | } | 1612 | } |
@@ -1627,7 +1626,6 @@ static inline void check_timer(void) | |||
1627 | nmi_watchdog_default(); | 1626 | nmi_watchdog_default(); |
1628 | if (nmi_watchdog == NMI_IO_APIC) { | 1627 | if (nmi_watchdog == NMI_IO_APIC) { |
1629 | setup_nmi(); | 1628 | setup_nmi(); |
1630 | check_nmi_watchdog(); | ||
1631 | } | 1629 | } |
1632 | return; | 1630 | return; |
1633 | } | 1631 | } |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index e00d4adec36b..61de0b34a01e 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -112,17 +112,20 @@ static __init int cpu_has_lapic(void) | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | int __init check_nmi_watchdog (void) | 115 | static int __init check_nmi_watchdog (void) |
116 | { | 116 | { |
117 | int counts[NR_CPUS]; | 117 | int counts[NR_CPUS]; |
118 | int cpu; | 118 | int cpu; |
119 | 119 | ||
120 | if (nmi_watchdog == NMI_NONE) | ||
121 | return 0; | ||
122 | |||
120 | if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) { | 123 | if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) { |
121 | nmi_watchdog = NMI_NONE; | 124 | nmi_watchdog = NMI_NONE; |
122 | return -1; | 125 | return -1; |
123 | } | 126 | } |
124 | 127 | ||
125 | printk(KERN_INFO "testing NMI watchdog ... "); | 128 | printk(KERN_INFO "Testing NMI watchdog ... "); |
126 | 129 | ||
127 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 130 | for (cpu = 0; cpu < NR_CPUS; cpu++) |
128 | counts[cpu] = cpu_pda[cpu].__nmi_count; | 131 | counts[cpu] = cpu_pda[cpu].__nmi_count; |
@@ -148,6 +151,8 @@ int __init check_nmi_watchdog (void) | |||
148 | 151 | ||
149 | return 0; | 152 | return 0; |
150 | } | 153 | } |
154 | /* Have this called later during boot so counters are updating */ | ||
155 | late_initcall(check_nmi_watchdog); | ||
151 | 156 | ||
152 | int __init setup_nmi_watchdog(char *str) | 157 | int __init setup_nmi_watchdog(char *str) |
153 | { | 158 | { |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 9922d2ba24a3..761b6d35e338 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -402,10 +402,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, | |||
402 | p->thread.fs = me->thread.fs; | 402 | p->thread.fs = me->thread.fs; |
403 | p->thread.gs = me->thread.gs; | 403 | p->thread.gs = me->thread.gs; |
404 | 404 | ||
405 | asm("movl %%gs,%0" : "=m" (p->thread.gsindex)); | 405 | asm("mov %%gs,%0" : "=m" (p->thread.gsindex)); |
406 | asm("movl %%fs,%0" : "=m" (p->thread.fsindex)); | 406 | asm("mov %%fs,%0" : "=m" (p->thread.fsindex)); |
407 | asm("movl %%es,%0" : "=m" (p->thread.es)); | 407 | asm("mov %%es,%0" : "=m" (p->thread.es)); |
408 | asm("movl %%ds,%0" : "=m" (p->thread.ds)); | 408 | asm("mov %%ds,%0" : "=m" (p->thread.ds)); |
409 | 409 | ||
410 | if (unlikely(me->thread.io_bitmap_ptr != NULL)) { | 410 | if (unlikely(me->thread.io_bitmap_ptr != NULL)) { |
411 | p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); | 411 | p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); |
@@ -468,11 +468,11 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct * | |||
468 | * Switch DS and ES. | 468 | * Switch DS and ES. |
469 | * This won't pick up thread selector changes, but I guess that is ok. | 469 | * This won't pick up thread selector changes, but I guess that is ok. |
470 | */ | 470 | */ |
471 | asm volatile("movl %%es,%0" : "=m" (prev->es)); | 471 | asm volatile("mov %%es,%0" : "=m" (prev->es)); |
472 | if (unlikely(next->es | prev->es)) | 472 | if (unlikely(next->es | prev->es)) |
473 | loadsegment(es, next->es); | 473 | loadsegment(es, next->es); |
474 | 474 | ||
475 | asm volatile ("movl %%ds,%0" : "=m" (prev->ds)); | 475 | asm volatile ("mov %%ds,%0" : "=m" (prev->ds)); |
476 | if (unlikely(next->ds | prev->ds)) | 476 | if (unlikely(next->ds | prev->ds)) |
477 | loadsegment(ds, next->ds); | 477 | loadsegment(ds, next->ds); |
478 | 478 | ||
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index c7011675007d..c64b9c97c745 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/audit.h> | 19 | #include <linux/audit.h> |
20 | #include <linux/seccomp.h> | 20 | #include <linux/seccomp.h> |
21 | #include <linux/signal.h> | ||
21 | 22 | ||
22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
23 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
@@ -467,7 +468,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data | |||
467 | case PTRACE_CONT: /* restart after signal. */ | 468 | case PTRACE_CONT: /* restart after signal. */ |
468 | 469 | ||
469 | ret = -EIO; | 470 | ret = -EIO; |
470 | if ((unsigned long) data > _NSIG) | 471 | if (!valid_signal(data)) |
471 | break; | 472 | break; |
472 | if (request == PTRACE_SYSCALL) | 473 | if (request == PTRACE_SYSCALL) |
473 | set_tsk_thread_flag(child,TIF_SYSCALL_TRACE); | 474 | set_tsk_thread_flag(child,TIF_SYSCALL_TRACE); |
@@ -529,7 +530,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data | |||
529 | 530 | ||
530 | case PTRACE_SINGLESTEP: /* set the trap flag. */ | 531 | case PTRACE_SINGLESTEP: /* set the trap flag. */ |
531 | ret = -EIO; | 532 | ret = -EIO; |
532 | if ((unsigned long) data > _NSIG) | 533 | if (!valid_signal(data)) |
533 | break; | 534 | break; |
534 | clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE); | 535 | clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE); |
535 | set_singlestep(child); | 536 | set_singlestep(child); |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index b18c114c7648..2129cf9ba6b2 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -977,7 +977,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) | |||
977 | if ((xlvl & 0xffff0000) == 0x80000000) { | 977 | if ((xlvl & 0xffff0000) == 0x80000000) { |
978 | if (xlvl >= 0x80000001) { | 978 | if (xlvl >= 0x80000001) { |
979 | c->x86_capability[1] = cpuid_edx(0x80000001); | 979 | c->x86_capability[1] = cpuid_edx(0x80000001); |
980 | c->x86_capability[5] = cpuid_ecx(0x80000001); | 980 | c->x86_capability[6] = cpuid_ecx(0x80000001); |
981 | } | 981 | } |
982 | if (xlvl >= 0x80000004) | 982 | if (xlvl >= 0x80000004) |
983 | get_model_name(c); /* Default name */ | 983 | get_model_name(c); /* Default name */ |
@@ -1076,7 +1076,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1076 | "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL, | 1076 | "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL, |
1077 | 1077 | ||
1078 | /* AMD-defined */ | 1078 | /* AMD-defined */ |
1079 | "pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1079 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1080 | NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, | 1080 | NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, |
1081 | NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL, | 1081 | NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL, |
1082 | NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow", | 1082 | NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow", |
@@ -1100,11 +1100,17 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1100 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1100 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1101 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1101 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1102 | 1102 | ||
1103 | /* VIA/Cyrix/Centaur-defined */ | ||
1104 | NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", | ||
1105 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | ||
1106 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | ||
1107 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | ||
1108 | |||
1103 | /* AMD-defined (#2) */ | 1109 | /* AMD-defined (#2) */ |
1104 | "lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL, | 1110 | "lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL, |
1105 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1111 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1106 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1112 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1107 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL | 1113 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1108 | }; | 1114 | }; |
1109 | static char *x86_power_flags[] = { | 1115 | static char *x86_power_flags[] = { |
1110 | "ts", /* temperature sensor */ | 1116 | "ts", /* temperature sensor */ |
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index b5305b04bc40..678b7ac33b8b 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
14 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
15 | #include <asm/bootsetup.h> | ||
15 | #include <asm/pda.h> | 16 | #include <asm/pda.h> |
16 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
17 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
@@ -26,7 +27,7 @@ | |||
26 | #include <asm/mman.h> | 27 | #include <asm/mman.h> |
27 | #include <asm/numa.h> | 28 | #include <asm/numa.h> |
28 | 29 | ||
29 | char x86_boot_params[2048] __initdata = {0,}; | 30 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; |
30 | 31 | ||
31 | cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; | 32 | cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; |
32 | 33 | ||
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c index 477d8be57d64..dbebd5ccba6b 100644 --- a/arch/x86_64/kernel/sys_x86_64.c +++ b/arch/x86_64/kernel/sys_x86_64.c | |||
@@ -152,12 +152,6 @@ asmlinkage long sys_uname(struct new_utsname __user * name) | |||
152 | return err ? -EFAULT : 0; | 152 | return err ? -EFAULT : 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) | ||
156 | { | ||
157 | unsigned long raddr; | ||
158 | return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr; | ||
159 | } | ||
160 | |||
161 | asmlinkage long sys_time64(long __user * tloc) | 155 | asmlinkage long sys_time64(long __user * tloc) |
162 | { | 156 | { |
163 | struct timeval now; | 157 | struct timeval now; |
diff --git a/crypto/Kconfig b/crypto/Kconfig index 536754faf4d2..90d6089d60ed 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -146,7 +146,7 @@ config CRYPTO_SERPENT | |||
146 | 146 | ||
147 | config CRYPTO_AES | 147 | config CRYPTO_AES |
148 | tristate "AES cipher algorithms" | 148 | tristate "AES cipher algorithms" |
149 | depends on CRYPTO && !(X86 && !X86_64) | 149 | depends on CRYPTO && !((X86 || UML_X86) && !64BIT) |
150 | help | 150 | help |
151 | AES cipher algorithms (FIPS-197). AES uses the Rijndael | 151 | AES cipher algorithms (FIPS-197). AES uses the Rijndael |
152 | algorithm. | 152 | algorithm. |
@@ -166,7 +166,7 @@ config CRYPTO_AES | |||
166 | 166 | ||
167 | config CRYPTO_AES_586 | 167 | config CRYPTO_AES_586 |
168 | tristate "AES cipher algorithms (i586)" | 168 | tristate "AES cipher algorithms (i586)" |
169 | depends on CRYPTO && (X86 && !X86_64) | 169 | depends on CRYPTO && ((X86 || UML_X86) && !64BIT) |
170 | help | 170 | help |
171 | AES cipher algorithms (FIPS-197). AES uses the Rijndael | 171 | AES cipher algorithms (FIPS-197). AES uses the Rijndael |
172 | algorithm. | 172 | algorithm. |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 05a17812d521..ff64d333e95f 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -838,7 +838,7 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr) | |||
838 | 838 | ||
839 | /* Fall back to the default idle loop */ | 839 | /* Fall back to the default idle loop */ |
840 | pm_idle = pm_idle_save; | 840 | pm_idle = pm_idle_save; |
841 | synchronize_kernel(); | 841 | synchronize_sched(); /* Relies on interrupts forcing exit from idle. */ |
842 | 842 | ||
843 | pr->flags.power = 0; | 843 | pr->flags.power = 0; |
844 | result = acpi_processor_get_power_info(pr); | 844 | result = acpi_processor_get_power_info(pr); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e7ca06626566..119c94093a13 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -379,8 +379,8 @@ ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); | |||
379 | 379 | ||
380 | /** | 380 | /** |
381 | * setup_sys_fs_device_files - sets up the device files under device namespace | 381 | * setup_sys_fs_device_files - sets up the device files under device namespace |
382 | * @@dev: acpi_device object | 382 | * @dev: acpi_device object |
383 | * @@func: function pointer to create or destroy the device file | 383 | * @func: function pointer to create or destroy the device file |
384 | */ | 384 | */ |
385 | static void | 385 | static void |
386 | setup_sys_fs_device_files ( | 386 | setup_sys_fs_device_files ( |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cd6453905a9b..3a5f4c991797 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -115,7 +115,7 @@ int platform_add_devices(struct platform_device **devs, int num) | |||
115 | 115 | ||
116 | /** | 116 | /** |
117 | * platform_device_register - add a platform-level device | 117 | * platform_device_register - add a platform-level device |
118 | * @dev: platform device we're adding | 118 | * @pdev: platform device we're adding |
119 | * | 119 | * |
120 | */ | 120 | */ |
121 | int platform_device_register(struct platform_device * pdev) | 121 | int platform_device_register(struct platform_device * pdev) |
@@ -174,7 +174,7 @@ int platform_device_register(struct platform_device * pdev) | |||
174 | 174 | ||
175 | /** | 175 | /** |
176 | * platform_device_unregister - remove a platform-level device | 176 | * platform_device_unregister - remove a platform-level device |
177 | * @dev: platform device we're removing | 177 | * @pdev: platform device we're removing |
178 | * | 178 | * |
179 | * Note that this function will also release all memory- and port-based | 179 | * Note that this function will also release all memory- and port-based |
180 | * resources owned by the device (@dev->resource). | 180 | * resources owned by the device (@dev->resource). |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index efdf04450bf7..9e268ddedfbd 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -78,6 +78,7 @@ | |||
78 | #define DBG_RX 0x0200 | 78 | #define DBG_RX 0x0200 |
79 | #define DBG_TX 0x0400 | 79 | #define DBG_TX 0x0400 |
80 | static unsigned int debugflags; | 80 | static unsigned int debugflags; |
81 | static unsigned int nbds_max = 16; | ||
81 | #endif /* NDEBUG */ | 82 | #endif /* NDEBUG */ |
82 | 83 | ||
83 | static struct nbd_device nbd_dev[MAX_NBD]; | 84 | static struct nbd_device nbd_dev[MAX_NBD]; |
@@ -647,7 +648,13 @@ static int __init nbd_init(void) | |||
647 | return -EIO; | 648 | return -EIO; |
648 | } | 649 | } |
649 | 650 | ||
650 | for (i = 0; i < MAX_NBD; i++) { | 651 | if (nbds_max > MAX_NBD) { |
652 | printk(KERN_CRIT "nbd: cannot allocate more than %u nbds; %u requested.\n", MAX_NBD, | ||
653 | nbds_max); | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | |||
657 | for (i = 0; i < nbds_max; i++) { | ||
651 | struct gendisk *disk = alloc_disk(1); | 658 | struct gendisk *disk = alloc_disk(1); |
652 | if (!disk) | 659 | if (!disk) |
653 | goto out; | 660 | goto out; |
@@ -673,7 +680,7 @@ static int __init nbd_init(void) | |||
673 | dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags); | 680 | dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags); |
674 | 681 | ||
675 | devfs_mk_dir("nbd"); | 682 | devfs_mk_dir("nbd"); |
676 | for (i = 0; i < MAX_NBD; i++) { | 683 | for (i = 0; i < nbds_max; i++) { |
677 | struct gendisk *disk = nbd_dev[i].disk; | 684 | struct gendisk *disk = nbd_dev[i].disk; |
678 | nbd_dev[i].file = NULL; | 685 | nbd_dev[i].file = NULL; |
679 | nbd_dev[i].magic = LO_MAGIC; | 686 | nbd_dev[i].magic = LO_MAGIC; |
@@ -706,8 +713,9 @@ out: | |||
706 | static void __exit nbd_cleanup(void) | 713 | static void __exit nbd_cleanup(void) |
707 | { | 714 | { |
708 | int i; | 715 | int i; |
709 | for (i = 0; i < MAX_NBD; i++) { | 716 | for (i = 0; i < nbds_max; i++) { |
710 | struct gendisk *disk = nbd_dev[i].disk; | 717 | struct gendisk *disk = nbd_dev[i].disk; |
718 | nbd_dev[i].magic = 0; | ||
711 | if (disk) { | 719 | if (disk) { |
712 | del_gendisk(disk); | 720 | del_gendisk(disk); |
713 | blk_cleanup_queue(disk->queue); | 721 | blk_cleanup_queue(disk->queue); |
@@ -725,6 +733,8 @@ module_exit(nbd_cleanup); | |||
725 | MODULE_DESCRIPTION("Network Block Device"); | 733 | MODULE_DESCRIPTION("Network Block Device"); |
726 | MODULE_LICENSE("GPL"); | 734 | MODULE_LICENSE("GPL"); |
727 | 735 | ||
736 | module_param(nbds_max, int, 0444); | ||
737 | MODULE_PARM_DESC(nbds_max, "How many network block devices to initialize."); | ||
728 | #ifndef NDEBUG | 738 | #ifndef NDEBUG |
729 | module_param(debugflags, int, 0644); | 739 | module_param(debugflags, int, 0644); |
730 | MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); | 740 | MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); |
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c index 888c477e02b3..b1730b62c37e 100644 --- a/drivers/block/noop-iosched.c +++ b/drivers/block/noop-iosched.c | |||
@@ -13,34 +13,13 @@ | |||
13 | static int elevator_noop_merge(request_queue_t *q, struct request **req, | 13 | static int elevator_noop_merge(request_queue_t *q, struct request **req, |
14 | struct bio *bio) | 14 | struct bio *bio) |
15 | { | 15 | { |
16 | struct list_head *entry = &q->queue_head; | ||
17 | struct request *__rq; | ||
18 | int ret; | 16 | int ret; |
19 | 17 | ||
20 | if ((ret = elv_try_last_merge(q, bio))) { | 18 | ret = elv_try_last_merge(q, bio); |
19 | if (ret != ELEVATOR_NO_MERGE) | ||
21 | *req = q->last_merge; | 20 | *req = q->last_merge; |
22 | return ret; | ||
23 | } | ||
24 | 21 | ||
25 | while ((entry = entry->prev) != &q->queue_head) { | 22 | return ret; |
26 | __rq = list_entry_rq(entry); | ||
27 | |||
28 | if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) | ||
29 | break; | ||
30 | else if (__rq->flags & REQ_STARTED) | ||
31 | break; | ||
32 | |||
33 | if (!blk_fs_request(__rq)) | ||
34 | continue; | ||
35 | |||
36 | if ((ret = elv_try_merge(__rq, bio))) { | ||
37 | *req = __rq; | ||
38 | q->last_merge = __rq; | ||
39 | return ret; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | return ELEVATOR_NO_MERGE; | ||
44 | } | 23 | } |
45 | 24 | ||
46 | static void elevator_noop_merge_requests(request_queue_t *q, struct request *req, | 25 | static void elevator_noop_merge_requests(request_queue_t *q, struct request *req, |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 9deca49c71f0..beaa561f2ed8 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -645,7 +645,7 @@ static int cdrom_mrw_exit(struct cdrom_device_info *cdi) | |||
645 | ret = cdrom_mrw_bgformat_susp(cdi, 0); | 645 | ret = cdrom_mrw_bgformat_susp(cdi, 0); |
646 | } | 646 | } |
647 | 647 | ||
648 | if (!ret) | 648 | if (!ret && cdi->media_written) |
649 | ret = cdrom_flush_cache(cdi); | 649 | ret = cdrom_flush_cache(cdi); |
650 | 650 | ||
651 | return ret; | 651 | return ret; |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 97ac4edf4655..e162dab64ffd 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -982,7 +982,7 @@ config MAX_RAW_DEVS | |||
982 | 982 | ||
983 | config HANGCHECK_TIMER | 983 | config HANGCHECK_TIMER |
984 | tristate "Hangcheck timer" | 984 | tristate "Hangcheck timer" |
985 | depends on X86_64 || X86 | 985 | depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390 |
986 | help | 986 | help |
987 | The hangcheck-timer module detects when the system has gone | 987 | The hangcheck-timer module detects when the system has gone |
988 | out to lunch past a certain margin. It can reboot the system | 988 | out to lunch past a certain margin. It can reboot the system |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index c86a22c5499b..0212febda654 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -192,7 +192,7 @@ static struct aper_size_info_32 ali_generic_sizes[7] = | |||
192 | {4, 1024, 0, 3} | 192 | {4, 1024, 0, 3} |
193 | }; | 193 | }; |
194 | 194 | ||
195 | struct agp_bridge_driver ali_generic_bridge = { | 195 | static struct agp_bridge_driver ali_generic_bridge = { |
196 | .owner = THIS_MODULE, | 196 | .owner = THIS_MODULE, |
197 | .aperture_sizes = ali_generic_sizes, | 197 | .aperture_sizes = ali_generic_sizes, |
198 | .size_type = U32_APER_SIZE, | 198 | .size_type = U32_APER_SIZE, |
@@ -215,7 +215,7 @@ struct agp_bridge_driver ali_generic_bridge = { | |||
215 | .agp_destroy_page = ali_destroy_page, | 215 | .agp_destroy_page = ali_destroy_page, |
216 | }; | 216 | }; |
217 | 217 | ||
218 | struct agp_bridge_driver ali_m1541_bridge = { | 218 | static struct agp_bridge_driver ali_m1541_bridge = { |
219 | .owner = THIS_MODULE, | 219 | .owner = THIS_MODULE, |
220 | .aperture_sizes = ali_generic_sizes, | 220 | .aperture_sizes = ali_generic_sizes, |
221 | .size_type = U32_APER_SIZE, | 221 | .size_type = U32_APER_SIZE, |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index f1ea87ea6b65..e62a3c2c44a9 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -358,7 +358,7 @@ static struct gatt_mask amd_irongate_masks[] = | |||
358 | {.mask = 1, .type = 0} | 358 | {.mask = 1, .type = 0} |
359 | }; | 359 | }; |
360 | 360 | ||
361 | struct agp_bridge_driver amd_irongate_driver = { | 361 | static struct agp_bridge_driver amd_irongate_driver = { |
362 | .owner = THIS_MODULE, | 362 | .owner = THIS_MODULE, |
363 | .aperture_sizes = amd_irongate_sizes, | 363 | .aperture_sizes = amd_irongate_sizes, |
364 | .size_type = LVL2_APER_SIZE, | 364 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 905f0629c44f..399c042f68f0 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -243,7 +243,7 @@ static void amd64_cleanup(void) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | 245 | ||
246 | struct agp_bridge_driver amd_8151_driver = { | 246 | static struct agp_bridge_driver amd_8151_driver = { |
247 | .owner = THIS_MODULE, | 247 | .owner = THIS_MODULE, |
248 | .aperture_sizes = amd_8151_sizes, | 248 | .aperture_sizes = amd_8151_sizes, |
249 | .size_type = U32_APER_SIZE, | 249 | .size_type = U32_APER_SIZE, |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 757dde006fc9..a65f8827c283 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -393,7 +393,7 @@ static int ati_free_gatt_table(struct agp_bridge_data *bridge) | |||
393 | return 0; | 393 | return 0; |
394 | } | 394 | } |
395 | 395 | ||
396 | struct agp_bridge_driver ati_generic_bridge = { | 396 | static struct agp_bridge_driver ati_generic_bridge = { |
397 | .owner = THIS_MODULE, | 397 | .owner = THIS_MODULE, |
398 | .aperture_sizes = ati_generic_sizes, | 398 | .aperture_sizes = ati_generic_sizes, |
399 | .size_type = LVL2_APER_SIZE, | 399 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index c3442f3c6480..2f3dfb63bdc6 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -97,7 +97,7 @@ void agp_backend_release(struct agp_bridge_data *bridge) | |||
97 | EXPORT_SYMBOL(agp_backend_release); | 97 | EXPORT_SYMBOL(agp_backend_release); |
98 | 98 | ||
99 | 99 | ||
100 | struct { int mem, agp; } maxes_table[] = { | 100 | static struct { int mem, agp; } maxes_table[] = { |
101 | {0, 0}, | 101 | {0, 0}, |
102 | {32, 4}, | 102 | {32, 4}, |
103 | {64, 28}, | 103 | {64, 28}, |
@@ -322,7 +322,7 @@ static int __init agp_init(void) | |||
322 | return 0; | 322 | return 0; |
323 | } | 323 | } |
324 | 324 | ||
325 | void __exit agp_exit(void) | 325 | static void __exit agp_exit(void) |
326 | { | 326 | { |
327 | } | 327 | } |
328 | 328 | ||
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 2a87cecdc912..1383c3165ea1 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c | |||
@@ -303,7 +303,7 @@ static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int t | |||
303 | } | 303 | } |
304 | 304 | ||
305 | 305 | ||
306 | struct agp_bridge_driver efficeon_driver = { | 306 | static struct agp_bridge_driver efficeon_driver = { |
307 | .owner = THIS_MODULE, | 307 | .owner = THIS_MODULE, |
308 | .aperture_sizes = efficeon_generic_sizes, | 308 | .aperture_sizes = efficeon_generic_sizes, |
309 | .size_type = LVL2_APER_SIZE, | 309 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index f633623ac802..3dfb6648547b 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c | |||
@@ -235,7 +235,7 @@ static void agp_insert_into_pool(struct agp_memory * temp) | |||
235 | 235 | ||
236 | /* File private list routines */ | 236 | /* File private list routines */ |
237 | 237 | ||
238 | struct agp_file_private *agp_find_private(pid_t pid) | 238 | static struct agp_file_private *agp_find_private(pid_t pid) |
239 | { | 239 | { |
240 | struct agp_file_private *curr; | 240 | struct agp_file_private *curr; |
241 | 241 | ||
@@ -250,7 +250,7 @@ struct agp_file_private *agp_find_private(pid_t pid) | |||
250 | return NULL; | 250 | return NULL; |
251 | } | 251 | } |
252 | 252 | ||
253 | void agp_insert_file_private(struct agp_file_private * priv) | 253 | static void agp_insert_file_private(struct agp_file_private * priv) |
254 | { | 254 | { |
255 | struct agp_file_private *prev; | 255 | struct agp_file_private *prev; |
256 | 256 | ||
@@ -262,7 +262,7 @@ void agp_insert_file_private(struct agp_file_private * priv) | |||
262 | agp_fe.file_priv_list = priv; | 262 | agp_fe.file_priv_list = priv; |
263 | } | 263 | } |
264 | 264 | ||
265 | void agp_remove_file_private(struct agp_file_private * priv) | 265 | static void agp_remove_file_private(struct agp_file_private * priv) |
266 | { | 266 | { |
267 | struct agp_file_private *next; | 267 | struct agp_file_private *next; |
268 | struct agp_file_private *prev; | 268 | struct agp_file_private *prev; |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 4f7a3e8bc919..80dafa3030bd 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -288,7 +288,7 @@ static struct gatt_mask nvidia_generic_masks[] = | |||
288 | }; | 288 | }; |
289 | 289 | ||
290 | 290 | ||
291 | struct agp_bridge_driver nvidia_driver = { | 291 | static struct agp_bridge_driver nvidia_driver = { |
292 | .owner = THIS_MODULE, | 292 | .owner = THIS_MODULE, |
293 | .aperture_sizes = nvidia_generic_sizes, | 293 | .aperture_sizes = nvidia_generic_sizes, |
294 | .size_type = U8_APER_SIZE, | 294 | .size_type = U8_APER_SIZE, |
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index cfccacb2a647..ebc05554045c 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c | |||
@@ -119,7 +119,7 @@ static struct aper_size_info_8 sis_generic_sizes[7] = | |||
119 | {4, 1024, 0, 3} | 119 | {4, 1024, 0, 3} |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct agp_bridge_driver sis_driver = { | 122 | static struct agp_bridge_driver sis_driver = { |
123 | .owner = THIS_MODULE, | 123 | .owner = THIS_MODULE, |
124 | .aperture_sizes = sis_generic_sizes, | 124 | .aperture_sizes = sis_generic_sizes, |
125 | .size_type = U8_APER_SIZE, | 125 | .size_type = U8_APER_SIZE, |
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index bb338d9134e0..10c23302dd84 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -409,7 +409,7 @@ static void serverworks_agp_enable(struct agp_bridge_data *bridge, u32 mode) | |||
409 | agp_device_command(command, 0); | 409 | agp_device_command(command, 0); |
410 | } | 410 | } |
411 | 411 | ||
412 | struct agp_bridge_driver sworks_driver = { | 412 | static struct agp_bridge_driver sworks_driver = { |
413 | .owner = THIS_MODULE, | 413 | .owner = THIS_MODULE, |
414 | .aperture_sizes = serverworks_sizes, | 414 | .aperture_sizes = serverworks_sizes, |
415 | .size_type = LVL2_APER_SIZE, | 415 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index e1451dd9b6a7..c847df575cf5 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c | |||
@@ -170,7 +170,7 @@ static void via_tlbflush_agp3(struct agp_memory *mem) | |||
170 | } | 170 | } |
171 | 171 | ||
172 | 172 | ||
173 | struct agp_bridge_driver via_agp3_driver = { | 173 | static struct agp_bridge_driver via_agp3_driver = { |
174 | .owner = THIS_MODULE, | 174 | .owner = THIS_MODULE, |
175 | .aperture_sizes = agp3_generic_sizes, | 175 | .aperture_sizes = agp3_generic_sizes, |
176 | .size_type = U8_APER_SIZE, | 176 | .size_type = U8_APER_SIZE, |
@@ -193,7 +193,7 @@ struct agp_bridge_driver via_agp3_driver = { | |||
193 | .agp_destroy_page = agp_generic_destroy_page, | 193 | .agp_destroy_page = agp_generic_destroy_page, |
194 | }; | 194 | }; |
195 | 195 | ||
196 | struct agp_bridge_driver via_driver = { | 196 | static struct agp_bridge_driver via_driver = { |
197 | .owner = THIS_MODULE, | 197 | .owner = THIS_MODULE, |
198 | .aperture_sizes = via_generic_sizes, | 198 | .aperture_sizes = via_generic_sizes, |
199 | .size_type = U8_APER_SIZE, | 199 | .size_type = U8_APER_SIZE, |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 903e4c3cc209..a229915ce1b2 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -52,7 +52,7 @@ | |||
52 | #define KERNEL | 52 | #define KERNEL |
53 | #include <linux/types.h> | 53 | #include <linux/types.h> |
54 | #include <linux/fs.h> | 54 | #include <linux/fs.h> |
55 | #include <linux/mm.h> /* for verify_area */ | 55 | #include <linux/mm.h> |
56 | #include <linux/errno.h> /* for -EBUSY */ | 56 | #include <linux/errno.h> /* for -EBUSY */ |
57 | #include <linux/ioport.h> /* for request_region */ | 57 | #include <linux/ioport.h> /* for request_region */ |
58 | #include <linux/delay.h> /* for loops_per_jiffy */ | 58 | #include <linux/delay.h> /* for loops_per_jiffy */ |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index 83d6b37b36cd..78e650fc5b41 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for a little io fencing timer. | 4 | * Driver for a little io fencing timer. |
5 | * | 5 | * |
6 | * Copyright (C) 2002 Oracle Corporation. All rights reserved. | 6 | * Copyright (C) 2002, 2003 Oracle. All rights reserved. |
7 | * | 7 | * |
8 | * Author: Joel Becker <joel.becker@oracle.com> | 8 | * Author: Joel Becker <joel.becker@oracle.com> |
9 | * | 9 | * |
@@ -44,11 +44,14 @@ | |||
44 | #include <linux/fs.h> | 44 | #include <linux/fs.h> |
45 | #include <linux/mm.h> | 45 | #include <linux/mm.h> |
46 | #include <linux/reboot.h> | 46 | #include <linux/reboot.h> |
47 | #include <linux/smp_lock.h> | ||
47 | #include <linux/init.h> | 48 | #include <linux/init.h> |
49 | #include <linux/delay.h> | ||
48 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
51 | #include <linux/sysrq.h> | ||
49 | 52 | ||
50 | 53 | ||
51 | #define VERSION_STR "0.5.0" | 54 | #define VERSION_STR "0.9.0" |
52 | 55 | ||
53 | #define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ | 56 | #define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ |
54 | #define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ | 57 | #define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ |
@@ -56,18 +59,89 @@ | |||
56 | static int hangcheck_tick = DEFAULT_IOFENCE_TICK; | 59 | static int hangcheck_tick = DEFAULT_IOFENCE_TICK; |
57 | static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN; | 60 | static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN; |
58 | static int hangcheck_reboot; /* Defaults to not reboot */ | 61 | static int hangcheck_reboot; /* Defaults to not reboot */ |
62 | static int hangcheck_dump_tasks; /* Defaults to not dumping SysRQ T */ | ||
59 | 63 | ||
60 | /* Driver options */ | 64 | /* options - modular */ |
61 | module_param(hangcheck_tick, int, 0); | 65 | module_param(hangcheck_tick, int, 0); |
62 | MODULE_PARM_DESC(hangcheck_tick, "Timer delay."); | 66 | MODULE_PARM_DESC(hangcheck_tick, "Timer delay."); |
63 | module_param(hangcheck_margin, int, 0); | 67 | module_param(hangcheck_margin, int, 0); |
64 | MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire."); | 68 | MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire."); |
65 | module_param(hangcheck_reboot, int, 0); | 69 | module_param(hangcheck_reboot, int, 0); |
66 | MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded."); | 70 | MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded."); |
71 | module_param(hangcheck_dump_tasks, int, 0); | ||
72 | MODULE_PARM_DESC(hangcheck_dump_tasks, "If nonzero, the machine will dump the system task state when the timer margin is exceeded."); | ||
67 | 73 | ||
68 | MODULE_AUTHOR("Joel Becker"); | 74 | MODULE_AUTHOR("Oracle"); |
69 | MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin."); | 75 | MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin."); |
70 | MODULE_LICENSE("GPL"); | 76 | MODULE_LICENSE("GPL"); |
77 | MODULE_VERSION(VERSION_STR); | ||
78 | |||
79 | /* options - nonmodular */ | ||
80 | #ifndef MODULE | ||
81 | |||
82 | static int __init hangcheck_parse_tick(char *str) | ||
83 | { | ||
84 | int par; | ||
85 | if (get_option(&str,&par)) | ||
86 | hangcheck_tick = par; | ||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | static int __init hangcheck_parse_margin(char *str) | ||
91 | { | ||
92 | int par; | ||
93 | if (get_option(&str,&par)) | ||
94 | hangcheck_margin = par; | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | static int __init hangcheck_parse_reboot(char *str) | ||
99 | { | ||
100 | int par; | ||
101 | if (get_option(&str,&par)) | ||
102 | hangcheck_reboot = par; | ||
103 | return 1; | ||
104 | } | ||
105 | |||
106 | static int __init hangcheck_parse_dump_tasks(char *str) | ||
107 | { | ||
108 | int par; | ||
109 | if (get_option(&str,&par)) | ||
110 | hangcheck_dump_tasks = par; | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | __setup("hcheck_tick", hangcheck_parse_tick); | ||
115 | __setup("hcheck_margin", hangcheck_parse_margin); | ||
116 | __setup("hcheck_reboot", hangcheck_parse_reboot); | ||
117 | __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); | ||
118 | #endif /* not MODULE */ | ||
119 | |||
120 | #if defined(CONFIG_X86) || defined(CONFIG_X86_64) | ||
121 | # define HAVE_MONOTONIC | ||
122 | # define TIMER_FREQ 1000000000ULL | ||
123 | #elif defined(CONFIG_ARCH_S390) | ||
124 | /* FA240000 is 1 Second in the IBM time universe (Page 4-38 Principles of Op for zSeries */ | ||
125 | # define TIMER_FREQ 0xFA240000ULL | ||
126 | #elif defined(CONFIG_IA64) | ||
127 | # define TIMER_FREQ ((unsigned long long)local_cpu_data->itc_freq) | ||
128 | #elif defined(CONFIG_PPC64) | ||
129 | # define TIMER_FREQ (HZ*loops_per_jiffy) | ||
130 | #endif | ||
131 | |||
132 | #ifdef HAVE_MONOTONIC | ||
133 | extern unsigned long long monotonic_clock(void); | ||
134 | #else | ||
135 | static inline unsigned long long monotonic_clock(void) | ||
136 | { | ||
137 | # ifdef __s390__ | ||
138 | /* returns the TOD. see 4-38 Principles of Op of zSeries */ | ||
139 | return get_clock(); | ||
140 | # else | ||
141 | return get_cycles(); | ||
142 | # endif /* __s390__ */ | ||
143 | } | ||
144 | #endif /* HAVE_MONOTONIC */ | ||
71 | 145 | ||
72 | 146 | ||
73 | /* Last time scheduled */ | 147 | /* Last time scheduled */ |
@@ -78,7 +152,6 @@ static void hangcheck_fire(unsigned long); | |||
78 | static struct timer_list hangcheck_ticktock = | 152 | static struct timer_list hangcheck_ticktock = |
79 | TIMER_INITIALIZER(hangcheck_fire, 0, 0); | 153 | TIMER_INITIALIZER(hangcheck_fire, 0, 0); |
80 | 154 | ||
81 | extern unsigned long long monotonic_clock(void); | ||
82 | 155 | ||
83 | static void hangcheck_fire(unsigned long data) | 156 | static void hangcheck_fire(unsigned long data) |
84 | { | 157 | { |
@@ -92,6 +165,12 @@ static void hangcheck_fire(unsigned long data) | |||
92 | tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */ | 165 | tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */ |
93 | 166 | ||
94 | if (tsc_diff > hangcheck_tsc_margin) { | 167 | if (tsc_diff > hangcheck_tsc_margin) { |
168 | if (hangcheck_dump_tasks) { | ||
169 | printk(KERN_CRIT "Hangcheck: Task state:\n"); | ||
170 | #ifdef CONFIG_MAGIC_SYSRQ | ||
171 | handle_sysrq('t', NULL, NULL); | ||
172 | #endif /* CONFIG_MAGIC_SYSRQ */ | ||
173 | } | ||
95 | if (hangcheck_reboot) { | 174 | if (hangcheck_reboot) { |
96 | printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); | 175 | printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); |
97 | machine_restart(NULL); | 176 | machine_restart(NULL); |
@@ -108,10 +187,16 @@ static int __init hangcheck_init(void) | |||
108 | { | 187 | { |
109 | printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", | 188 | printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", |
110 | VERSION_STR, hangcheck_tick, hangcheck_margin); | 189 | VERSION_STR, hangcheck_tick, hangcheck_margin); |
111 | 190 | #if defined (HAVE_MONOTONIC) | |
112 | hangcheck_tsc_margin = hangcheck_margin + hangcheck_tick; | 191 | printk("Hangcheck: Using monotonic_clock().\n"); |
113 | hangcheck_tsc_margin *= 1000000000; | 192 | #elif defined(__s390__) |
114 | 193 | printk("Hangcheck: Using TOD.\n"); | |
194 | #else | ||
195 | printk("Hangcheck: Using get_cycles().\n"); | ||
196 | #endif /* HAVE_MONOTONIC */ | ||
197 | hangcheck_tsc_margin = | ||
198 | (unsigned long long)(hangcheck_margin + hangcheck_tick); | ||
199 | hangcheck_tsc_margin *= (unsigned long long)TIMER_FREQ; | ||
115 | 200 | ||
116 | hangcheck_tsc = monotonic_clock(); | 201 | hangcheck_tsc = monotonic_clock(); |
117 | mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); | 202 | mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); |
@@ -123,6 +208,7 @@ static int __init hangcheck_init(void) | |||
123 | static void __exit hangcheck_exit(void) | 208 | static void __exit hangcheck_exit(void) |
124 | { | 209 | { |
125 | del_timer_sync(&hangcheck_ticktock); | 210 | del_timer_sync(&hangcheck_ticktock); |
211 | printk("Hangcheck: Stopped hangcheck timer.\n"); | ||
126 | } | 212 | } |
127 | 213 | ||
128 | module_init(hangcheck_init); | 214 | module_init(hangcheck_init); |
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 225b330115bb..5ce9c6269033 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -235,7 +235,6 @@ static void reset_flags(struct si_sm_data *bt) | |||
235 | if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); | 235 | if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); |
236 | BT_CONTROL(BT_CLR_WR_PTR); | 236 | BT_CONTROL(BT_CLR_WR_PTR); |
237 | BT_CONTROL(BT_SMS_ATN); | 237 | BT_CONTROL(BT_SMS_ATN); |
238 | BT_INTMASK_W(BT_BMC_HWRST); | ||
239 | #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION | 238 | #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION |
240 | if (BT_STATUS & BT_B2H_ATN) { | 239 | if (BT_STATUS & BT_B2H_ATN) { |
241 | int i; | 240 | int i; |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index a6606a1aced7..d7fb452af7f9 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -2588,28 +2588,20 @@ handle_msg_timeout(struct ipmi_recv_msg *msg) | |||
2588 | deliver_response(msg); | 2588 | deliver_response(msg); |
2589 | } | 2589 | } |
2590 | 2590 | ||
2591 | static void | 2591 | static struct ipmi_smi_msg * |
2592 | send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, | 2592 | smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, |
2593 | struct ipmi_smi_msg *smi_msg, | 2593 | unsigned char seq, long seqid) |
2594 | unsigned char seq, long seqid) | ||
2595 | { | 2594 | { |
2596 | if (!smi_msg) | 2595 | struct ipmi_smi_msg *smi_msg = ipmi_alloc_smi_msg(); |
2597 | smi_msg = ipmi_alloc_smi_msg(); | ||
2598 | if (!smi_msg) | 2596 | if (!smi_msg) |
2599 | /* If we can't allocate the message, then just return, we | 2597 | /* If we can't allocate the message, then just return, we |
2600 | get 4 retries, so this should be ok. */ | 2598 | get 4 retries, so this should be ok. */ |
2601 | return; | 2599 | return NULL; |
2602 | 2600 | ||
2603 | memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); | 2601 | memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); |
2604 | smi_msg->data_size = recv_msg->msg.data_len; | 2602 | smi_msg->data_size = recv_msg->msg.data_len; |
2605 | smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); | 2603 | smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); |
2606 | 2604 | ||
2607 | /* Send the new message. We send with a zero priority. It | ||
2608 | timed out, I doubt time is that critical now, and high | ||
2609 | priority messages are really only for messages to the local | ||
2610 | MC, which don't get resent. */ | ||
2611 | intf->handlers->sender(intf->send_info, smi_msg, 0); | ||
2612 | |||
2613 | #ifdef DEBUG_MSGING | 2605 | #ifdef DEBUG_MSGING |
2614 | { | 2606 | { |
2615 | int m; | 2607 | int m; |
@@ -2619,6 +2611,7 @@ send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, | |||
2619 | printk("\n"); | 2611 | printk("\n"); |
2620 | } | 2612 | } |
2621 | #endif | 2613 | #endif |
2614 | return smi_msg; | ||
2622 | } | 2615 | } |
2623 | 2616 | ||
2624 | static void | 2617 | static void |
@@ -2683,14 +2676,13 @@ ipmi_timeout_handler(long timeout_period) | |||
2683 | intf->timed_out_ipmb_commands++; | 2676 | intf->timed_out_ipmb_commands++; |
2684 | spin_unlock(&intf->counter_lock); | 2677 | spin_unlock(&intf->counter_lock); |
2685 | } else { | 2678 | } else { |
2679 | struct ipmi_smi_msg *smi_msg; | ||
2686 | /* More retries, send again. */ | 2680 | /* More retries, send again. */ |
2687 | 2681 | ||
2688 | /* Start with the max timer, set to normal | 2682 | /* Start with the max timer, set to normal |
2689 | timer after the message is sent. */ | 2683 | timer after the message is sent. */ |
2690 | ent->timeout = MAX_MSG_TIMEOUT; | 2684 | ent->timeout = MAX_MSG_TIMEOUT; |
2691 | ent->retries_left--; | 2685 | ent->retries_left--; |
2692 | send_from_recv_msg(intf, ent->recv_msg, NULL, | ||
2693 | j, ent->seqid); | ||
2694 | spin_lock(&intf->counter_lock); | 2686 | spin_lock(&intf->counter_lock); |
2695 | if (ent->recv_msg->addr.addr_type | 2687 | if (ent->recv_msg->addr.addr_type |
2696 | == IPMI_LAN_ADDR_TYPE) | 2688 | == IPMI_LAN_ADDR_TYPE) |
@@ -2698,6 +2690,20 @@ ipmi_timeout_handler(long timeout_period) | |||
2698 | else | 2690 | else |
2699 | intf->retransmitted_ipmb_commands++; | 2691 | intf->retransmitted_ipmb_commands++; |
2700 | spin_unlock(&intf->counter_lock); | 2692 | spin_unlock(&intf->counter_lock); |
2693 | smi_msg = smi_from_recv_msg(intf, | ||
2694 | ent->recv_msg, j, ent->seqid); | ||
2695 | if(!smi_msg) | ||
2696 | continue; | ||
2697 | |||
2698 | spin_unlock_irqrestore(&(intf->seq_lock),flags); | ||
2699 | /* Send the new message. We send with a zero | ||
2700 | * priority. It timed out, I doubt time is | ||
2701 | * that critical now, and high priority | ||
2702 | * messages are really only for messages to the | ||
2703 | * local MC, which don't get resent. */ | ||
2704 | intf->handlers->sender(intf->send_info, | ||
2705 | smi_msg, 0); | ||
2706 | spin_lock_irqsave(&(intf->seq_lock), flags); | ||
2701 | } | 2707 | } |
2702 | } | 2708 | } |
2703 | spin_unlock_irqrestore(&(intf->seq_lock), flags); | 2709 | spin_unlock_irqrestore(&(intf->seq_lock), flags); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 29de259a981e..5419440087fd 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -100,6 +100,11 @@ enum si_intf_state { | |||
100 | /* FIXME - add watchdog stuff. */ | 100 | /* FIXME - add watchdog stuff. */ |
101 | }; | 101 | }; |
102 | 102 | ||
103 | /* Some BT-specific defines we need here. */ | ||
104 | #define IPMI_BT_INTMASK_REG 2 | ||
105 | #define IPMI_BT_INTMASK_CLEAR_IRQ_BIT 2 | ||
106 | #define IPMI_BT_INTMASK_ENABLE_IRQ_BIT 1 | ||
107 | |||
103 | enum si_type { | 108 | enum si_type { |
104 | SI_KCS, SI_SMIC, SI_BT | 109 | SI_KCS, SI_SMIC, SI_BT |
105 | }; | 110 | }; |
@@ -875,6 +880,17 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs) | |||
875 | return IRQ_HANDLED; | 880 | return IRQ_HANDLED; |
876 | } | 881 | } |
877 | 882 | ||
883 | static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs) | ||
884 | { | ||
885 | struct smi_info *smi_info = data; | ||
886 | /* We need to clear the IRQ flag for the BT interface. */ | ||
887 | smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG, | ||
888 | IPMI_BT_INTMASK_CLEAR_IRQ_BIT | ||
889 | | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); | ||
890 | return si_irq_handler(irq, data, regs); | ||
891 | } | ||
892 | |||
893 | |||
878 | static struct ipmi_smi_handlers handlers = | 894 | static struct ipmi_smi_handlers handlers = |
879 | { | 895 | { |
880 | .owner = THIS_MODULE, | 896 | .owner = THIS_MODULE, |
@@ -1001,11 +1017,22 @@ static int std_irq_setup(struct smi_info *info) | |||
1001 | if (!info->irq) | 1017 | if (!info->irq) |
1002 | return 0; | 1018 | return 0; |
1003 | 1019 | ||
1004 | rv = request_irq(info->irq, | 1020 | if (info->si_type == SI_BT) { |
1005 | si_irq_handler, | 1021 | rv = request_irq(info->irq, |
1006 | SA_INTERRUPT, | 1022 | si_bt_irq_handler, |
1007 | DEVICE_NAME, | 1023 | SA_INTERRUPT, |
1008 | info); | 1024 | DEVICE_NAME, |
1025 | info); | ||
1026 | if (!rv) | ||
1027 | /* Enable the interrupt in the BT interface. */ | ||
1028 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, | ||
1029 | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); | ||
1030 | } else | ||
1031 | rv = request_irq(info->irq, | ||
1032 | si_irq_handler, | ||
1033 | SA_INTERRUPT, | ||
1034 | DEVICE_NAME, | ||
1035 | info); | ||
1009 | if (rv) { | 1036 | if (rv) { |
1010 | printk(KERN_WARNING | 1037 | printk(KERN_WARNING |
1011 | "ipmi_si: %s unable to claim interrupt %d," | 1038 | "ipmi_si: %s unable to claim interrupt %d," |
@@ -1024,6 +1051,9 @@ static void std_irq_cleanup(struct smi_info *info) | |||
1024 | if (!info->irq) | 1051 | if (!info->irq) |
1025 | return; | 1052 | return; |
1026 | 1053 | ||
1054 | if (info->si_type == SI_BT) | ||
1055 | /* Disable the interrupt in the BT interface. */ | ||
1056 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0); | ||
1027 | free_irq(info->irq, info); | 1057 | free_irq(info->irq, info); |
1028 | } | 1058 | } |
1029 | 1059 | ||
@@ -1526,8 +1556,17 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) | |||
1526 | info->irq_setup = NULL; | 1556 | info->irq_setup = NULL; |
1527 | } | 1557 | } |
1528 | 1558 | ||
1529 | regspacings[intf_num] = spmi->addr.register_bit_width / 8; | 1559 | if (spmi->addr.register_bit_width) { |
1530 | info->io.regspacing = spmi->addr.register_bit_width / 8; | 1560 | /* A (hopefully) properly formed register bit width. */ |
1561 | regspacings[intf_num] = spmi->addr.register_bit_width / 8; | ||
1562 | info->io.regspacing = spmi->addr.register_bit_width / 8; | ||
1563 | } else { | ||
1564 | /* Some broken systems get this wrong and set the value | ||
1565 | * to zero. Assume it is the default spacing. If that | ||
1566 | * is wrong, too bad, the vendor should fix the tables. */ | ||
1567 | regspacings[intf_num] = DEFAULT_REGSPACING; | ||
1568 | info->io.regspacing = DEFAULT_REGSPACING; | ||
1569 | } | ||
1531 | regsizes[intf_num] = regspacings[intf_num]; | 1570 | regsizes[intf_num] = regspacings[intf_num]; |
1532 | info->io.regsize = regsizes[intf_num]; | 1571 | info->io.regsize = regsizes[intf_num]; |
1533 | regshifts[intf_num] = spmi->addr.register_bit_offset; | 1572 | regshifts[intf_num] = spmi->addr.register_bit_offset; |
@@ -1623,7 +1662,13 @@ static int decode_dmi(dmi_header_t *dm, int intf_num) | |||
1623 | } | 1662 | } |
1624 | } else { | 1663 | } else { |
1625 | /* Old DMI spec. */ | 1664 | /* Old DMI spec. */ |
1626 | ipmi_data->base_addr = base_addr; | 1665 | /* Note that technically, the lower bit of the base |
1666 | * address should be 1 if the address is I/O and 0 if | ||
1667 | * the address is in memory. So many systems get that | ||
1668 | * wrong (and all that I have seen are I/O) so we just | ||
1669 | * ignore that bit and assume I/O. Systems that use | ||
1670 | * memory should use the newer spec, anyway. */ | ||
1671 | ipmi_data->base_addr = base_addr & 0xfffe; | ||
1627 | ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; | 1672 | ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; |
1628 | ipmi_data->offset = 1; | 1673 | ipmi_data->offset = 1; |
1629 | } | 1674 | } |
@@ -2199,7 +2244,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2199 | /* Wait until we know that we are out of any interrupt | 2244 | /* Wait until we know that we are out of any interrupt |
2200 | handlers might have been running before we freed the | 2245 | handlers might have been running before we freed the |
2201 | interrupt. */ | 2246 | interrupt. */ |
2202 | synchronize_kernel(); | 2247 | synchronize_sched(); |
2203 | 2248 | ||
2204 | if (new_smi->si_sm) { | 2249 | if (new_smi->si_sm) { |
2205 | if (new_smi->handlers) | 2250 | if (new_smi->handlers) |
@@ -2312,7 +2357,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean) | |||
2312 | /* Wait until we know that we are out of any interrupt | 2357 | /* Wait until we know that we are out of any interrupt |
2313 | handlers might have been running before we freed the | 2358 | handlers might have been running before we freed the |
2314 | interrupt. */ | 2359 | interrupt. */ |
2315 | synchronize_kernel(); | 2360 | synchronize_sched(); |
2316 | 2361 | ||
2317 | /* Wait for the timer to stop. This avoids problems with race | 2362 | /* Wait for the timer to stop. This avoids problems with race |
2318 | conditions removing the timer here. */ | 2363 | conditions removing the timer here. */ |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index fd7093879c66..fcd1c02a32cb 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -709,11 +709,11 @@ static int ipmi_close(struct inode *ino, struct file *filep) | |||
709 | if (expect_close == 42) { | 709 | if (expect_close == 42) { |
710 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 710 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
711 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | 711 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); |
712 | clear_bit(0, &ipmi_wdog_open); | ||
713 | } else { | 712 | } else { |
714 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 713 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); |
715 | ipmi_heartbeat(); | 714 | ipmi_heartbeat(); |
716 | } | 715 | } |
716 | clear_bit(0, &ipmi_wdog_open); | ||
717 | } | 717 | } |
718 | 718 | ||
719 | ipmi_fasync (-1, filep, 0); | 719 | ipmi_fasync (-1, filep, 0); |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index a91ae271cf0a..763893e289b3 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -221,7 +221,7 @@ static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000}; | |||
221 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. | 221 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. |
222 | Some architectures may need more. -- Changed to LONG to | 222 | Some architectures may need more. -- Changed to LONG to |
223 | support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ | 223 | support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ |
224 | long rio_irqmask = -1; | 224 | static long rio_irqmask = -1; |
225 | 225 | ||
226 | MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>"); | 226 | MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>"); |
227 | MODULE_DESCRIPTION("RIO driver"); | 227 | MODULE_DESCRIPTION("RIO driver"); |
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c index 8e61be34a1d3..ed867db550a9 100644 --- a/drivers/char/s3c2410-rtc.c +++ b/drivers/char/s3c2410-rtc.c | |||
@@ -116,7 +116,7 @@ static void s3c2410_rtc_setfreq(int freq) | |||
116 | 116 | ||
117 | /* Time read/write */ | 117 | /* Time read/write */ |
118 | 118 | ||
119 | static void s3c2410_rtc_gettime(struct rtc_time *rtc_tm) | 119 | static int s3c2410_rtc_gettime(struct rtc_time *rtc_tm) |
120 | { | 120 | { |
121 | unsigned int have_retried = 0; | 121 | unsigned int have_retried = 0; |
122 | 122 | ||
@@ -151,6 +151,8 @@ static void s3c2410_rtc_gettime(struct rtc_time *rtc_tm) | |||
151 | 151 | ||
152 | rtc_tm->tm_year += 100; | 152 | rtc_tm->tm_year += 100; |
153 | rtc_tm->tm_mon -= 1; | 153 | rtc_tm->tm_mon -= 1; |
154 | |||
155 | return 0; | ||
154 | } | 156 | } |
155 | 157 | ||
156 | 158 | ||
@@ -171,7 +173,7 @@ static int s3c2410_rtc_settime(struct rtc_time *tm) | |||
171 | return 0; | 173 | return 0; |
172 | } | 174 | } |
173 | 175 | ||
174 | static void s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm) | 176 | static int s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm) |
175 | { | 177 | { |
176 | struct rtc_time *alm_tm = &alrm->time; | 178 | struct rtc_time *alm_tm = &alrm->time; |
177 | unsigned int alm_en; | 179 | unsigned int alm_en; |
@@ -231,6 +233,8 @@ static void s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm) | |||
231 | } | 233 | } |
232 | 234 | ||
233 | /* todo - set alrm->enabled ? */ | 235 | /* todo - set alrm->enabled ? */ |
236 | |||
237 | return 0; | ||
234 | } | 238 | } |
235 | 239 | ||
236 | static int s3c2410_rtc_setalarm(struct rtc_wkalrm *alrm) | 240 | static int s3c2410_rtc_setalarm(struct rtc_wkalrm *alrm) |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index c789d5ceac76..50e0b612a8a2 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -1987,10 +1987,9 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
1987 | 1987 | ||
1988 | func_enter(); | 1988 | func_enter(); |
1989 | /* | 1989 | /* |
1990 | error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp)); | 1990 | if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) { |
1991 | if (error) { | ||
1992 | func_exit(); | 1991 | func_exit(); |
1993 | return error; | 1992 | return -EFAULT; |
1994 | } | 1993 | } |
1995 | */ | 1994 | */ |
1996 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { | 1995 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { |
@@ -2046,14 +2045,12 @@ static inline int sx_get_serial_info(struct specialix_port * port, | |||
2046 | { | 2045 | { |
2047 | struct serial_struct tmp; | 2046 | struct serial_struct tmp; |
2048 | struct specialix_board *bp = port_Board(port); | 2047 | struct specialix_board *bp = port_Board(port); |
2049 | // int error; | ||
2050 | 2048 | ||
2051 | func_enter(); | 2049 | func_enter(); |
2052 | 2050 | ||
2053 | /* | 2051 | /* |
2054 | error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)); | 2052 | if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp))) |
2055 | if (error) | 2053 | return -EFAULT; |
2056 | return error; | ||
2057 | */ | 2054 | */ |
2058 | 2055 | ||
2059 | memset(&tmp, 0, sizeof(tmp)); | 2056 | memset(&tmp, 0, sizeof(tmp)); |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index de166608c59e..b8899f560b5e 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -466,7 +466,7 @@ static int stl_parsebrd(stlconf_t *confp, char **argp); | |||
466 | 466 | ||
467 | static unsigned long stl_atol(char *str); | 467 | static unsigned long stl_atol(char *str); |
468 | 468 | ||
469 | int stl_init(void); | 469 | static int stl_init(void); |
470 | static int stl_open(struct tty_struct *tty, struct file *filp); | 470 | static int stl_open(struct tty_struct *tty, struct file *filp); |
471 | static void stl_close(struct tty_struct *tty, struct file *filp); | 471 | static void stl_close(struct tty_struct *tty, struct file *filp); |
472 | static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count); | 472 | static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count); |
@@ -3063,7 +3063,7 @@ static struct tty_operations stl_ops = { | |||
3063 | 3063 | ||
3064 | /*****************************************************************************/ | 3064 | /*****************************************************************************/ |
3065 | 3065 | ||
3066 | int __init stl_init(void) | 3066 | static int __init stl_init(void) |
3067 | { | 3067 | { |
3068 | int i; | 3068 | int i; |
3069 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); | 3069 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 5d386f4bea49..8971484b956b 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/major.h> | 24 | #include <linux/major.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/signal.h> | ||
27 | 28 | ||
28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
@@ -641,7 +642,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
641 | extern int spawnpid, spawnsig; | 642 | extern int spawnpid, spawnsig; |
642 | if (!perm || !capable(CAP_KILL)) | 643 | if (!perm || !capable(CAP_KILL)) |
643 | return -EPERM; | 644 | return -EPERM; |
644 | if (arg < 1 || arg > _NSIG || arg == SIGKILL) | 645 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) |
645 | return -EINVAL; | 646 | return -EINVAL; |
646 | spawnpid = current->pid; | 647 | spawnpid = current->pid; |
647 | spawnsig = arg; | 648 | spawnsig = arg; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b30001f31610..8e561313d094 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -223,7 +223,7 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) | |||
223 | } | 223 | } |
224 | if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) || | 224 | if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) || |
225 | (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) || | 225 | (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) || |
226 | (val == CPUFREQ_RESUMECHANGE)) { | 226 | (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { |
227 | loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new); | 227 | loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new); |
228 | dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new); | 228 | dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new); |
229 | } | 229 | } |
@@ -866,11 +866,90 @@ EXPORT_SYMBOL(cpufreq_get); | |||
866 | 866 | ||
867 | 867 | ||
868 | /** | 868 | /** |
869 | * cpufreq_suspend - let the low level driver prepare for suspend | ||
870 | */ | ||
871 | |||
872 | static int cpufreq_suspend(struct sys_device * sysdev, u32 state) | ||
873 | { | ||
874 | int cpu = sysdev->id; | ||
875 | unsigned int ret = 0; | ||
876 | unsigned int cur_freq = 0; | ||
877 | struct cpufreq_policy *cpu_policy; | ||
878 | |||
879 | dprintk("resuming cpu %u\n", cpu); | ||
880 | |||
881 | if (!cpu_online(cpu)) | ||
882 | return 0; | ||
883 | |||
884 | /* we may be lax here as interrupts are off. Nonetheless | ||
885 | * we need to grab the correct cpu policy, as to check | ||
886 | * whether we really run on this CPU. | ||
887 | */ | ||
888 | |||
889 | cpu_policy = cpufreq_cpu_get(cpu); | ||
890 | if (!cpu_policy) | ||
891 | return -EINVAL; | ||
892 | |||
893 | /* only handle each CPU group once */ | ||
894 | if (unlikely(cpu_policy->cpu != cpu)) { | ||
895 | cpufreq_cpu_put(cpu_policy); | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | if (cpufreq_driver->suspend) { | ||
900 | ret = cpufreq_driver->suspend(cpu_policy, state); | ||
901 | if (ret) { | ||
902 | printk(KERN_ERR "cpufreq: suspend failed in ->suspend " | ||
903 | "step on CPU %u\n", cpu_policy->cpu); | ||
904 | cpufreq_cpu_put(cpu_policy); | ||
905 | return ret; | ||
906 | } | ||
907 | } | ||
908 | |||
909 | |||
910 | if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS) | ||
911 | goto out; | ||
912 | |||
913 | if (cpufreq_driver->get) | ||
914 | cur_freq = cpufreq_driver->get(cpu_policy->cpu); | ||
915 | |||
916 | if (!cur_freq || !cpu_policy->cur) { | ||
917 | printk(KERN_ERR "cpufreq: suspend failed to assert current " | ||
918 | "frequency is what timing core thinks it is.\n"); | ||
919 | goto out; | ||
920 | } | ||
921 | |||
922 | if (unlikely(cur_freq != cpu_policy->cur)) { | ||
923 | struct cpufreq_freqs freqs; | ||
924 | |||
925 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) | ||
926 | printk(KERN_DEBUG "Warning: CPU frequency is %u, " | ||
927 | "cpufreq assumed %u kHz.\n", | ||
928 | cur_freq, cpu_policy->cur); | ||
929 | |||
930 | freqs.cpu = cpu; | ||
931 | freqs.old = cpu_policy->cur; | ||
932 | freqs.new = cur_freq; | ||
933 | |||
934 | notifier_call_chain(&cpufreq_transition_notifier_list, | ||
935 | CPUFREQ_SUSPENDCHANGE, &freqs); | ||
936 | adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); | ||
937 | |||
938 | cpu_policy->cur = cur_freq; | ||
939 | } | ||
940 | |||
941 | out: | ||
942 | cpufreq_cpu_put(cpu_policy); | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | /** | ||
869 | * cpufreq_resume - restore proper CPU frequency handling after resume | 947 | * cpufreq_resume - restore proper CPU frequency handling after resume |
870 | * | 948 | * |
871 | * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) | 949 | * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) |
872 | * 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync | 950 | * 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync |
873 | * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are restored. | 951 | * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are |
952 | * restored. | ||
874 | */ | 953 | */ |
875 | static int cpufreq_resume(struct sys_device * sysdev) | 954 | static int cpufreq_resume(struct sys_device * sysdev) |
876 | { | 955 | { |
@@ -915,21 +994,26 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
915 | cur_freq = cpufreq_driver->get(cpu_policy->cpu); | 994 | cur_freq = cpufreq_driver->get(cpu_policy->cpu); |
916 | 995 | ||
917 | if (!cur_freq || !cpu_policy->cur) { | 996 | if (!cur_freq || !cpu_policy->cur) { |
918 | printk(KERN_ERR "cpufreq: resume failed to assert current frequency is what timing core thinks it is.\n"); | 997 | printk(KERN_ERR "cpufreq: resume failed to assert " |
998 | "current frequency is what timing core " | ||
999 | "thinks it is.\n"); | ||
919 | goto out; | 1000 | goto out; |
920 | } | 1001 | } |
921 | 1002 | ||
922 | if (unlikely(cur_freq != cpu_policy->cur)) { | 1003 | if (unlikely(cur_freq != cpu_policy->cur)) { |
923 | struct cpufreq_freqs freqs; | 1004 | struct cpufreq_freqs freqs; |
924 | 1005 | ||
925 | printk(KERN_WARNING "Warning: CPU frequency is %u, " | 1006 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) |
926 | "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur); | 1007 | printk(KERN_WARNING "Warning: CPU frequency" |
1008 | "is %u, cpufreq assumed %u kHz.\n", | ||
1009 | cur_freq, cpu_policy->cur); | ||
927 | 1010 | ||
928 | freqs.cpu = cpu; | 1011 | freqs.cpu = cpu; |
929 | freqs.old = cpu_policy->cur; | 1012 | freqs.old = cpu_policy->cur; |
930 | freqs.new = cur_freq; | 1013 | freqs.new = cur_freq; |
931 | 1014 | ||
932 | notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs); | 1015 | notifier_call_chain(&cpufreq_transition_notifier_list, |
1016 | CPUFREQ_RESUMECHANGE, &freqs); | ||
933 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); | 1017 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); |
934 | 1018 | ||
935 | cpu_policy->cur = cur_freq; | 1019 | cpu_policy->cur = cur_freq; |
@@ -945,6 +1029,7 @@ out: | |||
945 | static struct sysdev_driver cpufreq_sysdev_driver = { | 1029 | static struct sysdev_driver cpufreq_sysdev_driver = { |
946 | .add = cpufreq_add_dev, | 1030 | .add = cpufreq_add_dev, |
947 | .remove = cpufreq_remove_dev, | 1031 | .remove = cpufreq_remove_dev, |
1032 | .suspend = cpufreq_suspend, | ||
948 | .resume = cpufreq_resume, | 1033 | .resume = cpufreq_resume, |
949 | }; | 1034 | }; |
950 | 1035 | ||
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 6dc273a81327..569f16767442 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -1204,6 +1204,8 @@ pmac_ide_do_suspend(ide_hwif_t *hwif) | |||
1204 | } | 1204 | } |
1205 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ | 1205 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ |
1206 | 1206 | ||
1207 | disable_irq(pmif->irq); | ||
1208 | |||
1207 | /* The media bay will handle itself just fine */ | 1209 | /* The media bay will handle itself just fine */ |
1208 | if (pmif->mediabay) | 1210 | if (pmif->mediabay) |
1209 | return 0; | 1211 | return 0; |
@@ -1236,7 +1238,6 @@ pmac_ide_do_resume(ide_hwif_t *hwif) | |||
1236 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); | 1238 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); |
1237 | msleep(10); | 1239 | msleep(10); |
1238 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0); | 1240 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0); |
1239 | msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY)); | ||
1240 | 1241 | ||
1241 | /* Kauai has it different */ | 1242 | /* Kauai has it different */ |
1242 | if (pmif->kauai_fcr) { | 1243 | if (pmif->kauai_fcr) { |
@@ -1244,11 +1245,15 @@ pmac_ide_do_resume(ide_hwif_t *hwif) | |||
1244 | fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE; | 1245 | fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE; |
1245 | writel(fcr, pmif->kauai_fcr); | 1246 | writel(fcr, pmif->kauai_fcr); |
1246 | } | 1247 | } |
1248 | |||
1249 | msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY)); | ||
1247 | } | 1250 | } |
1248 | 1251 | ||
1249 | /* Sanitize drive timings */ | 1252 | /* Sanitize drive timings */ |
1250 | sanitize_timings(pmif); | 1253 | sanitize_timings(pmif); |
1251 | 1254 | ||
1255 | enable_irq(pmif->irq); | ||
1256 | |||
1252 | return 0; | 1257 | return 0; |
1253 | } | 1258 | } |
1254 | 1259 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 986f2180404b..637b30e35592 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c | |||
@@ -32,10 +32,11 @@ | |||
32 | * $Id$ | 32 | * $Id$ |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/mm.h> | ||
36 | |||
35 | #include "mthca_memfree.h" | 37 | #include "mthca_memfree.h" |
36 | #include "mthca_dev.h" | 38 | #include "mthca_dev.h" |
37 | #include "mthca_cmd.h" | 39 | #include "mthca_cmd.h" |
38 | #include <linux/mm.h> | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * We allocate in as big chunks as we can, up to a maximum of 256 KB | 42 | * We allocate in as big chunks as we can, up to a maximum of 256 KB |
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index c76cf8ff29c0..874367bfab08 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c | |||
@@ -116,7 +116,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r | |||
116 | 116 | ||
117 | case 'K': /* Button data */ | 117 | case 'K': /* Button data */ |
118 | if (spaceorb->idx != 5) return; | 118 | if (spaceorb->idx != 5) return; |
119 | for (i = 0; i < 7; i++) | 119 | for (i = 0; i < 6; i++) |
120 | input_report_key(dev, spaceorb_buttons[i], (data[2] >> i) & 1); | 120 | input_report_key(dev, spaceorb_buttons[i], (data[2] >> i) & 1); |
121 | 121 | ||
122 | break; | 122 | break; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index f7304f0ce542..ff66ed4ee2cd 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -678,7 +678,7 @@ static void atkbd_disconnect(struct serio *serio) | |||
678 | atkbd_disable(atkbd); | 678 | atkbd_disable(atkbd); |
679 | 679 | ||
680 | /* make sure we don't have a command in flight */ | 680 | /* make sure we don't have a command in flight */ |
681 | synchronize_kernel(); | 681 | synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ |
682 | flush_scheduled_work(); | 682 | flush_scheduled_work(); |
683 | 683 | ||
684 | device_remove_file(&serio->dev, &atkbd_attr_extra); | 684 | device_remove_file(&serio->dev, &atkbd_attr_extra); |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 06163538bb20..12dee8e9fbbe 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -60,12 +60,12 @@ MODULE_LICENSE("GPL"); | |||
60 | 60 | ||
61 | static struct class_simple *capi_class; | 61 | static struct class_simple *capi_class; |
62 | 62 | ||
63 | int capi_major = 68; /* allocated */ | 63 | static int capi_major = 68; /* allocated */ |
64 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 64 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
65 | #define CAPINC_NR_PORTS 32 | 65 | #define CAPINC_NR_PORTS 32 |
66 | #define CAPINC_MAX_PORTS 256 | 66 | #define CAPINC_MAX_PORTS 256 |
67 | int capi_ttymajor = 191; | 67 | static int capi_ttymajor = 191; |
68 | int capi_ttyminors = CAPINC_NR_PORTS; | 68 | static int capi_ttyminors = CAPINC_NR_PORTS; |
69 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ | 69 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ |
70 | 70 | ||
71 | module_param_named(major, capi_major, uint, 0); | 71 | module_param_named(major, capi_major, uint, 0); |
@@ -268,7 +268,7 @@ static void capiminor_free(struct capiminor *mp) | |||
268 | kfree(mp); | 268 | kfree(mp); |
269 | } | 269 | } |
270 | 270 | ||
271 | struct capiminor *capiminor_find(unsigned int minor) | 271 | static struct capiminor *capiminor_find(unsigned int minor) |
272 | { | 272 | { |
273 | struct list_head *l; | 273 | struct list_head *l; |
274 | struct capiminor *p = NULL; | 274 | struct capiminor *p = NULL; |
@@ -1166,7 +1166,7 @@ static int capinc_tty_write_room(struct tty_struct *tty) | |||
1166 | return room; | 1166 | return room; |
1167 | } | 1167 | } |
1168 | 1168 | ||
1169 | int capinc_tty_chars_in_buffer(struct tty_struct *tty) | 1169 | static int capinc_tty_chars_in_buffer(struct tty_struct *tty) |
1170 | { | 1170 | { |
1171 | struct capiminor *mp = (struct capiminor *)tty->driver_data; | 1171 | struct capiminor *mp = (struct capiminor *)tty->driver_data; |
1172 | if (!mp || !mp->nccip) { | 1172 | if (!mp || !mp->nccip) { |
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c index 16dc5418ff41..2cc8b27e4c3b 100644 --- a/drivers/isdn/capi/kcapi_proc.c +++ b/drivers/isdn/capi/kcapi_proc.c | |||
@@ -89,14 +89,14 @@ static int contrstats_show(struct seq_file *seq, void *v) | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | struct seq_operations seq_controller_ops = { | 92 | static struct seq_operations seq_controller_ops = { |
93 | .start = controller_start, | 93 | .start = controller_start, |
94 | .next = controller_next, | 94 | .next = controller_next, |
95 | .stop = controller_stop, | 95 | .stop = controller_stop, |
96 | .show = controller_show, | 96 | .show = controller_show, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | struct seq_operations seq_contrstats_ops = { | 99 | static struct seq_operations seq_contrstats_ops = { |
100 | .start = controller_start, | 100 | .start = controller_start, |
101 | .next = controller_next, | 101 | .next = controller_next, |
102 | .stop = controller_stop, | 102 | .stop = controller_stop, |
@@ -192,14 +192,14 @@ applstats_show(struct seq_file *seq, void *v) | |||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | struct seq_operations seq_applications_ops = { | 195 | static struct seq_operations seq_applications_ops = { |
196 | .start = applications_start, | 196 | .start = applications_start, |
197 | .next = applications_next, | 197 | .next = applications_next, |
198 | .stop = applications_stop, | 198 | .stop = applications_stop, |
199 | .show = applications_show, | 199 | .show = applications_show, |
200 | }; | 200 | }; |
201 | 201 | ||
202 | struct seq_operations seq_applstats_ops = { | 202 | static struct seq_operations seq_applstats_ops = { |
203 | .start = applications_start, | 203 | .start = applications_start, |
204 | .next = applications_next, | 204 | .next = applications_next, |
205 | .stop = applications_stop, | 205 | .stop = applications_stop, |
@@ -287,7 +287,7 @@ static int capi_driver_show(struct seq_file *seq, void *v) | |||
287 | return 0; | 287 | return 0; |
288 | } | 288 | } |
289 | 289 | ||
290 | struct seq_operations seq_capi_driver_ops = { | 290 | static struct seq_operations seq_capi_driver_ops = { |
291 | .start = capi_driver_start, | 291 | .start = capi_driver_start, |
292 | .next = capi_driver_next, | 292 | .next = capi_driver_next, |
293 | .stop = capi_driver_stop, | 293 | .stop = capi_driver_stop, |
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index 1eb112213f0c..0bfd698726a6 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c | |||
@@ -383,7 +383,7 @@ divert_rule *getruleptr(int idx) | |||
383 | /*************************************************/ | 383 | /*************************************************/ |
384 | /* called from common module on an incoming call */ | 384 | /* called from common module on an incoming call */ |
385 | /*************************************************/ | 385 | /*************************************************/ |
386 | int isdn_divert_icall(isdn_ctrl *ic) | 386 | static int isdn_divert_icall(isdn_ctrl *ic) |
387 | { int retval = 0; | 387 | { int retval = 0; |
388 | unsigned long flags; | 388 | unsigned long flags; |
389 | struct call_struc *cs = NULL; | 389 | struct call_struc *cs = NULL; |
@@ -552,7 +552,7 @@ void deleteprocs(void) | |||
552 | /****************************************************/ | 552 | /****************************************************/ |
553 | /* put a address including address type into buffer */ | 553 | /* put a address including address type into buffer */ |
554 | /****************************************************/ | 554 | /****************************************************/ |
555 | int put_address(char *st, u_char *p, int len) | 555 | static int put_address(char *st, u_char *p, int len) |
556 | { u_char retval = 0; | 556 | { u_char retval = 0; |
557 | u_char adr_typ = 0; /* network standard */ | 557 | u_char adr_typ = 0; /* network standard */ |
558 | 558 | ||
@@ -595,7 +595,7 @@ int put_address(char *st, u_char *p, int len) | |||
595 | /*************************************/ | 595 | /*************************************/ |
596 | /* report a succesfull interrogation */ | 596 | /* report a succesfull interrogation */ |
597 | /*************************************/ | 597 | /*************************************/ |
598 | int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) | 598 | static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) |
599 | { char *src = ic->parm.dss1_io.data; | 599 | { char *src = ic->parm.dss1_io.data; |
600 | int restlen = ic->parm.dss1_io.datalen; | 600 | int restlen = ic->parm.dss1_io.datalen; |
601 | int cnt = 1; | 601 | int cnt = 1; |
@@ -689,7 +689,7 @@ int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) | |||
689 | /*********************************************/ | 689 | /*********************************************/ |
690 | /* callback for protocol specific extensions */ | 690 | /* callback for protocol specific extensions */ |
691 | /*********************************************/ | 691 | /*********************************************/ |
692 | int prot_stat_callback(isdn_ctrl *ic) | 692 | static int prot_stat_callback(isdn_ctrl *ic) |
693 | { struct call_struc *cs, *cs1; | 693 | { struct call_struc *cs, *cs1; |
694 | int i; | 694 | int i; |
695 | unsigned long flags; | 695 | unsigned long flags; |
@@ -781,7 +781,7 @@ int prot_stat_callback(isdn_ctrl *ic) | |||
781 | /***************************/ | 781 | /***************************/ |
782 | /* status callback from HL */ | 782 | /* status callback from HL */ |
783 | /***************************/ | 783 | /***************************/ |
784 | int isdn_divert_stat_callback(isdn_ctrl *ic) | 784 | static int isdn_divert_stat_callback(isdn_ctrl *ic) |
785 | { struct call_struc *cs, *cs1; | 785 | { struct call_struc *cs, *cs1; |
786 | unsigned long flags; | 786 | unsigned long flags; |
787 | int retval; | 787 | int retval; |
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 8f93d01d8928..db654e8bd67e 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
@@ -555,6 +555,42 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto | |||
555 | #endif /* CONFIG_PMAC_BACKLIGHT */ | 555 | #endif /* CONFIG_PMAC_BACKLIGHT */ |
556 | input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down); | 556 | input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down); |
557 | break; | 557 | break; |
558 | |||
559 | case 0xc: /* videomode switch */ | ||
560 | input_report_key(&adbhid[id]->input, KEY_SWITCHVIDEOMODE, down); | ||
561 | break; | ||
562 | |||
563 | case 0xd: /* keyboard illumination toggle */ | ||
564 | input_report_key(&adbhid[id]->input, KEY_KBDILLUMTOGGLE, down); | ||
565 | break; | ||
566 | |||
567 | case 0xe: /* keyboard illumination decrease */ | ||
568 | input_report_key(&adbhid[id]->input, KEY_KBDILLUMDOWN, down); | ||
569 | break; | ||
570 | |||
571 | case 0xf: | ||
572 | switch (data[1]) { | ||
573 | case 0x8f: | ||
574 | case 0x0f: | ||
575 | /* keyboard illumination increase */ | ||
576 | input_report_key(&adbhid[id]->input, KEY_KBDILLUMUP, down); | ||
577 | break; | ||
578 | |||
579 | case 0x7f: | ||
580 | case 0xff: | ||
581 | /* keypad overlay toogle */ | ||
582 | break; | ||
583 | |||
584 | default: | ||
585 | printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n", | ||
586 | data[0], data[1], data[2], data[3]); | ||
587 | break; | ||
588 | } | ||
589 | break; | ||
590 | default: | ||
591 | printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n", | ||
592 | data[0], data[1], data[2], data[3]); | ||
593 | break; | ||
558 | } | 594 | } |
559 | } | 595 | } |
560 | break; | 596 | break; |
@@ -775,6 +811,10 @@ adbhid_input_register(int id, int default_id, int original_handler_id, | |||
775 | set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit); | 811 | set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit); |
776 | set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit); | 812 | set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit); |
777 | set_bit(KEY_EJECTCD, adbhid[id]->input.keybit); | 813 | set_bit(KEY_EJECTCD, adbhid[id]->input.keybit); |
814 | set_bit(KEY_SWITCHVIDEOMODE, adbhid[id]->input.keybit); | ||
815 | set_bit(KEY_KBDILLUMTOGGLE, adbhid[id]->input.keybit); | ||
816 | set_bit(KEY_KBDILLUMDOWN, adbhid[id]->input.keybit); | ||
817 | set_bit(KEY_KBDILLUMUP, adbhid[id]->input.keybit); | ||
778 | break; | 818 | break; |
779 | } | 819 | } |
780 | if (adbhid[id]->name[0]) | 820 | if (adbhid[id]->name[0]) |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index fdea1a3a631d..e654aa5eecd4 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -2351,6 +2351,10 @@ pmac_suspend_devices(void) | |||
2351 | return -EBUSY; | 2351 | return -EBUSY; |
2352 | } | 2352 | } |
2353 | 2353 | ||
2354 | /* Disable clock spreading on some machines */ | ||
2355 | pmac_tweak_clock_spreading(0); | ||
2356 | |||
2357 | /* Stop preemption */ | ||
2354 | preempt_disable(); | 2358 | preempt_disable(); |
2355 | 2359 | ||
2356 | /* Make sure the decrementer won't interrupt us */ | 2360 | /* Make sure the decrementer won't interrupt us */ |
@@ -2417,11 +2421,12 @@ pmac_wakeup_devices(void) | |||
2417 | 2421 | ||
2418 | /* Re-enable local CPU interrupts */ | 2422 | /* Re-enable local CPU interrupts */ |
2419 | local_irq_enable(); | 2423 | local_irq_enable(); |
2420 | |||
2421 | mdelay(100); | 2424 | mdelay(100); |
2422 | |||
2423 | preempt_enable(); | 2425 | preempt_enable(); |
2424 | 2426 | ||
2427 | /* Re-enable clock spreading on some machines */ | ||
2428 | pmac_tweak_clock_spreading(1); | ||
2429 | |||
2425 | /* Resume devices */ | 2430 | /* Resume devices */ |
2426 | device_resume(); | 2431 | device_resume(); |
2427 | 2432 | ||
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 77619a56e2bf..0dd6c2b5391b 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -331,25 +331,19 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
331 | struct bio *bio; | 331 | struct bio *bio; |
332 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 332 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
333 | int gfp_mask = GFP_NOIO | __GFP_HIGHMEM; | 333 | int gfp_mask = GFP_NOIO | __GFP_HIGHMEM; |
334 | unsigned long flags = current->flags; | ||
335 | unsigned int i; | 334 | unsigned int i; |
336 | 335 | ||
337 | /* | 336 | /* |
338 | * Tell VM to act less aggressively and fail earlier. | 337 | * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and |
339 | * This is not necessary but increases throughput. | 338 | * to fail earlier. This is not necessary but increases throughput. |
340 | * FIXME: Is this really intelligent? | 339 | * FIXME: Is this really intelligent? |
341 | */ | 340 | */ |
342 | current->flags &= ~PF_MEMALLOC; | ||
343 | |||
344 | if (base_bio) | 341 | if (base_bio) |
345 | bio = bio_clone(base_bio, GFP_NOIO); | 342 | bio = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC); |
346 | else | 343 | else |
347 | bio = bio_alloc(GFP_NOIO, nr_iovecs); | 344 | bio = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs); |
348 | if (!bio) { | 345 | if (!bio) |
349 | if (flags & PF_MEMALLOC) | ||
350 | current->flags |= PF_MEMALLOC; | ||
351 | return NULL; | 346 | return NULL; |
352 | } | ||
353 | 347 | ||
354 | /* if the last bio was not complete, continue where that one ended */ | 348 | /* if the last bio was not complete, continue where that one ended */ |
355 | bio->bi_idx = *bio_vec_idx; | 349 | bio->bi_idx = *bio_vec_idx; |
@@ -386,9 +380,6 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
386 | size -= bv->bv_len; | 380 | size -= bv->bv_len; |
387 | } | 381 | } |
388 | 382 | ||
389 | if (flags & PF_MEMALLOC) | ||
390 | current->flags |= PF_MEMALLOC; | ||
391 | |||
392 | if (!bio->bi_size) { | 383 | if (!bio->bi_size) { |
393 | bio_put(bio); | 384 | bio_put(bio); |
394 | return NULL; | 385 | return NULL; |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index c9b134cd1532..1891e4930dcc 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -355,7 +355,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number) | |||
355 | goto abort; | 355 | goto abort; |
356 | } | 356 | } |
357 | p->rdev = NULL; | 357 | p->rdev = NULL; |
358 | synchronize_kernel(); | 358 | synchronize_rcu(); |
359 | if (atomic_read(&rdev->nr_pending)) { | 359 | if (atomic_read(&rdev->nr_pending)) { |
360 | /* lost the race, try later */ | 360 | /* lost the race, try later */ |
361 | err = -EBUSY; | 361 | err = -EBUSY; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a389394b52f6..83380b5d6593 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -797,7 +797,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) | |||
797 | goto abort; | 797 | goto abort; |
798 | } | 798 | } |
799 | p->rdev = NULL; | 799 | p->rdev = NULL; |
800 | synchronize_kernel(); | 800 | synchronize_rcu(); |
801 | if (atomic_read(&rdev->nr_pending)) { | 801 | if (atomic_read(&rdev->nr_pending)) { |
802 | /* lost the race, try later */ | 802 | /* lost the race, try later */ |
803 | err = -EBUSY; | 803 | err = -EBUSY; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b100bfe4fdca..e9dc2876a626 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -977,7 +977,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number) | |||
977 | goto abort; | 977 | goto abort; |
978 | } | 978 | } |
979 | p->rdev = NULL; | 979 | p->rdev = NULL; |
980 | synchronize_kernel(); | 980 | synchronize_rcu(); |
981 | if (atomic_read(&rdev->nr_pending)) { | 981 | if (atomic_read(&rdev->nr_pending)) { |
982 | /* lost the race, try later */ | 982 | /* lost the race, try later */ |
983 | err = -EBUSY; | 983 | err = -EBUSY; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 52c3a81c4aa7..e96e2a10a9c9 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1873,7 +1873,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number) | |||
1873 | goto abort; | 1873 | goto abort; |
1874 | } | 1874 | } |
1875 | p->rdev = NULL; | 1875 | p->rdev = NULL; |
1876 | synchronize_kernel(); | 1876 | synchronize_rcu(); |
1877 | if (atomic_read(&rdev->nr_pending)) { | 1877 | if (atomic_read(&rdev->nr_pending)) { |
1878 | /* lost the race, try later */ | 1878 | /* lost the race, try later */ |
1879 | err = -EBUSY; | 1879 | err = -EBUSY; |
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 7e30ab29691a..8a33f351e092 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -2038,7 +2038,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number) | |||
2038 | goto abort; | 2038 | goto abort; |
2039 | } | 2039 | } |
2040 | p->rdev = NULL; | 2040 | p->rdev = NULL; |
2041 | synchronize_kernel(); | 2041 | synchronize_rcu(); |
2042 | if (atomic_read(&rdev->nr_pending)) { | 2042 | if (atomic_read(&rdev->nr_pending)) { |
2043 | /* lost the race, try later */ | 2043 | /* lost the race, try later */ |
2044 | err = -EBUSY; | 2044 | err = -EBUSY; |
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c index 8c842e2f59a2..84a49d2ec919 100644 --- a/drivers/media/common/ir-common.c +++ b/drivers/media/common/ir-common.c | |||
@@ -131,10 +131,10 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
131 | [ 18 ] = KEY_KP0, | 131 | [ 18 ] = KEY_KP0, |
132 | 132 | ||
133 | [ 0 ] = KEY_POWER, | 133 | [ 0 ] = KEY_POWER, |
134 | // [ 27 ] = MTS button | 134 | [ 27 ] = KEY_LANGUAGE, //MTS button |
135 | [ 2 ] = KEY_TUNER, // TV/FM | 135 | [ 2 ] = KEY_TUNER, // TV/FM |
136 | [ 30 ] = KEY_VIDEO, | 136 | [ 30 ] = KEY_VIDEO, |
137 | // [ 22 ] = display button | 137 | [ 22 ] = KEY_INFO, //display button |
138 | [ 4 ] = KEY_VOLUMEUP, | 138 | [ 4 ] = KEY_VOLUMEUP, |
139 | [ 8 ] = KEY_VOLUMEDOWN, | 139 | [ 8 ] = KEY_VOLUMEDOWN, |
140 | [ 12 ] = KEY_CHANNELUP, | 140 | [ 12 ] = KEY_CHANNELUP, |
@@ -142,7 +142,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
142 | [ 3 ] = KEY_ZOOM, // fullscreen | 142 | [ 3 ] = KEY_ZOOM, // fullscreen |
143 | [ 31 ] = KEY_SUBTITLE, // closed caption/teletext | 143 | [ 31 ] = KEY_SUBTITLE, // closed caption/teletext |
144 | [ 32 ] = KEY_SLEEP, | 144 | [ 32 ] = KEY_SLEEP, |
145 | // [ 41 ] = boss key | 145 | [ 41 ] = KEY_SEARCH, //boss key |
146 | [ 20 ] = KEY_MUTE, | 146 | [ 20 ] = KEY_MUTE, |
147 | [ 43 ] = KEY_RED, | 147 | [ 43 ] = KEY_RED, |
148 | [ 44 ] = KEY_GREEN, | 148 | [ 44 ] = KEY_GREEN, |
@@ -150,17 +150,17 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
150 | [ 46 ] = KEY_BLUE, | 150 | [ 46 ] = KEY_BLUE, |
151 | [ 24 ] = KEY_KPPLUS, //fine tune + | 151 | [ 24 ] = KEY_KPPLUS, //fine tune + |
152 | [ 25 ] = KEY_KPMINUS, //fine tune - | 152 | [ 25 ] = KEY_KPMINUS, //fine tune - |
153 | // [ 42 ] = picture in picture | 153 | [ 42 ] = KEY_ANGLE, //picture in picture |
154 | [ 33 ] = KEY_KPDOT, | 154 | [ 33 ] = KEY_KPDOT, |
155 | [ 19 ] = KEY_KPENTER, | 155 | [ 19 ] = KEY_KPENTER, |
156 | // [ 17 ] = recall | 156 | [ 17 ] = KEY_AGAIN, //recall |
157 | [ 34 ] = KEY_BACK, | 157 | [ 34 ] = KEY_BACK, |
158 | [ 35 ] = KEY_PLAYPAUSE, | 158 | [ 35 ] = KEY_PLAYPAUSE, |
159 | [ 36 ] = KEY_NEXT, | 159 | [ 36 ] = KEY_NEXT, |
160 | // [ 37 ] = time shifting | 160 | [ 37 ] = KEY_T, //time shifting |
161 | [ 38 ] = KEY_STOP, | 161 | [ 38 ] = KEY_STOP, |
162 | [ 39 ] = KEY_RECORD | 162 | [ 39 ] = KEY_RECORD, |
163 | // [ 40 ] = snapshot | 163 | [ 40 ] = KEY_SHUFFLE //snapshot |
164 | }; | 164 | }; |
165 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | 165 | EXPORT_SYMBOL_GPL(ir_codes_winfast); |
166 | 166 | ||
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 1930b513eefa..011860ce36cc 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
35 | #include "dvb-pll.h" | ||
35 | #include "cx22702.h" | 36 | #include "cx22702.h" |
36 | 37 | ||
37 | 38 | ||
@@ -203,7 +204,19 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
203 | 204 | ||
204 | /* set PLL */ | 205 | /* set PLL */ |
205 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); | 206 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); |
206 | state->config->pll_set(fe, p); | 207 | if (state->config->pll_set) { |
208 | state->config->pll_set(fe, p); | ||
209 | } else if (state->config->pll_desc) { | ||
210 | u8 pllbuf[4]; | ||
211 | struct i2c_msg msg = { .addr = state->config->pll_address, | ||
212 | .buf = pllbuf, .len = 4 }; | ||
213 | dvb_pll_configure(state->config->pll_desc, pllbuf, | ||
214 | p->frequency, | ||
215 | p->u.ofdm.bandwidth); | ||
216 | i2c_transfer(state->i2c, &msg, 1); | ||
217 | } else { | ||
218 | BUG(); | ||
219 | } | ||
207 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 220 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); |
208 | 221 | ||
209 | /* set inversion */ | 222 | /* set inversion */ |
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index 6e34f997aba2..559fdb906669 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h | |||
@@ -36,6 +36,9 @@ struct cx22702_config | |||
36 | u8 demod_address; | 36 | u8 demod_address; |
37 | 37 | ||
38 | /* PLL maintenance */ | 38 | /* PLL maintenance */ |
39 | u8 pll_address; | ||
40 | struct dvb_pll_desc *pll_desc; | ||
41 | |||
39 | int (*pll_init)(struct dvb_frontend* fe); | 42 | int (*pll_init)(struct dvb_frontend* fe); |
40 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 43 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
41 | }; | 44 | }; |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index c1b3542dad88..d3dd4228b72d 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -252,6 +252,7 @@ config VIDEO_SAA7134_DVB | |||
252 | depends on VIDEO_SAA7134 && DVB_CORE | 252 | depends on VIDEO_SAA7134 && DVB_CORE |
253 | select VIDEO_BUF_DVB | 253 | select VIDEO_BUF_DVB |
254 | select DVB_MT352 | 254 | select DVB_MT352 |
255 | select DVB_CX22702 | ||
255 | ---help--- | 256 | ---help--- |
256 | This adds support for DVB cards based on the | 257 | This adds support for DVB cards based on the |
257 | Philips saa7134 chip. | 258 | Philips saa7134 chip. |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index c13f222fe6bd..033cc5498f23 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -3169,7 +3169,7 @@ static struct video_device radio_template = | |||
3169 | /* ----------------------------------------------------------------------- */ | 3169 | /* ----------------------------------------------------------------------- */ |
3170 | /* some debug code */ | 3170 | /* some debug code */ |
3171 | 3171 | ||
3172 | int bttv_risc_decode(u32 risc) | 3172 | static int bttv_risc_decode(u32 risc) |
3173 | { | 3173 | { |
3174 | static char *instr[16] = { | 3174 | static char *instr[16] = { |
3175 | [ BT848_RISC_WRITE >> 28 ] = "write", | 3175 | [ BT848_RISC_WRITE >> 28 ] = "write", |
@@ -3206,8 +3206,8 @@ int bttv_risc_decode(u32 risc) | |||
3206 | return incr[risc >> 28] ? incr[risc >> 28] : 1; | 3206 | return incr[risc >> 28] ? incr[risc >> 28] : 1; |
3207 | } | 3207 | } |
3208 | 3208 | ||
3209 | void bttv_risc_disasm(struct bttv *btv, | 3209 | static void bttv_risc_disasm(struct bttv *btv, |
3210 | struct btcx_riscmem *risc) | 3210 | struct btcx_riscmem *risc) |
3211 | { | 3211 | { |
3212 | unsigned int i,j,n; | 3212 | unsigned int i,j,n; |
3213 | 3213 | ||
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 26a6138015cb..1ff79b5a8835 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -429,7 +429,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, | |||
429 | /* ------------------------------------------------------------------ */ | 429 | /* ------------------------------------------------------------------ */ |
430 | /* debug helper code */ | 430 | /* debug helper code */ |
431 | 431 | ||
432 | int cx88_risc_decode(u32 risc) | 432 | static int cx88_risc_decode(u32 risc) |
433 | { | 433 | { |
434 | static char *instr[16] = { | 434 | static char *instr[16] = { |
435 | [ RISC_SYNC >> 28 ] = "sync", | 435 | [ RISC_SYNC >> 28 ] = "sync", |
@@ -542,7 +542,7 @@ void cx88_sram_channel_dump(struct cx88_core *core, | |||
542 | core->name,cx_read(ch->cnt2_reg)); | 542 | core->name,cx_read(ch->cnt2_reg)); |
543 | } | 543 | } |
544 | 544 | ||
545 | char *cx88_pci_irqs[32] = { | 545 | static char *cx88_pci_irqs[32] = { |
546 | "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", | 546 | "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", |
547 | "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err", | 547 | "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err", |
548 | "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err", | 548 | "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err", |
@@ -1206,7 +1206,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) | |||
1206 | /* ------------------------------------------------------------------ */ | 1206 | /* ------------------------------------------------------------------ */ |
1207 | 1207 | ||
1208 | EXPORT_SYMBOL(cx88_print_ioctl); | 1208 | EXPORT_SYMBOL(cx88_print_ioctl); |
1209 | EXPORT_SYMBOL(cx88_pci_irqs); | ||
1210 | EXPORT_SYMBOL(cx88_vid_irqs); | 1209 | EXPORT_SYMBOL(cx88_vid_irqs); |
1211 | EXPORT_SYMBOL(cx88_mpeg_irqs); | 1210 | EXPORT_SYMBOL(cx88_mpeg_irqs); |
1212 | EXPORT_SYMBOL(cx88_print_irqbits); | 1211 | EXPORT_SYMBOL(cx88_print_irqbits); |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index bc6f18c45357..9d15d3d5a2b7 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/suspend.h> | 31 | #include <linux/suspend.h> |
32 | 32 | ||
33 | /* those two frontends need merging via linuxtv cvs ... */ | 33 | /* those two frontends need merging via linuxtv cvs ... */ |
34 | #define HAVE_CX22702 0 | 34 | #define HAVE_CX22702 1 |
35 | #define HAVE_OR51132 1 | 35 | #define HAVE_OR51132 1 |
36 | 36 | ||
37 | #include "cx88.h" | 37 | #include "cx88.h" |
@@ -91,7 +91,7 @@ static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb | |||
91 | cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb); | 91 | cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb); |
92 | } | 92 | } |
93 | 93 | ||
94 | struct videobuf_queue_ops dvb_qops = { | 94 | static struct videobuf_queue_ops dvb_qops = { |
95 | .buf_setup = dvb_buf_setup, | 95 | .buf_setup = dvb_buf_setup, |
96 | .buf_prepare = dvb_buf_prepare, | 96 | .buf_prepare = dvb_buf_prepare, |
97 | .buf_queue = dvb_buf_queue, | 97 | .buf_queue = dvb_buf_queue, |
@@ -191,7 +191,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, | |||
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | struct or51132_config pchdtv_hd3000 = { | 194 | static struct or51132_config pchdtv_hd3000 = { |
195 | .demod_address = 0x15, | 195 | .demod_address = 0x15, |
196 | .pll_address = 0x61, | 196 | .pll_address = 0x61, |
197 | .pll_desc = &dvb_pll_thomson_dtt7610, | 197 | .pll_desc = &dvb_pll_thomson_dtt7610, |
@@ -243,10 +243,8 @@ static int dvb_register(struct cx8802_dev *dev) | |||
243 | break; | 243 | break; |
244 | #endif | 244 | #endif |
245 | default: | 245 | default: |
246 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n" | 246 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
247 | "%s: you might want to look out for patches here:\n" | 247 | dev->core->name); |
248 | "%s: http://dl.bytesex.org/patches/\n", | ||
249 | dev->core->name, dev->core->name, dev->core->name); | ||
250 | break; | 248 | break; |
251 | } | 249 | } |
252 | if (NULL == dev->dvb.frontend) { | 250 | if (NULL == dev->dvb.frontend) { |
@@ -308,9 +306,11 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
308 | dev); | 306 | dev); |
309 | err = dvb_register(dev); | 307 | err = dvb_register(dev); |
310 | if (0 != err) | 308 | if (0 != err) |
311 | goto fail_free; | 309 | goto fail_fini; |
312 | return 0; | 310 | return 0; |
313 | 311 | ||
312 | fail_fini: | ||
313 | cx8802_fini_common(dev); | ||
314 | fail_free: | 314 | fail_free: |
315 | kfree(dev); | 315 | kfree(dev); |
316 | fail_core: | 316 | fail_core: |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 60800172c026..0725b1288f4f 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); | |||
45 | 45 | ||
46 | /* ----------------------------------------------------------------------- */ | 46 | /* ----------------------------------------------------------------------- */ |
47 | 47 | ||
48 | void cx8800_bit_setscl(void *data, int state) | 48 | static void cx8800_bit_setscl(void *data, int state) |
49 | { | 49 | { |
50 | struct cx88_core *core = data; | 50 | struct cx88_core *core = data; |
51 | 51 | ||
@@ -57,7 +57,7 @@ void cx8800_bit_setscl(void *data, int state) | |||
57 | cx_read(MO_I2C); | 57 | cx_read(MO_I2C); |
58 | } | 58 | } |
59 | 59 | ||
60 | void cx8800_bit_setsda(void *data, int state) | 60 | static void cx8800_bit_setsda(void *data, int state) |
61 | { | 61 | { |
62 | struct cx88_core *core = data; | 62 | struct cx88_core *core = data; |
63 | 63 | ||
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index 471e508b0746..0584ff476387 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c | |||
@@ -46,9 +46,9 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f) | |||
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | int cx8800_start_vbi_dma(struct cx8800_dev *dev, | 49 | static int cx8800_start_vbi_dma(struct cx8800_dev *dev, |
50 | struct cx88_dmaqueue *q, | 50 | struct cx88_dmaqueue *q, |
51 | struct cx88_buffer *buf) | 51 | struct cx88_buffer *buf) |
52 | { | 52 | { |
53 | struct cx88_core *core = dev->core; | 53 | struct cx88_core *core = dev->core; |
54 | 54 | ||
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 701f594e1816..d1f5c92f0ce5 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -325,7 +325,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
325 | .shift = 0, | 325 | .shift = 0, |
326 | } | 326 | } |
327 | }; | 327 | }; |
328 | const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); | 328 | static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); |
329 | 329 | ||
330 | /* ------------------------------------------------------------------- */ | 330 | /* ------------------------------------------------------------------- */ |
331 | /* resource management */ | 331 | /* resource management */ |
@@ -665,7 +665,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
665 | cx88_free_buffer(fh->dev->pci,buf); | 665 | cx88_free_buffer(fh->dev->pci,buf); |
666 | } | 666 | } |
667 | 667 | ||
668 | struct videobuf_queue_ops cx8800_video_qops = { | 668 | static struct videobuf_queue_ops cx8800_video_qops = { |
669 | .buf_setup = buffer_setup, | 669 | .buf_setup = buffer_setup, |
670 | .buf_prepare = buffer_prepare, | 670 | .buf_prepare = buffer_prepare, |
671 | .buf_queue = buffer_queue, | 671 | .buf_queue = buffer_queue, |
@@ -1924,7 +1924,7 @@ static struct file_operations video_fops = | |||
1924 | .llseek = no_llseek, | 1924 | .llseek = no_llseek, |
1925 | }; | 1925 | }; |
1926 | 1926 | ||
1927 | struct video_device cx8800_video_template = | 1927 | static struct video_device cx8800_video_template = |
1928 | { | 1928 | { |
1929 | .name = "cx8800-video", | 1929 | .name = "cx8800-video", |
1930 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, | 1930 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, |
@@ -1933,7 +1933,7 @@ struct video_device cx8800_video_template = | |||
1933 | .minor = -1, | 1933 | .minor = -1, |
1934 | }; | 1934 | }; |
1935 | 1935 | ||
1936 | struct video_device cx8800_vbi_template = | 1936 | static struct video_device cx8800_vbi_template = |
1937 | { | 1937 | { |
1938 | .name = "cx8800-vbi", | 1938 | .name = "cx8800-vbi", |
1939 | .type = VID_TYPE_TELETEXT|VID_TYPE_TUNER, | 1939 | .type = VID_TYPE_TELETEXT|VID_TYPE_TUNER, |
@@ -1951,7 +1951,7 @@ static struct file_operations radio_fops = | |||
1951 | .llseek = no_llseek, | 1951 | .llseek = no_llseek, |
1952 | }; | 1952 | }; |
1953 | 1953 | ||
1954 | struct video_device cx8800_radio_template = | 1954 | static struct video_device cx8800_radio_template = |
1955 | { | 1955 | { |
1956 | .name = "cx8800-radio", | 1956 | .name = "cx8800-radio", |
1957 | .type = VID_TYPE_TUNER, | 1957 | .type = VID_TYPE_TUNER, |
@@ -2226,7 +2226,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) | |||
2226 | 2226 | ||
2227 | /* ----------------------------------------------------------- */ | 2227 | /* ----------------------------------------------------------- */ |
2228 | 2228 | ||
2229 | struct pci_device_id cx8800_pci_tbl[] = { | 2229 | static struct pci_device_id cx8800_pci_tbl[] = { |
2230 | { | 2230 | { |
2231 | .vendor = 0x14f1, | 2231 | .vendor = 0x14f1, |
2232 | .device = 0x8800, | 2232 | .device = 0x8800, |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index b351d9eae615..88eaaaba5ad8 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -420,7 +420,6 @@ struct cx8802_dev { | |||
420 | /* ----------------------------------------------------------- */ | 420 | /* ----------------------------------------------------------- */ |
421 | /* cx88-core.c */ | 421 | /* cx88-core.c */ |
422 | 422 | ||
423 | extern char *cx88_pci_irqs[32]; | ||
424 | extern char *cx88_vid_irqs[32]; | 423 | extern char *cx88_vid_irqs[32]; |
425 | extern char *cx88_mpeg_irqs[32]; | 424 | extern char *cx88_mpeg_irqs[32]; |
426 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, | 425 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, |
@@ -472,9 +471,6 @@ extern void cx88_core_put(struct cx88_core *core, | |||
472 | /* cx88-vbi.c */ | 471 | /* cx88-vbi.c */ |
473 | 472 | ||
474 | void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f); | 473 | void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f); |
475 | int cx8800_start_vbi_dma(struct cx8800_dev *dev, | ||
476 | struct cx88_dmaqueue *q, | ||
477 | struct cx88_buffer *buf); | ||
478 | int cx8800_stop_vbi_dma(struct cx8800_dev *dev); | 474 | int cx8800_stop_vbi_dma(struct cx8800_dev *dev); |
479 | int cx8800_restart_vbi_queue(struct cx8800_dev *dev, | 475 | int cx8800_restart_vbi_queue(struct cx8800_dev *dev, |
480 | struct cx88_dmaqueue *q); | 476 | struct cx88_dmaqueue *q); |
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index c97df705df5e..7fbb8581a87d 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -380,7 +380,9 @@ static void msp3400c_setvolume(struct i2c_client *client, | |||
380 | int val = 0, bal = 0; | 380 | int val = 0, bal = 0; |
381 | 381 | ||
382 | if (!muted) { | 382 | if (!muted) { |
383 | val = (volume * 0x7F / 65535) << 8; | 383 | /* 0x7f instead if 0x73 here has sound quality issues, |
384 | * probably due to overmodulation + clipping ... */ | ||
385 | val = (volume * 0x73 / 65535) << 8; | ||
384 | } | 386 | } |
385 | if (val) { | 387 | if (val) { |
386 | bal = (balance / 256) - 128; | 388 | bal = (balance / 256) - 128; |
@@ -997,7 +999,13 @@ static int msp34xx_modus(int norm) | |||
997 | { | 999 | { |
998 | switch (norm) { | 1000 | switch (norm) { |
999 | case VIDEO_MODE_PAL: | 1001 | case VIDEO_MODE_PAL: |
1002 | #if 1 | ||
1003 | /* experimental: not sure this works with all chip versions */ | ||
1004 | return 0x7003; | ||
1005 | #else | ||
1006 | /* previous value, try this if it breaks ... */ | ||
1000 | return 0x1003; | 1007 | return 0x1003; |
1008 | #endif | ||
1001 | case VIDEO_MODE_NTSC: /* BTSC */ | 1009 | case VIDEO_MODE_NTSC: /* BTSC */ |
1002 | return 0x2003; | 1010 | return 0x2003; |
1003 | case VIDEO_MODE_SECAM: | 1011 | case VIDEO_MODE_SECAM: |
@@ -1264,6 +1272,7 @@ static int msp34xxg_thread(void *data) | |||
1264 | int val, std, i; | 1272 | int val, std, i; |
1265 | 1273 | ||
1266 | printk("msp34xxg: daemon started\n"); | 1274 | printk("msp34xxg: daemon started\n"); |
1275 | msp->source = 1; /* default */ | ||
1267 | for (;;) { | 1276 | for (;;) { |
1268 | d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); | 1277 | d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); |
1269 | msp34xx_sleep(msp,-1); | 1278 | msp34xx_sleep(msp,-1); |
@@ -1334,8 +1343,9 @@ static void msp34xxg_set_source(struct i2c_client *client, int source) | |||
1334 | 1343 | ||
1335 | /* fix matrix mode to stereo and let the msp choose what | 1344 | /* fix matrix mode to stereo and let the msp choose what |
1336 | * to output according to 'source', as recommended | 1345 | * to output according to 'source', as recommended |
1346 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | ||
1337 | */ | 1347 | */ |
1338 | int value = (source&0x07)<<8|(source==0 ? 0x00:0x20); | 1348 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); |
1339 | dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); | 1349 | dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); |
1340 | msp3400c_write(client, | 1350 | msp3400c_write(client, |
1341 | I2C_MSP3400C_DFP, | 1351 | I2C_MSP3400C_DFP, |
@@ -1359,7 +1369,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source) | |||
1359 | msp3400c_write(client, | 1369 | msp3400c_write(client, |
1360 | I2C_MSP3400C_DEM, | 1370 | I2C_MSP3400C_DEM, |
1361 | 0x22, /* a2 threshold for stereo/bilingual */ | 1371 | 0x22, /* a2 threshold for stereo/bilingual */ |
1362 | source==0 ? 0x7f0:stereo_threshold); | 1372 | stereo_threshold); |
1363 | msp->source=source; | 1373 | msp->source=source; |
1364 | } | 1374 | } |
1365 | 1375 | ||
@@ -1394,7 +1404,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client) | |||
1394 | static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | 1404 | static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) |
1395 | { | 1405 | { |
1396 | struct msp3400c *msp = i2c_get_clientdata(client); | 1406 | struct msp3400c *msp = i2c_get_clientdata(client); |
1397 | int source = 0; | 1407 | int source; |
1398 | 1408 | ||
1399 | switch (audmode) { | 1409 | switch (audmode) { |
1400 | case V4L2_TUNER_MODE_MONO: | 1410 | case V4L2_TUNER_MODE_MONO: |
@@ -1410,9 +1420,10 @@ static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | |||
1410 | case V4L2_TUNER_MODE_LANG2: | 1420 | case V4L2_TUNER_MODE_LANG2: |
1411 | source=4; /* stereo or B */ | 1421 | source=4; /* stereo or B */ |
1412 | break; | 1422 | break; |
1413 | default: /* doing nothing: a safe, sane default */ | 1423 | default: |
1414 | audmode = 0; | 1424 | audmode = 0; |
1415 | return; | 1425 | source = 1; |
1426 | break; | ||
1416 | } | 1427 | } |
1417 | msp->audmode = audmode; | 1428 | msp->audmode = audmode; |
1418 | msp34xxg_set_source(client, source); | 1429 | msp34xxg_set_source(client, source); |
@@ -1514,12 +1525,9 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1514 | 1525 | ||
1515 | msp->opmode = opmode; | 1526 | msp->opmode = opmode; |
1516 | if (OPMODE_AUTO == msp->opmode) { | 1527 | if (OPMODE_AUTO == msp->opmode) { |
1517 | #if 0 /* seems to work for ivtv only, disable by default for now ... */ | ||
1518 | if (HAVE_SIMPLER(msp)) | 1528 | if (HAVE_SIMPLER(msp)) |
1519 | msp->opmode = OPMODE_SIMPLER; | 1529 | msp->opmode = OPMODE_SIMPLER; |
1520 | else | 1530 | else if (HAVE_SIMPLE(msp)) |
1521 | #endif | ||
1522 | if (HAVE_SIMPLE(msp)) | ||
1523 | msp->opmode = OPMODE_SIMPLE; | 1531 | msp->opmode = OPMODE_SIMPLE; |
1524 | else | 1532 | else |
1525 | msp->opmode = OPMODE_MANUAL; | 1533 | msp->opmode = OPMODE_MANUAL; |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 180d3175ea5b..c51eb7f078d3 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -183,12 +183,12 @@ struct saa7134_board saa7134_boards[] = { | |||
183 | .name = "LifeView FlyTV Platinum FM", | 183 | .name = "LifeView FlyTV Platinum FM", |
184 | .audio_clock = 0x00200000, | 184 | .audio_clock = 0x00200000, |
185 | .tuner_type = TUNER_PHILIPS_TDA8290, | 185 | .tuner_type = TUNER_PHILIPS_TDA8290, |
186 | // .gpiomask = 0xe000, | 186 | .gpiomask = 0x1E000, /* Set GP16 and unused 15,14,13 to Output */ |
187 | .inputs = {{ | 187 | .inputs = {{ |
188 | .name = name_tv, | 188 | .name = name_tv, |
189 | .vmux = 1, | 189 | .vmux = 1, |
190 | .amux = TV, | 190 | .amux = TV, |
191 | // .gpio = 0x0000, | 191 | .gpio = 0x10000, /* GP16=1 selects TV input */ |
192 | .tv = 1, | 192 | .tv = 1, |
193 | },{ | 193 | },{ |
194 | /* .name = name_tv_mono, | 194 | /* .name = name_tv_mono, |
@@ -212,12 +212,12 @@ struct saa7134_board saa7134_boards[] = { | |||
212 | .amux = LINE2, | 212 | .amux = LINE2, |
213 | // .gpio = 0x4000, | 213 | // .gpio = 0x4000, |
214 | }}, | 214 | }}, |
215 | /* .radio = { | 215 | .radio = { |
216 | .name = name_radio, | 216 | .name = name_radio, |
217 | .amux = LINE2, | 217 | .amux = TV, |
218 | .gpio = 0x2000, | 218 | .gpio = 0x00000, /* GP16=0 selects FM radio antenna */ |
219 | }, | 219 | }, |
220 | */ }, | 220 | }, |
221 | [SAA7134_BOARD_EMPRESS] = { | 221 | [SAA7134_BOARD_EMPRESS] = { |
222 | /* "Gert Vervoort" <gert.vervoort@philips.com> */ | 222 | /* "Gert Vervoort" <gert.vervoort@philips.com> */ |
223 | .name = "EMPRESS", | 223 | .name = "EMPRESS", |
@@ -1628,11 +1628,17 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
1628 | },{ | 1628 | },{ |
1629 | .vendor = PCI_VENDOR_ID_PHILIPS, | 1629 | .vendor = PCI_VENDOR_ID_PHILIPS, |
1630 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 1630 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
1631 | .subvendor = 0x5168, | 1631 | .subvendor = 0x5168, /* Animation Technologies (LifeView) */ |
1632 | .subdevice = 0x0214, /* Standard PCI, LR214WF */ | 1632 | .subdevice = 0x0214, /* Standard PCI, LR214WF */ |
1633 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, | 1633 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, |
1634 | },{ | 1634 | },{ |
1635 | .vendor = PCI_VENDOR_ID_PHILIPS, | 1635 | .vendor = PCI_VENDOR_ID_PHILIPS, |
1636 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
1637 | .subvendor = 0x1489, /* KYE */ | ||
1638 | .subdevice = 0x0214, /* Genius VideoWonder ProTV */ | ||
1639 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */ | ||
1640 | },{ | ||
1641 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
1636 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 1642 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
1637 | .subvendor = 0x16be, | 1643 | .subvendor = 0x16be, |
1638 | .subdevice = 0x0003, | 1644 | .subdevice = 0x0003, |
@@ -1948,6 +1954,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
1948 | dev->has_remote = 1; | 1954 | dev->has_remote = 1; |
1949 | board_flyvideo(dev); | 1955 | board_flyvideo(dev); |
1950 | break; | 1956 | break; |
1957 | case SAA7134_BOARD_FLYTVPLATINUM_FM: | ||
1951 | case SAA7134_BOARD_CINERGY400: | 1958 | case SAA7134_BOARD_CINERGY400: |
1952 | case SAA7134_BOARD_CINERGY600: | 1959 | case SAA7134_BOARD_CINERGY600: |
1953 | case SAA7134_BOARD_CINERGY600_MK3: | 1960 | case SAA7134_BOARD_CINERGY600_MK3: |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index dd4a6c8ee65f..c2873ae029f9 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -172,7 +172,7 @@ static int fe_request_firmware(struct dvb_frontend* fe, | |||
172 | return request_firmware(fw, name, &dev->pci->dev); | 172 | return request_firmware(fw, name, &dev->pci->dev); |
173 | } | 173 | } |
174 | 174 | ||
175 | struct tda1004x_config medion_cardbus = { | 175 | static struct tda1004x_config medion_cardbus = { |
176 | .demod_address = 0x08, /* not sure this is correct */ | 176 | .demod_address = 0x08, /* not sure this is correct */ |
177 | .invert = 0, | 177 | .invert = 0, |
178 | .invert_oclk = 0, | 178 | .invert_oclk = 0, |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 727d437e07df..ca50cf531f20 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -379,6 +379,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
379 | switch (dev->board) { | 379 | switch (dev->board) { |
380 | case SAA7134_BOARD_FLYVIDEO2000: | 380 | case SAA7134_BOARD_FLYVIDEO2000: |
381 | case SAA7134_BOARD_FLYVIDEO3000: | 381 | case SAA7134_BOARD_FLYVIDEO3000: |
382 | case SAA7134_BOARD_FLYTVPLATINUM_FM: | ||
382 | ir_codes = flyvideo_codes; | 383 | ir_codes = flyvideo_codes; |
383 | mask_keycode = 0xEC00000; | 384 | mask_keycode = 0xEC00000; |
384 | mask_keydown = 0x0040000; | 385 | mask_keydown = 0x0040000; |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 065eb4007b1d..80dc34f18c2c 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -991,7 +991,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) | |||
991 | { | 991 | { |
992 | if (tda9874a_SIF > 2) | 992 | if (tda9874a_SIF > 2) |
993 | tda9874a_SIF = 1; | 993 | tda9874a_SIF = 1; |
994 | if (tda9874a_STD >= 8) | 994 | if (tda9874a_STD > 8) |
995 | tda9874a_STD = 0; | 995 | tda9874a_STD = 0; |
996 | if(tda9874a_AMSEL > 1) | 996 | if(tda9874a_AMSEL > 1) |
997 | tda9874a_AMSEL = 0; | 997 | tda9874a_AMSEL = 0; |
diff --git a/drivers/net/gt96100eth.h b/drivers/net/gt96100eth.h index 2f4bfd4dacbe..395869c5ed3e 100644 --- a/drivers/net/gt96100eth.h +++ b/drivers/net/gt96100eth.h | |||
@@ -214,7 +214,7 @@ typedef struct { | |||
214 | u32 cmdstat; | 214 | u32 cmdstat; |
215 | u32 next; | 215 | u32 next; |
216 | u32 buff_ptr; | 216 | u32 buff_ptr; |
217 | } gt96100_td_t __attribute__ ((packed)); | 217 | } __attribute__ ((packed)) gt96100_td_t; |
218 | 218 | ||
219 | typedef struct { | 219 | typedef struct { |
220 | #ifdef DESC_BE | 220 | #ifdef DESC_BE |
@@ -227,7 +227,7 @@ typedef struct { | |||
227 | u32 cmdstat; | 227 | u32 cmdstat; |
228 | u32 next; | 228 | u32 next; |
229 | u32 buff_ptr; | 229 | u32 buff_ptr; |
230 | } gt96100_rd_t __attribute__ ((packed)); | 230 | } __attribute__ ((packed)) gt96100_rd_t; |
231 | 231 | ||
232 | 232 | ||
233 | /* Values for the Tx command-status descriptor entry. */ | 233 | /* Values for the Tx command-status descriptor entry. */ |
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index acb170152bbd..b3a898c5a585 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c | |||
@@ -13,8 +13,8 @@ | |||
13 | ** This driver has only been tested with | 13 | ** This driver has only been tested with |
14 | ** -- HP J2585B 10/100 Mbit/s PCI Busmaster | 14 | ** -- HP J2585B 10/100 Mbit/s PCI Busmaster |
15 | ** -- HP J2585A 10/100 Mbit/s PCI | 15 | ** -- HP J2585A 10/100 Mbit/s PCI |
16 | ** -- HP J2970 10 Mbit/s PCI Combo 10base-T/BNC | 16 | ** -- HP J2970A 10 Mbit/s PCI Combo 10base-T/BNC |
17 | ** -- HP J2973 10 Mbit/s PCI 10base-T | 17 | ** -- HP J2973A 10 Mbit/s PCI 10base-T |
18 | ** -- HP J2573 10/100 ISA | 18 | ** -- HP J2573 10/100 ISA |
19 | ** -- Compex ReadyLink ENET100-VG4 10/100 Mbit/s PCI / EISA | 19 | ** -- Compex ReadyLink ENET100-VG4 10/100 Mbit/s PCI / EISA |
20 | ** -- Compex FreedomLine 100/VG 10/100 Mbit/s ISA / EISA / PCI | 20 | ** -- Compex FreedomLine 100/VG 10/100 Mbit/s ISA / EISA / PCI |
diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c index 507d6328d4eb..3872088fdd10 100644 --- a/drivers/net/ppp_deflate.c +++ b/drivers/net/ppp_deflate.c | |||
@@ -87,8 +87,7 @@ static void z_comp_free(void *arg) | |||
87 | 87 | ||
88 | if (state) { | 88 | if (state) { |
89 | zlib_deflateEnd(&state->strm); | 89 | zlib_deflateEnd(&state->strm); |
90 | if (state->strm.workspace) | 90 | vfree(state->strm.workspace); |
91 | vfree(state->strm.workspace); | ||
92 | kfree(state); | 91 | kfree(state); |
93 | } | 92 | } |
94 | } | 93 | } |
@@ -308,8 +307,7 @@ static void z_decomp_free(void *arg) | |||
308 | 307 | ||
309 | if (state) { | 308 | if (state) { |
310 | zlib_inflateEnd(&state->strm); | 309 | zlib_inflateEnd(&state->strm); |
311 | if (state->strm.workspace) | 310 | kfree(state->strm.workspace); |
312 | kfree(state->strm.workspace); | ||
313 | kfree(state); | 311 | kfree(state); |
314 | } | 312 | } |
315 | } | 313 | } |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index c456dc81b873..3b377f6cd4a0 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -2467,14 +2467,10 @@ static void ppp_destroy_interface(struct ppp *ppp) | |||
2467 | skb_queue_purge(&ppp->mrq); | 2467 | skb_queue_purge(&ppp->mrq); |
2468 | #endif /* CONFIG_PPP_MULTILINK */ | 2468 | #endif /* CONFIG_PPP_MULTILINK */ |
2469 | #ifdef CONFIG_PPP_FILTER | 2469 | #ifdef CONFIG_PPP_FILTER |
2470 | if (ppp->pass_filter) { | 2470 | kfree(ppp->pass_filter); |
2471 | kfree(ppp->pass_filter); | 2471 | ppp->pass_filter = NULL; |
2472 | ppp->pass_filter = NULL; | 2472 | kfree(ppp->active_filter); |
2473 | } | 2473 | ppp->active_filter = NULL; |
2474 | if (ppp->active_filter) { | ||
2475 | kfree(ppp->active_filter); | ||
2476 | ppp->active_filter = NULL; | ||
2477 | } | ||
2478 | #endif /* CONFIG_PPP_FILTER */ | 2474 | #endif /* CONFIG_PPP_FILTER */ |
2479 | 2475 | ||
2480 | kfree(ppp); | 2476 | kfree(ppp); |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 07e2df09491f..c59507f8a76b 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -2385,7 +2385,7 @@ core_down: | |||
2385 | } | 2385 | } |
2386 | 2386 | ||
2387 | /* Give a racing hard_start_xmit a few cycles to complete. */ | 2387 | /* Give a racing hard_start_xmit a few cycles to complete. */ |
2388 | synchronize_kernel(); | 2388 | synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ |
2389 | 2389 | ||
2390 | /* | 2390 | /* |
2391 | * And now for the 50k$ question: are IRQ disabled or not ? | 2391 | * And now for the 50k$ question: are IRQ disabled or not ? |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 903d0ced7ddb..058c70c6f1ac 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -5830,7 +5830,7 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
5830 | free_irq(tp->pdev->irq, dev); | 5830 | free_irq(tp->pdev->irq, dev); |
5831 | 5831 | ||
5832 | err = request_irq(tp->pdev->irq, tg3_test_isr, | 5832 | err = request_irq(tp->pdev->irq, tg3_test_isr, |
5833 | SA_SHIRQ, dev->name, dev); | 5833 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); |
5834 | if (err) | 5834 | if (err) |
5835 | return err; | 5835 | return err; |
5836 | 5836 | ||
@@ -5852,10 +5852,10 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
5852 | 5852 | ||
5853 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) | 5853 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) |
5854 | err = request_irq(tp->pdev->irq, tg3_msi, | 5854 | err = request_irq(tp->pdev->irq, tg3_msi, |
5855 | 0, dev->name, dev); | 5855 | SA_SAMPLE_RANDOM, dev->name, dev); |
5856 | else | 5856 | else |
5857 | err = request_irq(tp->pdev->irq, tg3_interrupt, | 5857 | err = request_irq(tp->pdev->irq, tg3_interrupt, |
5858 | SA_SHIRQ, dev->name, dev); | 5858 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); |
5859 | 5859 | ||
5860 | if (err) | 5860 | if (err) |
5861 | return err; | 5861 | return err; |
@@ -5908,7 +5908,7 @@ static int tg3_test_msi(struct tg3 *tp) | |||
5908 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; | 5908 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; |
5909 | 5909 | ||
5910 | err = request_irq(tp->pdev->irq, tg3_interrupt, | 5910 | err = request_irq(tp->pdev->irq, tg3_interrupt, |
5911 | SA_SHIRQ, dev->name, dev); | 5911 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); |
5912 | 5912 | ||
5913 | if (err) | 5913 | if (err) |
5914 | return err; | 5914 | return err; |
@@ -5965,10 +5965,10 @@ static int tg3_open(struct net_device *dev) | |||
5965 | } | 5965 | } |
5966 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) | 5966 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) |
5967 | err = request_irq(tp->pdev->irq, tg3_msi, | 5967 | err = request_irq(tp->pdev->irq, tg3_msi, |
5968 | 0, dev->name, dev); | 5968 | SA_SAMPLE_RANDOM, dev->name, dev); |
5969 | else | 5969 | else |
5970 | err = request_irq(tp->pdev->irq, tg3_interrupt, | 5970 | err = request_irq(tp->pdev->irq, tg3_interrupt, |
5971 | SA_SHIRQ, dev->name, dev); | 5971 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); |
5972 | 5972 | ||
5973 | if (err) { | 5973 | if (err) { |
5974 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { | 5974 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { |
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 5b48cd8568f5..02d57c0b4243 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c | |||
@@ -436,9 +436,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev, | |||
436 | } | 436 | } |
437 | 437 | ||
438 | if (err) { | 438 | if (err) { |
439 | if (chan->local_addr) | 439 | kfree(chan->local_addr); |
440 | kfree(chan->local_addr); | ||
441 | |||
442 | kfree(chan); | 440 | kfree(chan); |
443 | return err; | 441 | return err; |
444 | } | 442 | } |
@@ -458,9 +456,7 @@ static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev) | |||
458 | struct cycx_x25_channel *chan = dev->priv; | 456 | struct cycx_x25_channel *chan = dev->priv; |
459 | 457 | ||
460 | if (chan->svc) { | 458 | if (chan->svc) { |
461 | if (chan->local_addr) | 459 | kfree(chan->local_addr); |
462 | kfree(chan->local_addr); | ||
463 | |||
464 | if (chan->state == WAN_CONNECTED) | 460 | if (chan->state == WAN_CONNECTED) |
465 | del_timer(&chan->timer); | 461 | del_timer(&chan->timer); |
466 | } | 462 | } |
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 29f84ad08730..8454bf6caaa7 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c | |||
@@ -400,10 +400,8 @@ static void cpc_tty_close(struct tty_struct *tty, struct file *flip) | |||
400 | cpc_tty->buf_rx.last = NULL; | 400 | cpc_tty->buf_rx.last = NULL; |
401 | } | 401 | } |
402 | 402 | ||
403 | if (cpc_tty->buf_tx) { | 403 | kfree(cpc_tty->buf_tx); |
404 | kfree(cpc_tty->buf_tx); | 404 | cpc_tty->buf_tx = NULL; |
405 | cpc_tty->buf_tx = NULL; | ||
406 | } | ||
407 | 405 | ||
408 | CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); | 406 | CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); |
409 | 407 | ||
@@ -666,7 +664,7 @@ static void cpc_tty_rx_work(void * data) | |||
666 | unsigned long port; | 664 | unsigned long port; |
667 | int i, j; | 665 | int i, j; |
668 | st_cpc_tty_area *cpc_tty; | 666 | st_cpc_tty_area *cpc_tty; |
669 | volatile st_cpc_rx_buf * buf; | 667 | volatile st_cpc_rx_buf *buf; |
670 | char flags=0,flg_rx=1; | 668 | char flags=0,flg_rx=1; |
671 | struct tty_ldisc *ld; | 669 | struct tty_ldisc *ld; |
672 | 670 | ||
@@ -680,9 +678,9 @@ static void cpc_tty_rx_work(void * data) | |||
680 | cpc_tty = &cpc_tty_area[port]; | 678 | cpc_tty = &cpc_tty_area[port]; |
681 | 679 | ||
682 | if ((buf=cpc_tty->buf_rx.first) != 0) { | 680 | if ((buf=cpc_tty->buf_rx.first) != 0) { |
683 | if(cpc_tty->tty) { | 681 | if (cpc_tty->tty) { |
684 | ld = tty_ldisc_ref(cpc_tty->tty); | 682 | ld = tty_ldisc_ref(cpc_tty->tty); |
685 | if(ld) { | 683 | if (ld) { |
686 | if (ld->receive_buf) { | 684 | if (ld->receive_buf) { |
687 | CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); | 685 | CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); |
688 | ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size); | 686 | ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size); |
@@ -691,7 +689,7 @@ static void cpc_tty_rx_work(void * data) | |||
691 | } | 689 | } |
692 | } | 690 | } |
693 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; | 691 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; |
694 | kfree((unsigned char *)buf); | 692 | kfree(buf); |
695 | buf = cpc_tty->buf_rx.first; | 693 | buf = cpc_tty->buf_rx.first; |
696 | flg_rx = 1; | 694 | flg_rx = 1; |
697 | } | 695 | } |
@@ -733,7 +731,7 @@ static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan) | |||
733 | 731 | ||
734 | void cpc_tty_receive(pc300dev_t *pc300dev) | 732 | void cpc_tty_receive(pc300dev_t *pc300dev) |
735 | { | 733 | { |
736 | st_cpc_tty_area *cpc_tty; | 734 | st_cpc_tty_area *cpc_tty; |
737 | pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; | 735 | pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; |
738 | pc300_t *card = (pc300_t *)pc300chan->card; | 736 | pc300_t *card = (pc300_t *)pc300chan->card; |
739 | int ch = pc300chan->channel; | 737 | int ch = pc300chan->channel; |
@@ -742,7 +740,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev) | |||
742 | int rx_len, rx_aux; | 740 | int rx_len, rx_aux; |
743 | volatile unsigned char status; | 741 | volatile unsigned char status; |
744 | unsigned short first_bd = pc300chan->rx_first_bd; | 742 | unsigned short first_bd = pc300chan->rx_first_bd; |
745 | st_cpc_rx_buf *new=NULL; | 743 | st_cpc_rx_buf *new = NULL; |
746 | unsigned char dsr_rx; | 744 | unsigned char dsr_rx; |
747 | 745 | ||
748 | if (pc300dev->cpc_tty == NULL) { | 746 | if (pc300dev->cpc_tty == NULL) { |
@@ -762,7 +760,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev) | |||
762 | if (status & DST_EOM) { | 760 | if (status & DST_EOM) { |
763 | break; | 761 | break; |
764 | } | 762 | } |
765 | ptdescr=(pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next)); | 763 | ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next)); |
766 | } | 764 | } |
767 | 765 | ||
768 | if (!rx_len) { | 766 | if (!rx_len) { |
@@ -771,10 +769,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev) | |||
771 | cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), | 769 | cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), |
772 | RX_BD_ADDR(ch, pc300chan->rx_last_bd)); | 770 | RX_BD_ADDR(ch, pc300chan->rx_last_bd)); |
773 | } | 771 | } |
774 | if (new) { | 772 | kfree(new); |
775 | kfree(new); | ||
776 | new = NULL; | ||
777 | } | ||
778 | return; | 773 | return; |
779 | } | 774 | } |
780 | 775 | ||
@@ -787,7 +782,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev) | |||
787 | continue; | 782 | continue; |
788 | } | 783 | } |
789 | 784 | ||
790 | new = (st_cpc_rx_buf *) kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC); | 785 | new = (st_cpc_rx_buf *)kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC); |
791 | if (new == 0) { | 786 | if (new == 0) { |
792 | cpc_tty_rx_disc_frame(pc300chan); | 787 | cpc_tty_rx_disc_frame(pc300chan); |
793 | continue; | 788 | continue; |
diff --git a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c index afbe0024e3e1..496d29237e92 100644 --- a/drivers/net/wan/sdla_chdlc.c +++ b/drivers/net/wan/sdla_chdlc.c | |||
@@ -3664,15 +3664,10 @@ static void wanpipe_tty_close(struct tty_struct *tty, struct file * filp) | |||
3664 | chdlc_disable_comm_shutdown(card); | 3664 | chdlc_disable_comm_shutdown(card); |
3665 | unlock_adapter_irq(&card->wandev.lock,&smp_flags); | 3665 | unlock_adapter_irq(&card->wandev.lock,&smp_flags); |
3666 | 3666 | ||
3667 | if (card->tty_buf){ | 3667 | kfree(card->tty_buf); |
3668 | kfree(card->tty_buf); | 3668 | card->tty_buf = NULL; |
3669 | card->tty_buf=NULL; | 3669 | kfree(card->tty_rx); |
3670 | } | 3670 | card->tty_rx = NULL; |
3671 | |||
3672 | if (card->tty_rx){ | ||
3673 | kfree(card->tty_rx); | ||
3674 | card->tty_rx=NULL; | ||
3675 | } | ||
3676 | } | 3671 | } |
3677 | return; | 3672 | return; |
3678 | } | 3673 | } |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 8c5cfcb55826..1c540d825551 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -107,13 +107,9 @@ static struct x25_asy *x25_asy_alloc(void) | |||
107 | static void x25_asy_free(struct x25_asy *sl) | 107 | static void x25_asy_free(struct x25_asy *sl) |
108 | { | 108 | { |
109 | /* Free all X.25 frame buffers. */ | 109 | /* Free all X.25 frame buffers. */ |
110 | if (sl->rbuff) { | 110 | kfree(sl->rbuff); |
111 | kfree(sl->rbuff); | ||
112 | } | ||
113 | sl->rbuff = NULL; | 111 | sl->rbuff = NULL; |
114 | if (sl->xbuff) { | 112 | kfree(sl->xbuff); |
115 | kfree(sl->xbuff); | ||
116 | } | ||
117 | sl->xbuff = NULL; | 113 | sl->xbuff = NULL; |
118 | 114 | ||
119 | if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) { | 115 | if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) { |
@@ -134,10 +130,8 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu) | |||
134 | { | 130 | { |
135 | printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n", | 131 | printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n", |
136 | dev->name); | 132 | dev->name); |
137 | if (xbuff != NULL) | 133 | kfree(xbuff); |
138 | kfree(xbuff); | 134 | kfree(rbuff); |
139 | if (rbuff != NULL) | ||
140 | kfree(rbuff); | ||
141 | return -ENOMEM; | 135 | return -ENOMEM; |
142 | } | 136 | } |
143 | 137 | ||
@@ -169,10 +163,8 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu) | |||
169 | 163 | ||
170 | spin_unlock_bh(&sl->lock); | 164 | spin_unlock_bh(&sl->lock); |
171 | 165 | ||
172 | if (xbuff != NULL) | 166 | kfree(xbuff); |
173 | kfree(xbuff); | 167 | kfree(rbuff); |
174 | if (rbuff != NULL) | ||
175 | kfree(rbuff); | ||
176 | return 0; | 168 | return 0; |
177 | } | 169 | } |
178 | 170 | ||
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index d471b3ea5d12..021d0f76bc4c 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c | |||
@@ -120,6 +120,10 @@ static int pci_visit_bridge (struct pci_visit * fn, | |||
120 | 120 | ||
121 | /** | 121 | /** |
122 | * pci_visit_dev - scans the pci buses. | 122 | * pci_visit_dev - scans the pci buses. |
123 | * @fn: callback functions that are called while visiting | ||
124 | * @wrapped_dev: the device to scan | ||
125 | * @wrapped_parent: the bus where @wrapped_dev is connected to | ||
126 | * | ||
123 | * Every bus and every function is presented to a custom | 127 | * Every bus and every function is presented to a custom |
124 | * function that can act upon it. | 128 | * function that can act upon it. |
125 | */ | 129 | */ |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 3e64ff64b38c..838575e3fac6 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | /** | 15 | /** |
16 | * pci_enable_rom - enable ROM decoding for a PCI device | 16 | * pci_enable_rom - enable ROM decoding for a PCI device |
17 | * @dev: PCI device to enable | 17 | * @pdev: PCI device to enable |
18 | * | 18 | * |
19 | * Enable ROM decoding on @dev. This involves simply turning on the last | 19 | * Enable ROM decoding on @dev. This involves simply turning on the last |
20 | * bit of the PCI ROM BAR. Note that some cards may share address decoders | 20 | * bit of the PCI ROM BAR. Note that some cards may share address decoders |
@@ -32,7 +32,7 @@ static void pci_enable_rom(struct pci_dev *pdev) | |||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * pci_disable_rom - disable ROM decoding for a PCI device | 34 | * pci_disable_rom - disable ROM decoding for a PCI device |
35 | * @dev: PCI device to disable | 35 | * @pdev: PCI device to disable |
36 | * | 36 | * |
37 | * Disable ROM decoding on a PCI device by turning off the last bit in the | 37 | * Disable ROM decoding on a PCI device by turning off the last bit in the |
38 | * ROM BAR. | 38 | * ROM BAR. |
@@ -47,7 +47,7 @@ static void pci_disable_rom(struct pci_dev *pdev) | |||
47 | 47 | ||
48 | /** | 48 | /** |
49 | * pci_map_rom - map a PCI ROM to kernel space | 49 | * pci_map_rom - map a PCI ROM to kernel space |
50 | * @dev: pointer to pci device struct | 50 | * @pdev: pointer to pci device struct |
51 | * @size: pointer to receive size of pci window over ROM | 51 | * @size: pointer to receive size of pci window over ROM |
52 | * @return: kernel virtual pointer to image of ROM | 52 | * @return: kernel virtual pointer to image of ROM |
53 | * | 53 | * |
@@ -132,7 +132,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
132 | 132 | ||
133 | /** | 133 | /** |
134 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy | 134 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy |
135 | * @dev: pointer to pci device struct | 135 | * @pdev: pointer to pci device struct |
136 | * @size: pointer to receive size of pci window over ROM | 136 | * @size: pointer to receive size of pci window over ROM |
137 | * @return: kernel virtual pointer to image of ROM | 137 | * @return: kernel virtual pointer to image of ROM |
138 | * | 138 | * |
@@ -166,7 +166,7 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) | |||
166 | 166 | ||
167 | /** | 167 | /** |
168 | * pci_unmap_rom - unmap the ROM from kernel space | 168 | * pci_unmap_rom - unmap the ROM from kernel space |
169 | * @dev: pointer to pci device struct | 169 | * @pdev: pointer to pci device struct |
170 | * @rom: virtual address of the previous mapping | 170 | * @rom: virtual address of the previous mapping |
171 | * | 171 | * |
172 | * Remove a mapping of a previously mapped ROM | 172 | * Remove a mapping of a previously mapped ROM |
@@ -187,7 +187,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) | |||
187 | 187 | ||
188 | /** | 188 | /** |
189 | * pci_remove_rom - disable the ROM and remove its sysfs attribute | 189 | * pci_remove_rom - disable the ROM and remove its sysfs attribute |
190 | * @dev: pointer to pci device struct | 190 | * @pdev: pointer to pci device struct |
191 | * | 191 | * |
192 | * Remove the rom file in sysfs and disable ROM decoding. | 192 | * Remove the rom file in sysfs and disable ROM decoding. |
193 | */ | 193 | */ |
@@ -206,7 +206,7 @@ void pci_remove_rom(struct pci_dev *pdev) | |||
206 | /** | 206 | /** |
207 | * pci_cleanup_rom - internal routine for freeing the ROM copy created | 207 | * pci_cleanup_rom - internal routine for freeing the ROM copy created |
208 | * by pci_map_rom_copy called from remove.c | 208 | * by pci_map_rom_copy called from remove.c |
209 | * @dev: pointer to pci device struct | 209 | * @pdev: pointer to pci device struct |
210 | * | 210 | * |
211 | * Free the copied ROM if we allocated one. | 211 | * Free the copied ROM if we allocated one. |
212 | */ | 212 | */ |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 639e04253482..65ecef738537 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -253,7 +253,7 @@ void pnp_init_resource_table(struct pnp_resource_table *table) | |||
253 | 253 | ||
254 | /** | 254 | /** |
255 | * pnp_clean_resources - clears resources that were not manually set | 255 | * pnp_clean_resources - clears resources that were not manually set |
256 | * @res - the resources to clean | 256 | * @res: the resources to clean |
257 | * | 257 | * |
258 | */ | 258 | */ |
259 | static void pnp_clean_resource_table(struct pnp_resource_table * res) | 259 | static void pnp_clean_resource_table(struct pnp_resource_table * res) |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index c0ddb1eb8c4d..dd61e09029b1 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -94,8 +94,8 @@ static void | |||
94 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) | 94 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) |
95 | { | 95 | { |
96 | int i = 0; | 96 | int i = 0; |
97 | while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) && | 97 | while (i < PNP_MAX_DMA && |
98 | i < PNP_MAX_DMA) | 98 | !(res->dma_resource[i].flags & IORESOURCE_UNSET)) |
99 | i++; | 99 | i++; |
100 | if (i < PNP_MAX_DMA) { | 100 | if (i < PNP_MAX_DMA) { |
101 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag | 101 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag |
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 618ac15a9e90..79bce7b75740 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
@@ -72,7 +72,9 @@ static void | |||
72 | pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) | 72 | pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) |
73 | { | 73 | { |
74 | int i = 0; | 74 | int i = 0; |
75 | while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_DMA) i++; | 75 | while (i < PNP_MAX_DMA && |
76 | !(res->dma_resource[i].flags & IORESOURCE_UNSET)) | ||
77 | i++; | ||
76 | if (i < PNP_MAX_DMA) { | 78 | if (i < PNP_MAX_DMA) { |
77 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag | 79 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag |
78 | if (dma == -1) { | 80 | if (dma == -1) { |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index b755bac6ccbc..02cfe244e069 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 |
9 | * | 9 | * |
10 | * $Revision: 1.158 $ | 10 | * $Revision: 1.161 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -1131,13 +1131,17 @@ __dasd_process_blk_queue(struct dasd_device * device) | |||
1131 | request_queue_t *queue; | 1131 | request_queue_t *queue; |
1132 | struct request *req; | 1132 | struct request *req; |
1133 | struct dasd_ccw_req *cqr; | 1133 | struct dasd_ccw_req *cqr; |
1134 | int nr_queued; | 1134 | int nr_queued, feature_ro; |
1135 | 1135 | ||
1136 | queue = device->request_queue; | 1136 | queue = device->request_queue; |
1137 | /* No queue ? Then there is nothing to do. */ | 1137 | /* No queue ? Then there is nothing to do. */ |
1138 | if (queue == NULL) | 1138 | if (queue == NULL) |
1139 | return; | 1139 | return; |
1140 | 1140 | ||
1141 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
1142 | if (feature_ro < 0) /* no devmap */ | ||
1143 | return; | ||
1144 | |||
1141 | /* | 1145 | /* |
1142 | * We requeue request from the block device queue to the ccw | 1146 | * We requeue request from the block device queue to the ccw |
1143 | * queue only in two states. In state DASD_STATE_READY the | 1147 | * queue only in two states. In state DASD_STATE_READY the |
@@ -1157,8 +1161,8 @@ __dasd_process_blk_queue(struct dasd_device * device) | |||
1157 | elv_next_request(queue) && | 1161 | elv_next_request(queue) && |
1158 | nr_queued < DASD_CHANQ_MAX_SIZE) { | 1162 | nr_queued < DASD_CHANQ_MAX_SIZE) { |
1159 | req = elv_next_request(queue); | 1163 | req = elv_next_request(queue); |
1160 | if (test_bit(DASD_FLAG_RO, &device->flags) && | 1164 | |
1161 | rq_data_dir(req) == WRITE) { | 1165 | if (feature_ro && rq_data_dir(req) == WRITE) { |
1162 | DBF_DEV_EVENT(DBF_ERR, device, | 1166 | DBF_DEV_EVENT(DBF_ERR, device, |
1163 | "Rejecting write request %p", | 1167 | "Rejecting write request %p", |
1164 | req); | 1168 | req); |
@@ -1631,6 +1635,7 @@ dasd_setup_queue(struct dasd_device * device) | |||
1631 | blk_queue_max_hw_segments(device->request_queue, -1L); | 1635 | blk_queue_max_hw_segments(device->request_queue, -1L); |
1632 | blk_queue_max_segment_size(device->request_queue, -1L); | 1636 | blk_queue_max_segment_size(device->request_queue, -1L); |
1633 | blk_queue_segment_boundary(device->request_queue, -1L); | 1637 | blk_queue_segment_boundary(device->request_queue, -1L); |
1638 | blk_queue_ordered(device->request_queue, 1); | ||
1634 | } | 1639 | } |
1635 | 1640 | ||
1636 | /* | 1641 | /* |
@@ -1803,13 +1808,17 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1803 | 1808 | ||
1804 | { | 1809 | { |
1805 | struct dasd_device *device; | 1810 | struct dasd_device *device; |
1806 | int rc; | 1811 | int feature_diag, rc; |
1812 | |||
1813 | feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG); | ||
1814 | if (feature_diag < 0) | ||
1815 | return feature_diag; | ||
1807 | 1816 | ||
1808 | device = dasd_create_device(cdev); | 1817 | device = dasd_create_device(cdev); |
1809 | if (IS_ERR(device)) | 1818 | if (IS_ERR(device)) |
1810 | return PTR_ERR(device); | 1819 | return PTR_ERR(device); |
1811 | 1820 | ||
1812 | if (test_bit(DASD_FLAG_USE_DIAG, &device->flags)) { | 1821 | if (feature_diag) { |
1813 | if (!dasd_diag_discipline_pointer) { | 1822 | if (!dasd_diag_discipline_pointer) { |
1814 | printk (KERN_WARNING | 1823 | printk (KERN_WARNING |
1815 | "dasd_generic couldn't online device %s " | 1824 | "dasd_generic couldn't online device %s " |
diff --git a/drivers/s390/block/dasd_cmb.c b/drivers/s390/block/dasd_cmb.c index ed1ab474c0c6..4f365bff275c 100644 --- a/drivers/s390/block/dasd_cmb.c +++ b/drivers/s390/block/dasd_cmb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/s390/block/dasd_cmb.c ($Revision: 1.6 $) | 2 | * linux/drivers/s390/block/dasd_cmb.c ($Revision: 1.9 $) |
3 | * | 3 | * |
4 | * Linux on zSeries Channel Measurement Facility support | 4 | * Linux on zSeries Channel Measurement Facility support |
5 | * (dasd device driver interface) | 5 | * (dasd device driver interface) |
@@ -23,7 +23,6 @@ | |||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | */ | 24 | */ |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/ioctl32.h> | ||
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
28 | #include <asm/ccwdev.h> | 27 | #include <asm/ccwdev.h> |
29 | #include <asm/cmb.h> | 28 | #include <asm/cmb.h> |
@@ -84,27 +83,13 @@ dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args) | |||
84 | static inline int | 83 | static inline int |
85 | ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler) | 84 | ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler) |
86 | { | 85 | { |
87 | int ret; | 86 | return dasd_ioctl_no_register(THIS_MODULE, no, handler); |
88 | ret = dasd_ioctl_no_register(THIS_MODULE, no, handler); | ||
89 | #ifdef CONFIG_COMPAT | ||
90 | if (ret) | ||
91 | return ret; | ||
92 | |||
93 | ret = register_ioctl32_conversion(no, NULL); | ||
94 | if (ret) | ||
95 | dasd_ioctl_no_unregister(THIS_MODULE, no, handler); | ||
96 | #endif | ||
97 | return ret; | ||
98 | } | 87 | } |
99 | 88 | ||
100 | static inline void | 89 | static inline void |
101 | ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler) | 90 | ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler) |
102 | { | 91 | { |
103 | dasd_ioctl_no_unregister(THIS_MODULE, no, handler); | 92 | dasd_ioctl_no_unregister(THIS_MODULE, no, handler); |
104 | #ifdef CONFIG_COMPAT | ||
105 | unregister_ioctl32_conversion(no); | ||
106 | #endif | ||
107 | |||
108 | } | 93 | } |
109 | 94 | ||
110 | static void | 95 | static void |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index ad1841a96c87..1aedc48e5f85 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * functions may not be called from interrupt context. In particular | 11 | * functions may not be called from interrupt context. In particular |
12 | * dasd_get_device is a no-no from interrupt context. | 12 | * dasd_get_device is a no-no from interrupt context. |
13 | * | 13 | * |
14 | * $Revision: 1.37 $ | 14 | * $Revision: 1.40 $ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
@@ -513,14 +513,6 @@ dasd_create_device(struct ccw_device *cdev) | |||
513 | if (!devmap->device) { | 513 | if (!devmap->device) { |
514 | devmap->device = device; | 514 | devmap->device = device; |
515 | device->devindex = devmap->devindex; | 515 | device->devindex = devmap->devindex; |
516 | if (devmap->features & DASD_FEATURE_READONLY) | ||
517 | set_bit(DASD_FLAG_RO, &device->flags); | ||
518 | else | ||
519 | clear_bit(DASD_FLAG_RO, &device->flags); | ||
520 | if (devmap->features & DASD_FEATURE_USEDIAG) | ||
521 | set_bit(DASD_FLAG_USE_DIAG, &device->flags); | ||
522 | else | ||
523 | clear_bit(DASD_FLAG_USE_DIAG, &device->flags); | ||
524 | get_device(&cdev->dev); | 516 | get_device(&cdev->dev); |
525 | device->cdev = cdev; | 517 | device->cdev = cdev; |
526 | rc = 0; | 518 | rc = 0; |
@@ -651,14 +643,8 @@ dasd_ro_store(struct device *dev, const char *buf, size_t count) | |||
651 | devmap->features |= DASD_FEATURE_READONLY; | 643 | devmap->features |= DASD_FEATURE_READONLY; |
652 | else | 644 | else |
653 | devmap->features &= ~DASD_FEATURE_READONLY; | 645 | devmap->features &= ~DASD_FEATURE_READONLY; |
654 | if (devmap->device) { | 646 | if (devmap->device && devmap->device->gdp) |
655 | if (devmap->device->gdp) | 647 | set_disk_ro(devmap->device->gdp, ro_flag); |
656 | set_disk_ro(devmap->device->gdp, ro_flag); | ||
657 | if (ro_flag) | ||
658 | set_bit(DASD_FLAG_RO, &devmap->device->flags); | ||
659 | else | ||
660 | clear_bit(DASD_FLAG_RO, &devmap->device->flags); | ||
661 | } | ||
662 | spin_unlock(&dasd_devmap_lock); | 648 | spin_unlock(&dasd_devmap_lock); |
663 | return count; | 649 | return count; |
664 | } | 650 | } |
@@ -739,6 +725,45 @@ static struct attribute_group dasd_attr_group = { | |||
739 | .attrs = dasd_attrs, | 725 | .attrs = dasd_attrs, |
740 | }; | 726 | }; |
741 | 727 | ||
728 | /* | ||
729 | * Return value of the specified feature. | ||
730 | */ | ||
731 | int | ||
732 | dasd_get_feature(struct ccw_device *cdev, int feature) | ||
733 | { | ||
734 | struct dasd_devmap *devmap; | ||
735 | |||
736 | devmap = dasd_find_busid(cdev->dev.bus_id); | ||
737 | if (IS_ERR(devmap)) | ||
738 | return (int) PTR_ERR(devmap); | ||
739 | |||
740 | return ((devmap->features & feature) != 0); | ||
741 | } | ||
742 | |||
743 | /* | ||
744 | * Set / reset given feature. | ||
745 | * Flag indicates wether to set (!=0) or the reset (=0) the feature. | ||
746 | */ | ||
747 | int | ||
748 | dasd_set_feature(struct ccw_device *cdev, int feature, int flag) | ||
749 | { | ||
750 | struct dasd_devmap *devmap; | ||
751 | |||
752 | devmap = dasd_find_busid(cdev->dev.bus_id); | ||
753 | if (IS_ERR(devmap)) | ||
754 | return (int) PTR_ERR(devmap); | ||
755 | |||
756 | spin_lock(&dasd_devmap_lock); | ||
757 | if (flag) | ||
758 | devmap->features |= feature; | ||
759 | else | ||
760 | devmap->features &= ~feature; | ||
761 | |||
762 | spin_unlock(&dasd_devmap_lock); | ||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | |||
742 | int | 767 | int |
743 | dasd_add_sysfs_files(struct ccw_device *cdev) | 768 | dasd_add_sysfs_files(struct ccw_device *cdev) |
744 | { | 769 | { |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 838aedf78a56..811060e10c00 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
9 | * | 9 | * |
10 | * $Revision: 1.69 $ | 10 | * $Revision: 1.71 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -1101,7 +1101,8 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1101 | if (dasd_eckd_cdl_special(blk_per_trk, recid)){ | 1101 | if (dasd_eckd_cdl_special(blk_per_trk, recid)){ |
1102 | rcmd |= 0x8; | 1102 | rcmd |= 0x8; |
1103 | count = dasd_eckd_cdl_reclen(recid); | 1103 | count = dasd_eckd_cdl_reclen(recid); |
1104 | if (count < blksize) | 1104 | if (count < blksize && |
1105 | rq_data_dir(req) == READ) | ||
1105 | memset(dst + count, 0xe5, | 1106 | memset(dst + count, 0xe5, |
1106 | blksize - count); | 1107 | blksize - count); |
1107 | } | 1108 | } |
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 1d52db406b2e..96c49349701f 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * gendisk related functions for the dasd driver. | 10 | * gendisk related functions for the dasd driver. |
11 | * | 11 | * |
12 | * $Revision: 1.48 $ | 12 | * $Revision: 1.50 $ |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
@@ -31,12 +31,16 @@ int | |||
31 | dasd_gendisk_alloc(struct dasd_device *device) | 31 | dasd_gendisk_alloc(struct dasd_device *device) |
32 | { | 32 | { |
33 | struct gendisk *gdp; | 33 | struct gendisk *gdp; |
34 | int len; | 34 | int len, feature_ro; |
35 | 35 | ||
36 | /* Make sure the minor for this device exists. */ | 36 | /* Make sure the minor for this device exists. */ |
37 | if (device->devindex >= DASD_PER_MAJOR) | 37 | if (device->devindex >= DASD_PER_MAJOR) |
38 | return -EBUSY; | 38 | return -EBUSY; |
39 | 39 | ||
40 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
41 | if (feature_ro < 0) | ||
42 | return feature_ro; | ||
43 | |||
40 | gdp = alloc_disk(1 << DASD_PARTN_BITS); | 44 | gdp = alloc_disk(1 << DASD_PARTN_BITS); |
41 | if (!gdp) | 45 | if (!gdp) |
42 | return -ENOMEM; | 46 | return -ENOMEM; |
@@ -71,7 +75,7 @@ dasd_gendisk_alloc(struct dasd_device *device) | |||
71 | 75 | ||
72 | sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id); | 76 | sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id); |
73 | 77 | ||
74 | if (test_bit(DASD_FLAG_RO, &device->flags)) | 78 | if (feature_ro) |
75 | set_disk_ro(gdp, 1); | 79 | set_disk_ro(gdp, 1); |
76 | gdp->private_data = device; | 80 | gdp->private_data = device; |
77 | gdp->queue = device->request_queue; | 81 | gdp->queue = device->request_queue; |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 4586e0ecc526..a9f38b235981 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Bugreports.to..: <Linux390@de.ibm.com> | 6 | * Bugreports.to..: <Linux390@de.ibm.com> |
7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
8 | * | 8 | * |
9 | * $Revision: 1.63 $ | 9 | * $Revision: 1.64 $ |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef DASD_INT_H | 12 | #ifndef DASD_INT_H |
@@ -329,8 +329,6 @@ struct dasd_device { | |||
329 | #define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */ | 329 | #define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */ |
330 | 330 | ||
331 | /* per device flags */ | 331 | /* per device flags */ |
332 | #define DASD_FLAG_RO 0 /* device is read-only */ | ||
333 | #define DASD_FLAG_USE_DIAG 1 /* use diag disciplnie */ | ||
334 | #define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */ | 332 | #define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */ |
335 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ | 333 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ |
336 | 334 | ||
@@ -501,6 +499,9 @@ void dasd_devmap_exit(void); | |||
501 | struct dasd_device *dasd_create_device(struct ccw_device *); | 499 | struct dasd_device *dasd_create_device(struct ccw_device *); |
502 | void dasd_delete_device(struct dasd_device *); | 500 | void dasd_delete_device(struct dasd_device *); |
503 | 501 | ||
502 | int dasd_get_feature(struct ccw_device *, int); | ||
503 | int dasd_set_feature(struct ccw_device *, int, int); | ||
504 | |||
504 | int dasd_add_sysfs_files(struct ccw_device *); | 505 | int dasd_add_sysfs_files(struct ccw_device *); |
505 | void dasd_remove_sysfs_files(struct ccw_device *); | 506 | void dasd_remove_sysfs_files(struct ccw_device *); |
506 | 507 | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index f1892baa3b18..980c555aa538 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 |
9 | * | 9 | * |
10 | * $Revision: 1.45 $ | ||
11 | * | ||
10 | * i/o controls for the dasd driver. | 12 | * i/o controls for the dasd driver. |
11 | */ | 13 | */ |
12 | #include <linux/config.h> | 14 | #include <linux/config.h> |
@@ -294,6 +296,7 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args) | |||
294 | { | 296 | { |
295 | struct dasd_device *device; | 297 | struct dasd_device *device; |
296 | struct format_data_t fdata; | 298 | struct format_data_t fdata; |
299 | int feature_ro; | ||
297 | 300 | ||
298 | if (!capable(CAP_SYS_ADMIN)) | 301 | if (!capable(CAP_SYS_ADMIN)) |
299 | return -EACCES; | 302 | return -EACCES; |
@@ -304,7 +307,11 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args) | |||
304 | 307 | ||
305 | if (device == NULL) | 308 | if (device == NULL) |
306 | return -ENODEV; | 309 | return -ENODEV; |
307 | if (test_bit(DASD_FLAG_RO, &device->flags)) | 310 | |
311 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
312 | if (feature_ro < 0) | ||
313 | return feature_ro; | ||
314 | if (feature_ro) | ||
308 | return -EROFS; | 315 | return -EROFS; |
309 | if (copy_from_user(&fdata, (void __user *) args, | 316 | if (copy_from_user(&fdata, (void __user *) args, |
310 | sizeof (struct format_data_t))) | 317 | sizeof (struct format_data_t))) |
@@ -377,7 +384,7 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
377 | struct dasd_device *device; | 384 | struct dasd_device *device; |
378 | struct dasd_information2_t *dasd_info; | 385 | struct dasd_information2_t *dasd_info; |
379 | unsigned long flags; | 386 | unsigned long flags; |
380 | int rc; | 387 | int rc, feature_ro; |
381 | struct ccw_device *cdev; | 388 | struct ccw_device *cdev; |
382 | 389 | ||
383 | device = bdev->bd_disk->private_data; | 390 | device = bdev->bd_disk->private_data; |
@@ -387,6 +394,10 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
387 | if (!device->discipline->fill_info) | 394 | if (!device->discipline->fill_info) |
388 | return -EINVAL; | 395 | return -EINVAL; |
389 | 396 | ||
397 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
398 | if (feature_ro < 0) | ||
399 | return feature_ro; | ||
400 | |||
390 | dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); | 401 | dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); |
391 | if (dasd_info == NULL) | 402 | if (dasd_info == NULL) |
392 | return -ENOMEM; | 403 | return -ENOMEM; |
@@ -415,9 +426,8 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
415 | if ((device->state < DASD_STATE_READY) || | 426 | if ((device->state < DASD_STATE_READY) || |
416 | (dasd_check_blocksize(device->bp_block))) | 427 | (dasd_check_blocksize(device->bp_block))) |
417 | dasd_info->format = DASD_FORMAT_NONE; | 428 | dasd_info->format = DASD_FORMAT_NONE; |
418 | 429 | ||
419 | dasd_info->features |= test_bit(DASD_FLAG_RO, &device->flags) ? | 430 | dasd_info->features |= feature_ro; |
420 | DASD_FEATURE_READONLY : DASD_FEATURE_DEFAULT; | ||
421 | 431 | ||
422 | if (device->discipline) | 432 | if (device->discipline) |
423 | memcpy(dasd_info->type, device->discipline->name, 4); | 433 | memcpy(dasd_info->type, device->discipline->name, 4); |
@@ -460,7 +470,7 @@ static int | |||
460 | dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) | 470 | dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) |
461 | { | 471 | { |
462 | struct dasd_device *device; | 472 | struct dasd_device *device; |
463 | int intval; | 473 | int intval, rc; |
464 | 474 | ||
465 | if (!capable(CAP_SYS_ADMIN)) | 475 | if (!capable(CAP_SYS_ADMIN)) |
466 | return -EACCES; | 476 | return -EACCES; |
@@ -472,12 +482,11 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) | |||
472 | device = bdev->bd_disk->private_data; | 482 | device = bdev->bd_disk->private_data; |
473 | if (device == NULL) | 483 | if (device == NULL) |
474 | return -ENODEV; | 484 | return -ENODEV; |
485 | |||
475 | set_disk_ro(bdev->bd_disk, intval); | 486 | set_disk_ro(bdev->bd_disk, intval); |
476 | if (intval) | 487 | rc = dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval); |
477 | set_bit(DASD_FLAG_RO, &device->flags); | 488 | |
478 | else | 489 | return rc; |
479 | clear_bit(DASD_FLAG_RO, &device->flags); | ||
480 | return 0; | ||
481 | } | 490 | } |
482 | 491 | ||
483 | /* | 492 | /* |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 353d41118c62..d7f19745911f 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * /proc interface for the dasd driver. | 10 | * /proc interface for the dasd driver. |
11 | * | 11 | * |
12 | * $Revision: 1.30 $ | 12 | * $Revision: 1.31 $ |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
@@ -54,6 +54,7 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
54 | { | 54 | { |
55 | struct dasd_device *device; | 55 | struct dasd_device *device; |
56 | char *substr; | 56 | char *substr; |
57 | int feature; | ||
57 | 58 | ||
58 | device = dasd_device_from_devindex((unsigned long) v - 1); | 59 | device = dasd_device_from_devindex((unsigned long) v - 1); |
59 | if (IS_ERR(device)) | 60 | if (IS_ERR(device)) |
@@ -77,7 +78,10 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
77 | else | 78 | else |
78 | seq_printf(m, " is ????????"); | 79 | seq_printf(m, " is ????????"); |
79 | /* Print devices features. */ | 80 | /* Print devices features. */ |
80 | substr = test_bit(DASD_FLAG_RO, &device->flags) ? "(ro)" : " "; | 81 | feature = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); |
82 | if (feature < 0) | ||
83 | return 0; | ||
84 | substr = feature ? "(ro)" : " "; | ||
81 | seq_printf(m, "%4s: ", substr); | 85 | seq_printf(m, "%4s: ", substr); |
82 | /* Print device status information. */ | 86 | /* Print device status information. */ |
83 | switch ((device != NULL) ? device->state : -1) { | 87 | switch ((device != NULL) ? device->state : -1) { |
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index 3720e77b465f..83e6a060668e 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c | |||
@@ -45,7 +45,7 @@ s390_register_adapter_interrupt (adapter_int_handler_t handler) | |||
45 | else | 45 | else |
46 | ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0); | 46 | ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0); |
47 | if (!ret) | 47 | if (!ret) |
48 | synchronize_kernel(); | 48 | synchronize_sched(); /* Allow interrupts to complete. */ |
49 | 49 | ||
50 | sprintf (dbf_txt, "ret:%d", ret); | 50 | sprintf (dbf_txt, "ret:%d", ret); |
51 | CIO_TRACE_EVENT (4, dbf_txt); | 51 | CIO_TRACE_EVENT (4, dbf_txt); |
@@ -65,7 +65,7 @@ s390_unregister_adapter_interrupt (adapter_int_handler_t handler) | |||
65 | ret = -EINVAL; | 65 | ret = -EINVAL; |
66 | else { | 66 | else { |
67 | adapter_handler = NULL; | 67 | adapter_handler = NULL; |
68 | synchronize_kernel(); | 68 | synchronize_sched(); /* Allow interrupts to complete. */ |
69 | ret = 0; | 69 | ret = 0; |
70 | } | 70 | } |
71 | sprintf (dbf_txt, "ret:%d", ret); | 71 | sprintf (dbf_txt, "ret:%d", ret); |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 99ce5a567982..1d9b3f18d8de 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/cio.c | 2 | * drivers/s390/cio/cio.c |
3 | * S/390 common I/O routines -- low level i/o calls | 3 | * S/390 common I/O routines -- low level i/o calls |
4 | * $Revision: 1.131 $ | 4 | * $Revision: 1.133 $ |
5 | * | 5 | * |
6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, | 6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, |
7 | * IBM Corporation | 7 | * IBM Corporation |
@@ -228,7 +228,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ | |||
228 | int | 228 | int |
229 | cio_start (struct subchannel *sch, struct ccw1 *cpa, __u8 lpm) | 229 | cio_start (struct subchannel *sch, struct ccw1 *cpa, __u8 lpm) |
230 | { | 230 | { |
231 | return cio_start_key(sch, cpa, lpm, default_storage_key); | 231 | return cio_start_key(sch, cpa, lpm, PAGE_DEFAULT_KEY); |
232 | } | 232 | } |
233 | 233 | ||
234 | /* | 234 | /* |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 11e260e0b9c9..02d01a0de16c 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/device_ops.c | 2 | * drivers/s390/cio/device_ops.c |
3 | * | 3 | * |
4 | * $Revision: 1.55 $ | 4 | * $Revision: 1.56 $ |
5 | * | 5 | * |
6 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, | 6 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, |
7 | * IBM Corporation | 7 | * IBM Corporation |
@@ -128,7 +128,7 @@ ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa, | |||
128 | unsigned long intparm, __u8 lpm, unsigned long flags) | 128 | unsigned long intparm, __u8 lpm, unsigned long flags) |
129 | { | 129 | { |
130 | return ccw_device_start_key(cdev, cpa, intparm, lpm, | 130 | return ccw_device_start_key(cdev, cpa, intparm, lpm, |
131 | default_storage_key, flags); | 131 | PAGE_DEFAULT_KEY, flags); |
132 | } | 132 | } |
133 | 133 | ||
134 | int | 134 | int |
@@ -137,7 +137,7 @@ ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa, | |||
137 | int expires) | 137 | int expires) |
138 | { | 138 | { |
139 | return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, | 139 | return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, |
140 | default_storage_key, flags, | 140 | PAGE_DEFAULT_KEY, flags, |
141 | expires); | 141 | expires); |
142 | } | 142 | } |
143 | 143 | ||
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 9ad14db24143..b6daadac4e8b 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -1,7 +1,9 @@ | |||
1 | #ifndef _CIO_QDIO_H | 1 | #ifndef _CIO_QDIO_H |
2 | #define _CIO_QDIO_H | 2 | #define _CIO_QDIO_H |
3 | 3 | ||
4 | #define VERSION_CIO_QDIO_H "$Revision: 1.26 $" | 4 | #include <asm/page.h> |
5 | |||
6 | #define VERSION_CIO_QDIO_H "$Revision: 1.32 $" | ||
5 | 7 | ||
6 | #ifdef CONFIG_QDIO_DEBUG | 8 | #ifdef CONFIG_QDIO_DEBUG |
7 | #define QDIO_VERBOSE_LEVEL 9 | 9 | #define QDIO_VERBOSE_LEVEL 9 |
@@ -42,7 +44,7 @@ | |||
42 | 44 | ||
43 | #define QDIO_Q_LAPS 5 | 45 | #define QDIO_Q_LAPS 5 |
44 | 46 | ||
45 | #define QDIO_STORAGE_KEY 0 | 47 | #define QDIO_STORAGE_KEY PAGE_DEFAULT_KEY |
46 | 48 | ||
47 | #define L2_CACHELINE_SIZE 256 | 49 | #define L2_CACHELINE_SIZE 256 |
48 | #define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32)) | 50 | #define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32)) |
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index a98c00c02559..9ec29bb41b28 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c | |||
@@ -385,8 +385,8 @@ static int z90crypt_release(struct inode *, struct file *); | |||
385 | static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); | 385 | static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); |
386 | static ssize_t z90crypt_write(struct file *, const char __user *, | 386 | static ssize_t z90crypt_write(struct file *, const char __user *, |
387 | size_t, loff_t *); | 387 | size_t, loff_t *); |
388 | static int z90crypt_ioctl(struct inode *, struct file *, | 388 | static long z90crypt_unlocked_ioctl(struct file *, unsigned int, unsigned long); |
389 | unsigned int, unsigned long); | 389 | static long z90crypt_compat_ioctl(struct file *, unsigned int, unsigned long); |
390 | 390 | ||
391 | static void z90crypt_reader_task(unsigned long); | 391 | static void z90crypt_reader_task(unsigned long); |
392 | static void z90crypt_schedule_reader_task(unsigned long); | 392 | static void z90crypt_schedule_reader_task(unsigned long); |
@@ -433,12 +433,15 @@ static atomic_t total_open; | |||
433 | static atomic_t z90crypt_step; | 433 | static atomic_t z90crypt_step; |
434 | 434 | ||
435 | static struct file_operations z90crypt_fops = { | 435 | static struct file_operations z90crypt_fops = { |
436 | .owner = THIS_MODULE, | 436 | .owner = THIS_MODULE, |
437 | .read = z90crypt_read, | 437 | .read = z90crypt_read, |
438 | .write = z90crypt_write, | 438 | .write = z90crypt_write, |
439 | .ioctl = z90crypt_ioctl, | 439 | .unlocked_ioctl = z90crypt_unlocked_ioctl, |
440 | .open = z90crypt_open, | 440 | #ifdef CONFIG_COMPAT |
441 | .release = z90crypt_release | 441 | .compat_ioctl = z90crypt_compat_ioctl, |
442 | #endif | ||
443 | .open = z90crypt_open, | ||
444 | .release = z90crypt_release | ||
442 | }; | 445 | }; |
443 | 446 | ||
444 | #ifndef Z90CRYPT_USE_HOTPLUG | 447 | #ifndef Z90CRYPT_USE_HOTPLUG |
@@ -474,14 +477,13 @@ struct ica_rsa_modexpo_32 { // For 32-bit callers | |||
474 | compat_uptr_t n_modulus; | 477 | compat_uptr_t n_modulus; |
475 | }; | 478 | }; |
476 | 479 | ||
477 | static int | 480 | static long |
478 | trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, | 481 | trans_modexpo32(struct file *filp, unsigned int cmd, unsigned long arg) |
479 | struct file *file) | ||
480 | { | 482 | { |
481 | struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg); | 483 | struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg); |
482 | struct ica_rsa_modexpo_32 mex32k; | 484 | struct ica_rsa_modexpo_32 mex32k; |
483 | struct ica_rsa_modexpo __user *mex64; | 485 | struct ica_rsa_modexpo __user *mex64; |
484 | int ret = 0; | 486 | long ret = 0; |
485 | unsigned int i; | 487 | unsigned int i; |
486 | 488 | ||
487 | if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32))) | 489 | if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32))) |
@@ -498,7 +500,7 @@ trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
498 | __put_user(compat_ptr(mex32k.b_key), &mex64->b_key) || | 500 | __put_user(compat_ptr(mex32k.b_key), &mex64->b_key) || |
499 | __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus)) | 501 | __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus)) |
500 | return -EFAULT; | 502 | return -EFAULT; |
501 | ret = sys_ioctl(fd, cmd, (unsigned long)mex64); | 503 | ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)mex64); |
502 | if (!ret) | 504 | if (!ret) |
503 | if (__get_user(i, &mex64->outputdatalength) || | 505 | if (__get_user(i, &mex64->outputdatalength) || |
504 | __put_user(i, &mex32u->outputdatalength)) | 506 | __put_user(i, &mex32u->outputdatalength)) |
@@ -518,14 +520,13 @@ struct ica_rsa_modexpo_crt_32 { // For 32-bit callers | |||
518 | compat_uptr_t u_mult_inv; | 520 | compat_uptr_t u_mult_inv; |
519 | }; | 521 | }; |
520 | 522 | ||
521 | static int | 523 | static long |
522 | trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | 524 | trans_modexpo_crt32(struct file *filp, unsigned int cmd, unsigned long arg) |
523 | struct file *file) | ||
524 | { | 525 | { |
525 | struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); | 526 | struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); |
526 | struct ica_rsa_modexpo_crt_32 crt32k; | 527 | struct ica_rsa_modexpo_crt_32 crt32k; |
527 | struct ica_rsa_modexpo_crt __user *crt64; | 528 | struct ica_rsa_modexpo_crt __user *crt64; |
528 | int ret = 0; | 529 | long ret = 0; |
529 | unsigned int i; | 530 | unsigned int i; |
530 | 531 | ||
531 | if (!access_ok(VERIFY_WRITE, crt32u, | 532 | if (!access_ok(VERIFY_WRITE, crt32u, |
@@ -546,9 +547,8 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
546 | __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) || | 547 | __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) || |
547 | __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) || | 548 | __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) || |
548 | __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv)) | 549 | __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv)) |
549 | ret = -EFAULT; | 550 | return -EFAULT; |
550 | if (!ret) | 551 | ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)crt64); |
551 | ret = sys_ioctl(fd, cmd, (unsigned long)crt64); | ||
552 | if (!ret) | 552 | if (!ret) |
553 | if (__get_user(i, &crt64->outputdatalength) || | 553 | if (__get_user(i, &crt64->outputdatalength) || |
554 | __put_user(i, &crt32u->outputdatalength)) | 554 | __put_user(i, &crt32u->outputdatalength)) |
@@ -556,66 +556,34 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
556 | return ret; | 556 | return ret; |
557 | } | 557 | } |
558 | 558 | ||
559 | static int compatible_ioctls[] = { | 559 | static long |
560 | ICAZ90STATUS, Z90QUIESCE, Z90STAT_TOTALCOUNT, Z90STAT_PCICACOUNT, | 560 | z90crypt_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
561 | Z90STAT_PCICCCOUNT, Z90STAT_PCIXCCCOUNT, Z90STAT_PCIXCCMCL2COUNT, | ||
562 | Z90STAT_PCIXCCMCL3COUNT, Z90STAT_CEX2CCOUNT, Z90STAT_REQUESTQ_COUNT, | ||
563 | Z90STAT_PENDINGQ_COUNT, Z90STAT_TOTALOPEN_COUNT, Z90STAT_DOMAIN_INDEX, | ||
564 | Z90STAT_STATUS_MASK, Z90STAT_QDEPTH_MASK, Z90STAT_PERDEV_REQCNT, | ||
565 | }; | ||
566 | |||
567 | static void z90_unregister_ioctl32s(void) | ||
568 | { | ||
569 | int i; | ||
570 | |||
571 | unregister_ioctl32_conversion(ICARSAMODEXPO); | ||
572 | unregister_ioctl32_conversion(ICARSACRT); | ||
573 | |||
574 | for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) | ||
575 | unregister_ioctl32_conversion(compatible_ioctls[i]); | ||
576 | } | ||
577 | |||
578 | static int z90_register_ioctl32s(void) | ||
579 | { | ||
580 | int result, i; | ||
581 | |||
582 | result = register_ioctl32_conversion(ICARSAMODEXPO, trans_modexpo32); | ||
583 | if (result == -EBUSY) { | ||
584 | unregister_ioctl32_conversion(ICARSAMODEXPO); | ||
585 | result = register_ioctl32_conversion(ICARSAMODEXPO, | ||
586 | trans_modexpo32); | ||
587 | } | ||
588 | if (result) | ||
589 | return result; | ||
590 | result = register_ioctl32_conversion(ICARSACRT, trans_modexpo_crt32); | ||
591 | if (result == -EBUSY) { | ||
592 | unregister_ioctl32_conversion(ICARSACRT); | ||
593 | result = register_ioctl32_conversion(ICARSACRT, | ||
594 | trans_modexpo_crt32); | ||
595 | } | ||
596 | if (result) | ||
597 | return result; | ||
598 | |||
599 | for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) { | ||
600 | result = register_ioctl32_conversion(compatible_ioctls[i], 0); | ||
601 | if (result == -EBUSY) { | ||
602 | unregister_ioctl32_conversion(compatible_ioctls[i]); | ||
603 | result = register_ioctl32_conversion( | ||
604 | compatible_ioctls[i], 0); | ||
605 | } | ||
606 | if (result) | ||
607 | return result; | ||
608 | } | ||
609 | return 0; | ||
610 | } | ||
611 | #else // !CONFIG_COMPAT | ||
612 | static inline void z90_unregister_ioctl32s(void) | ||
613 | { | ||
614 | } | ||
615 | |||
616 | static inline int z90_register_ioctl32s(void) | ||
617 | { | 561 | { |
618 | return 0; | 562 | switch (cmd) { |
563 | case ICAZ90STATUS: | ||
564 | case Z90QUIESCE: | ||
565 | case Z90STAT_TOTALCOUNT: | ||
566 | case Z90STAT_PCICACOUNT: | ||
567 | case Z90STAT_PCICCCOUNT: | ||
568 | case Z90STAT_PCIXCCCOUNT: | ||
569 | case Z90STAT_PCIXCCMCL2COUNT: | ||
570 | case Z90STAT_PCIXCCMCL3COUNT: | ||
571 | case Z90STAT_CEX2CCOUNT: | ||
572 | case Z90STAT_REQUESTQ_COUNT: | ||
573 | case Z90STAT_PENDINGQ_COUNT: | ||
574 | case Z90STAT_TOTALOPEN_COUNT: | ||
575 | case Z90STAT_DOMAIN_INDEX: | ||
576 | case Z90STAT_STATUS_MASK: | ||
577 | case Z90STAT_QDEPTH_MASK: | ||
578 | case Z90STAT_PERDEV_REQCNT: | ||
579 | return z90crypt_unlocked_ioctl(filp, cmd, arg); | ||
580 | case ICARSAMODEXPO: | ||
581 | return trans_modexpo32(filp, cmd, arg); | ||
582 | case ICARSACRT: | ||
583 | return trans_modexpo_crt32(filp, cmd, arg); | ||
584 | default: | ||
585 | return -ENOIOCTLCMD; | ||
586 | } | ||
619 | } | 587 | } |
620 | #endif | 588 | #endif |
621 | 589 | ||
@@ -730,14 +698,9 @@ z90crypt_init_module(void) | |||
730 | reader_timer.expires = jiffies + (READERTIME * HZ / 1000); | 698 | reader_timer.expires = jiffies + (READERTIME * HZ / 1000); |
731 | add_timer(&reader_timer); | 699 | add_timer(&reader_timer); |
732 | 700 | ||
733 | if ((result = z90_register_ioctl32s())) | ||
734 | goto init_module_cleanup; | ||
735 | |||
736 | return 0; // success | 701 | return 0; // success |
737 | 702 | ||
738 | init_module_cleanup: | 703 | init_module_cleanup: |
739 | z90_unregister_ioctl32s(); | ||
740 | |||
741 | #ifndef Z90CRYPT_USE_HOTPLUG | 704 | #ifndef Z90CRYPT_USE_HOTPLUG |
742 | if ((nresult = misc_deregister(&z90crypt_misc_device))) | 705 | if ((nresult = misc_deregister(&z90crypt_misc_device))) |
743 | PRINTK("misc_deregister failed with %d.\n", nresult); | 706 | PRINTK("misc_deregister failed with %d.\n", nresult); |
@@ -763,8 +726,6 @@ z90crypt_cleanup_module(void) | |||
763 | 726 | ||
764 | PDEBUG("PID %d\n", PID()); | 727 | PDEBUG("PID %d\n", PID()); |
765 | 728 | ||
766 | z90_unregister_ioctl32s(); | ||
767 | |||
768 | remove_proc_entry("driver/z90crypt", 0); | 729 | remove_proc_entry("driver/z90crypt", 0); |
769 | 730 | ||
770 | #ifndef Z90CRYPT_USE_HOTPLUG | 731 | #ifndef Z90CRYPT_USE_HOTPLUG |
@@ -800,7 +761,7 @@ z90crypt_cleanup_module(void) | |||
800 | * z90crypt_release | 761 | * z90crypt_release |
801 | * z90crypt_read | 762 | * z90crypt_read |
802 | * z90crypt_write | 763 | * z90crypt_write |
803 | * z90crypt_ioctl | 764 | * z90crypt_unlocked_ioctl |
804 | * z90crypt_status | 765 | * z90crypt_status |
805 | * z90crypt_status_write | 766 | * z90crypt_status_write |
806 | * disable_card | 767 | * disable_card |
@@ -1804,9 +1765,8 @@ z90crypt_rsa(struct priv_data *private_data_p, pid_t pid, | |||
1804 | * This function is a little long, but it's really just one large switch | 1765 | * This function is a little long, but it's really just one large switch |
1805 | * statement. | 1766 | * statement. |
1806 | */ | 1767 | */ |
1807 | static int | 1768 | static long |
1808 | z90crypt_ioctl(struct inode *inode, struct file *filp, | 1769 | z90crypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1809 | unsigned int cmd, unsigned long arg) | ||
1810 | { | 1770 | { |
1811 | struct priv_data *private_data_p = filp->private_data; | 1771 | struct priv_data *private_data_p = filp->private_data; |
1812 | unsigned char *status; | 1772 | unsigned char *status; |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index a3d285859564..1e3f7f3c662f 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -32,7 +32,7 @@ struct smsg_callback { | |||
32 | struct list_head list; | 32 | struct list_head list; |
33 | char *prefix; | 33 | char *prefix; |
34 | int len; | 34 | int len; |
35 | void (*callback)(char *str); | 35 | void (*callback)(char *from, char *str); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | MODULE_AUTHOR | 38 | MODULE_AUTHOR |
@@ -55,8 +55,9 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) | |||
55 | { | 55 | { |
56 | struct smsg_callback *cb; | 56 | struct smsg_callback *cb; |
57 | unsigned char *msg; | 57 | unsigned char *msg; |
58 | unsigned char sender[9]; | ||
58 | unsigned short len; | 59 | unsigned short len; |
59 | int rc; | 60 | int rc, i; |
60 | 61 | ||
61 | len = eib->ln1msg2.ipbfln1f; | 62 | len = eib->ln1msg2.ipbfln1f; |
62 | msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); | 63 | msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); |
@@ -69,10 +70,18 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) | |||
69 | if (rc == 0) { | 70 | if (rc == 0) { |
70 | msg[len] = 0; | 71 | msg[len] = 0; |
71 | EBCASC(msg, len); | 72 | EBCASC(msg, len); |
73 | memcpy(sender, msg, 8); | ||
74 | sender[8] = 0; | ||
75 | /* Remove trailing whitespace from the sender name. */ | ||
76 | for (i = 7; i >= 0; i--) { | ||
77 | if (sender[i] != ' ' && sender[i] != '\t') | ||
78 | break; | ||
79 | sender[i] = 0; | ||
80 | } | ||
72 | spin_lock(&smsg_list_lock); | 81 | spin_lock(&smsg_list_lock); |
73 | list_for_each_entry(cb, &smsg_list, list) | 82 | list_for_each_entry(cb, &smsg_list, list) |
74 | if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { | 83 | if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { |
75 | cb->callback(msg + 8); | 84 | cb->callback(sender, msg + 8); |
76 | break; | 85 | break; |
77 | } | 86 | } |
78 | spin_unlock(&smsg_list_lock); | 87 | spin_unlock(&smsg_list_lock); |
@@ -91,7 +100,7 @@ static struct device_driver smsg_driver = { | |||
91 | }; | 100 | }; |
92 | 101 | ||
93 | int | 102 | int |
94 | smsg_register_callback(char *prefix, void (*callback)(char *str)) | 103 | smsg_register_callback(char *prefix, void (*callback)(char *from, char *str)) |
95 | { | 104 | { |
96 | struct smsg_callback *cb; | 105 | struct smsg_callback *cb; |
97 | 106 | ||
@@ -108,7 +117,7 @@ smsg_register_callback(char *prefix, void (*callback)(char *str)) | |||
108 | } | 117 | } |
109 | 118 | ||
110 | void | 119 | void |
111 | smsg_unregister_callback(char *prefix, void (*callback)(char *str)) | 120 | smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str)) |
112 | { | 121 | { |
113 | struct smsg_callback *cb, *tmp; | 122 | struct smsg_callback *cb, *tmp; |
114 | 123 | ||
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h index 04cd87152964..67f5d4f8378d 100644 --- a/drivers/s390/net/smsgiucv.h +++ b/drivers/s390/net/smsgiucv.h | |||
@@ -5,6 +5,6 @@ | |||
5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | 5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) |
6 | */ | 6 | */ |
7 | 7 | ||
8 | int smsg_register_callback(char *, void (*)(char *)); | 8 | int smsg_register_callback(char *, void (*)(char *, char *)); |
9 | void smsg_unregister_callback(char *, void (*)(char *)); | 9 | void smsg_unregister_callback(char *, void (*)(char *, char *)); |
10 | 10 | ||
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index e70dedb0d0a5..7976947c0322 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c | |||
@@ -137,7 +137,7 @@ static unsigned short pas16_addr = 0; | |||
137 | static int pas16_irq = 0; | 137 | static int pas16_irq = 0; |
138 | 138 | ||
139 | 139 | ||
140 | int scsi_irq_translate[] = | 140 | static const int scsi_irq_translate[] = |
141 | { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 }; | 141 | { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 }; |
142 | 142 | ||
143 | /* The default_irqs array contains values used to set the irq into the | 143 | /* The default_irqs array contains values used to set the irq into the |
@@ -145,7 +145,7 @@ int scsi_irq_translate[] = | |||
145 | * irq jumpers on the board). The first value in the array will be | 145 | * irq jumpers on the board). The first value in the array will be |
146 | * assigned to logical board 0, the next to board 1, etc. | 146 | * assigned to logical board 0, the next to board 1, etc. |
147 | */ | 147 | */ |
148 | int default_irqs[] __initdata = | 148 | static int default_irqs[] __initdata = |
149 | { PAS16_DEFAULT_BOARD_1_IRQ, | 149 | { PAS16_DEFAULT_BOARD_1_IRQ, |
150 | PAS16_DEFAULT_BOARD_2_IRQ, | 150 | PAS16_DEFAULT_BOARD_2_IRQ, |
151 | PAS16_DEFAULT_BOARD_3_IRQ, | 151 | PAS16_DEFAULT_BOARD_3_IRQ, |
@@ -177,7 +177,7 @@ static struct base { | |||
177 | 177 | ||
178 | #define NO_BASES (sizeof (bases) / sizeof (struct base)) | 178 | #define NO_BASES (sizeof (bases) / sizeof (struct base)) |
179 | 179 | ||
180 | unsigned short pas16_offset[ 8 ] = | 180 | static const unsigned short pas16_offset[ 8 ] = |
181 | { | 181 | { |
182 | 0x1c00, /* OUTPUT_DATA_REG */ | 182 | 0x1c00, /* OUTPUT_DATA_REG */ |
183 | 0x1c01, /* INITIATOR_COMMAND_REG */ | 183 | 0x1c01, /* INITIATOR_COMMAND_REG */ |
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index a00095cc74c6..97f4d9112b48 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c | |||
@@ -945,7 +945,7 @@ static int ultrastor_abort(Scsi_Cmnd *SCpnt) | |||
945 | config.mscp[mscp_index].SCint, SCpnt); | 945 | config.mscp[mscp_index].SCint, SCpnt); |
946 | #endif | 946 | #endif |
947 | if (config.mscp[mscp_index].SCint == 0) | 947 | if (config.mscp[mscp_index].SCint == 0) |
948 | return FAILURE; | 948 | return FAILED; |
949 | 949 | ||
950 | if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort"); | 950 | if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort"); |
951 | config.mscp[mscp_index].SCint = NULL; | 951 | config.mscp[mscp_index].SCint = NULL; |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 218b69372c0b..0d9358608fdf 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -51,7 +51,7 @@ | |||
51 | * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option | 51 | * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option |
52 | * is unsafe when used on edge-triggered interrupts. | 52 | * is unsafe when used on edge-triggered interrupts. |
53 | */ | 53 | */ |
54 | unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | 54 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Debugging. | 57 | * Debugging. |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index c682c6308cde..01a8726a3f97 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -321,18 +321,39 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
321 | #define TXTL 2 /* reset default */ | 321 | #define TXTL 2 /* reset default */ |
322 | #define RXTL 1 /* reset default */ | 322 | #define RXTL 1 /* reset default */ |
323 | 323 | ||
324 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | ||
325 | { | ||
326 | unsigned int val; | ||
327 | unsigned int ufcr_rfdiv; | ||
328 | |||
329 | /* set receiver / transmitter trigger level. | ||
330 | * RFDIV is set such way to satisfy requested uartclk value | ||
331 | */ | ||
332 | val = TXTL<<10 | RXTL; | ||
333 | ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; | ||
334 | |||
335 | if(!ufcr_rfdiv) | ||
336 | ufcr_rfdiv = 1; | ||
337 | |||
338 | if(ufcr_rfdiv >= 7) | ||
339 | ufcr_rfdiv = 6; | ||
340 | else | ||
341 | ufcr_rfdiv = 6 - ufcr_rfdiv; | ||
342 | |||
343 | val |= UFCR_RFDIV & (ufcr_rfdiv << 7); | ||
344 | |||
345 | UFCR((u32)sport->port.membase) = val; | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
324 | static int imx_startup(struct uart_port *port) | 350 | static int imx_startup(struct uart_port *port) |
325 | { | 351 | { |
326 | struct imx_port *sport = (struct imx_port *)port; | 352 | struct imx_port *sport = (struct imx_port *)port; |
327 | int retval; | 353 | int retval; |
328 | unsigned int val; | ||
329 | unsigned long flags; | 354 | unsigned long flags; |
330 | 355 | ||
331 | /* set receiver / transmitter trigger level. We assume | 356 | imx_setup_ufcr(sport, 0); |
332 | * that RFDIV has been set by the arch setup or by the bootloader. | ||
333 | */ | ||
334 | val = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) | TXTL<<10 | RXTL; | ||
335 | UFCR((u32)sport->port.membase) = val; | ||
336 | 357 | ||
337 | /* disable the DREN bit (Data Ready interrupt enable) before | 358 | /* disable the DREN bit (Data Ready interrupt enable) before |
338 | * requesting IRQs | 359 | * requesting IRQs |
@@ -737,9 +758,12 @@ static void __init | |||
737 | imx_console_get_options(struct imx_port *sport, int *baud, | 758 | imx_console_get_options(struct imx_port *sport, int *baud, |
738 | int *parity, int *bits) | 759 | int *parity, int *bits) |
739 | { | 760 | { |
761 | |||
740 | if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { | 762 | if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { |
741 | /* ok, the port was enabled */ | 763 | /* ok, the port was enabled */ |
742 | unsigned int ucr2, ubir,ubmr, uartclk; | 764 | unsigned int ucr2, ubir,ubmr, uartclk; |
765 | unsigned int baud_raw; | ||
766 | unsigned int ucfr_rfdiv; | ||
743 | 767 | ||
744 | ucr2 = UCR2((u32)sport->port.membase); | 768 | ucr2 = UCR2((u32)sport->port.membase); |
745 | 769 | ||
@@ -758,9 +782,35 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
758 | 782 | ||
759 | ubir = UBIR((u32)sport->port.membase) & 0xffff; | 783 | ubir = UBIR((u32)sport->port.membase) & 0xffff; |
760 | ubmr = UBMR((u32)sport->port.membase) & 0xffff; | 784 | ubmr = UBMR((u32)sport->port.membase) & 0xffff; |
761 | uartclk = sport->port.uartclk; | ||
762 | 785 | ||
763 | *baud = ((uartclk/16) * (ubir + 1)) / (ubmr + 1); | 786 | |
787 | ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7; | ||
788 | if (ucfr_rfdiv == 6) | ||
789 | ucfr_rfdiv = 7; | ||
790 | else | ||
791 | ucfr_rfdiv = 6 - ucfr_rfdiv; | ||
792 | |||
793 | uartclk = imx_get_perclk1(); | ||
794 | uartclk /= ucfr_rfdiv; | ||
795 | |||
796 | { /* | ||
797 | * The next code provides exact computation of | ||
798 | * baud_raw = round(((uartclk/16) * (ubir + 1)) / (ubmr + 1)) | ||
799 | * without need of float support or long long division, | ||
800 | * which would be required to prevent 32bit arithmetic overflow | ||
801 | */ | ||
802 | unsigned int mul = ubir + 1; | ||
803 | unsigned int div = 16 * (ubmr + 1); | ||
804 | unsigned int rem = uartclk % div; | ||
805 | |||
806 | baud_raw = (uartclk / div) * mul; | ||
807 | baud_raw += (rem * mul + div / 2) / div; | ||
808 | *baud = (baud_raw + 50) / 100 * 100; | ||
809 | } | ||
810 | |||
811 | if(*baud != baud_raw) | ||
812 | printk(KERN_INFO "Serial: Console IMX rounded baud rate from %d to %d\n", | ||
813 | baud_raw, *baud); | ||
764 | } | 814 | } |
765 | } | 815 | } |
766 | 816 | ||
@@ -787,6 +837,8 @@ imx_console_setup(struct console *co, char *options) | |||
787 | else | 837 | else |
788 | imx_console_get_options(sport, &baud, &parity, &bits); | 838 | imx_console_get_options(sport, &baud, &parity, &bits); |
789 | 839 | ||
840 | imx_setup_ufcr(sport, 0); | ||
841 | |||
790 | return uart_set_options(&sport->port, co, baud, parity, bits, flow); | 842 | return uart_set_options(&sport->port, co, baud, parity, bits, flow); |
791 | } | 843 | } |
792 | 844 | ||
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index d054f1265701..ba4e13a22a50 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -838,7 +838,7 @@ static int inline port_init(struct ioc4_port *port) | |||
838 | port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK; | 838 | port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK; |
839 | writel(port->ip_tx_prod, &port->ip_serial_regs->stpir); | 839 | writel(port->ip_tx_prod, &port->ip_serial_regs->stpir); |
840 | port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK; | 840 | port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK; |
841 | writel(port->ip_rx_cons, &port->ip_serial_regs->srcir); | 841 | writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir); |
842 | 842 | ||
843 | /* Disable interrupts for this 16550 */ | 843 | /* Disable interrupts for this 16550 */ |
844 | uart = port->ip_uart_regs; | 844 | uart = port->ip_uart_regs; |
@@ -1272,8 +1272,9 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout) | |||
1272 | * and set the rx threshold to that amount. There are 4 chars | 1272 | * and set the rx threshold to that amount. There are 4 chars |
1273 | * per ring entry, so we'll divide the number of chars that will | 1273 | * per ring entry, so we'll divide the number of chars that will |
1274 | * arrive in timeout by 4. | 1274 | * arrive in timeout by 4. |
1275 | * So .... timeout * baud / 10 / HZ / 4, with HZ = 100. | ||
1275 | */ | 1276 | */ |
1276 | threshold = timeout * port->ip_baud / 10 / HZ / 4; | 1277 | threshold = timeout * port->ip_baud / 4000; |
1277 | if (threshold == 0) | 1278 | if (threshold == 0) |
1278 | threshold = 1; /* otherwise we'll intr all the time! */ | 1279 | threshold = 1; /* otherwise we'll intr all the time! */ |
1279 | 1280 | ||
@@ -1285,8 +1286,10 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout) | |||
1285 | 1286 | ||
1286 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | 1287 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); |
1287 | 1288 | ||
1288 | /* Now set the rx timeout to the given value */ | 1289 | /* Now set the rx timeout to the given value |
1289 | timeout = timeout * IOC4_SRTR_HZ / HZ; | 1290 | * again timeout * IOC4_SRTR_HZ / HZ |
1291 | */ | ||
1292 | timeout = timeout * IOC4_SRTR_HZ / 100; | ||
1290 | if (timeout > IOC4_SRTR_CNT) | 1293 | if (timeout > IOC4_SRTR_CNT) |
1291 | timeout = IOC4_SRTR_CNT; | 1294 | timeout = IOC4_SRTR_CNT; |
1292 | 1295 | ||
@@ -1380,7 +1383,7 @@ config_port(struct ioc4_port *port, | |||
1380 | if (port->ip_tx_lowat == 0) | 1383 | if (port->ip_tx_lowat == 0) |
1381 | port->ip_tx_lowat = 1; | 1384 | port->ip_tx_lowat = 1; |
1382 | 1385 | ||
1383 | set_rx_timeout(port, port->ip_rx_timeout); | 1386 | set_rx_timeout(port, 2); |
1384 | 1387 | ||
1385 | return 0; | 1388 | return 0; |
1386 | } | 1389 | } |
@@ -1685,8 +1688,8 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1685 | { | 1688 | { |
1686 | struct ioc4_port *port = get_ioc4_port(the_port); | 1689 | struct ioc4_port *port = get_ioc4_port(the_port); |
1687 | int baud, bits; | 1690 | int baud, bits; |
1688 | unsigned cflag, cval; | 1691 | unsigned cflag; |
1689 | int new_parity = 0, new_parity_enable = 0, new_stop = 1, new_data = 8; | 1692 | int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; |
1690 | struct uart_info *info = the_port->info; | 1693 | struct uart_info *info = the_port->info; |
1691 | 1694 | ||
1692 | cflag = new_termios->c_cflag; | 1695 | cflag = new_termios->c_cflag; |
@@ -1694,48 +1697,35 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1694 | switch (cflag & CSIZE) { | 1697 | switch (cflag & CSIZE) { |
1695 | case CS5: | 1698 | case CS5: |
1696 | new_data = 5; | 1699 | new_data = 5; |
1697 | cval = 0x00; | ||
1698 | bits = 7; | 1700 | bits = 7; |
1699 | break; | 1701 | break; |
1700 | case CS6: | 1702 | case CS6: |
1701 | new_data = 6; | 1703 | new_data = 6; |
1702 | cval = 0x01; | ||
1703 | bits = 8; | 1704 | bits = 8; |
1704 | break; | 1705 | break; |
1705 | case CS7: | 1706 | case CS7: |
1706 | new_data = 7; | 1707 | new_data = 7; |
1707 | cval = 0x02; | ||
1708 | bits = 9; | 1708 | bits = 9; |
1709 | break; | 1709 | break; |
1710 | case CS8: | 1710 | case CS8: |
1711 | new_data = 8; | 1711 | new_data = 8; |
1712 | cval = 0x03; | ||
1713 | bits = 10; | 1712 | bits = 10; |
1714 | break; | 1713 | break; |
1715 | default: | 1714 | default: |
1716 | /* cuz we always need a default ... */ | 1715 | /* cuz we always need a default ... */ |
1717 | new_data = 5; | 1716 | new_data = 5; |
1718 | cval = 0x00; | ||
1719 | bits = 7; | 1717 | bits = 7; |
1720 | break; | 1718 | break; |
1721 | } | 1719 | } |
1722 | if (cflag & CSTOPB) { | 1720 | if (cflag & CSTOPB) { |
1723 | cval |= 0x04; | ||
1724 | bits++; | 1721 | bits++; |
1725 | new_stop = 1; | 1722 | new_stop = 1; |
1726 | } | 1723 | } |
1727 | if (cflag & PARENB) { | 1724 | if (cflag & PARENB) { |
1728 | cval |= UART_LCR_PARITY; | ||
1729 | bits++; | 1725 | bits++; |
1730 | new_parity_enable = 1; | 1726 | new_parity_enable = 1; |
1731 | } | 1727 | if (cflag & PARODD) |
1732 | if (cflag & PARODD) { | 1728 | new_parity = 1; |
1733 | cval |= UART_LCR_EPAR; | ||
1734 | new_parity = 1; | ||
1735 | } | ||
1736 | if (cflag & IGNPAR) { | ||
1737 | cval &= ~UART_LCR_PARITY; | ||
1738 | new_parity_enable = 0; | ||
1739 | } | 1729 | } |
1740 | baud = uart_get_baud_rate(the_port, new_termios, old_termios, | 1730 | baud = uart_get_baud_rate(the_port, new_termios, old_termios, |
1741 | MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED); | 1731 | MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED); |
@@ -1765,10 +1755,15 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1765 | the_port->ignore_status_mask &= ~N_DATA_READY; | 1755 | the_port->ignore_status_mask &= ~N_DATA_READY; |
1766 | } | 1756 | } |
1767 | 1757 | ||
1768 | if (cflag & CRTSCTS) | 1758 | if (cflag & CRTSCTS) { |
1769 | info->flags |= ASYNC_CTS_FLOW; | 1759 | info->flags |= ASYNC_CTS_FLOW; |
1770 | else | 1760 | port->ip_sscr |= IOC4_SSCR_HFC_EN; |
1761 | } | ||
1762 | else { | ||
1771 | info->flags &= ~ASYNC_CTS_FLOW; | 1763 | info->flags &= ~ASYNC_CTS_FLOW; |
1764 | port->ip_sscr &= ~IOC4_SSCR_HFC_EN; | ||
1765 | } | ||
1766 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | ||
1772 | 1767 | ||
1773 | /* Set the configuration and proper notification call */ | 1768 | /* Set the configuration and proper notification call */ |
1774 | DPRINT_CONFIG(("%s : port 0x%p cflag 0%o " | 1769 | DPRINT_CONFIG(("%s : port 0x%p cflag 0%o " |
@@ -1825,12 +1820,6 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
1825 | /* set the speed of the serial port */ | 1820 | /* set the speed of the serial port */ |
1826 | ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); | 1821 | ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); |
1827 | 1822 | ||
1828 | /* enable hardware flow control - after ioc4_change_speed because | ||
1829 | * ASYNC_CTS_FLOW is set there */ | ||
1830 | if (info->flags & ASYNC_CTS_FLOW) { | ||
1831 | port->ip_sscr |= IOC4_SSCR_HFC_EN; | ||
1832 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | ||
1833 | } | ||
1834 | info->flags |= UIF_INITIALIZED; | 1823 | info->flags |= UIF_INITIALIZED; |
1835 | return 0; | 1824 | return 0; |
1836 | } | 1825 | } |
@@ -1847,7 +1836,6 @@ static void ioc4_cb_output_lowat(struct ioc4_port *port) | |||
1847 | } | 1836 | } |
1848 | } | 1837 | } |
1849 | 1838 | ||
1850 | |||
1851 | /** | 1839 | /** |
1852 | * handle_intr - service any interrupts for the given port - 2nd level | 1840 | * handle_intr - service any interrupts for the given port - 2nd level |
1853 | * called via sd_intr | 1841 | * called via sd_intr |
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h index e0717611c940..777829fa3300 100644 --- a/drivers/serial/jsm/jsm.h +++ b/drivers/serial/jsm/jsm.h | |||
@@ -393,7 +393,6 @@ int jsm_tty_init(struct jsm_board *); | |||
393 | int jsm_uart_port_init(struct jsm_board *); | 393 | int jsm_uart_port_init(struct jsm_board *); |
394 | int jsm_remove_uart_port(struct jsm_board *); | 394 | int jsm_remove_uart_port(struct jsm_board *); |
395 | void jsm_input(struct jsm_channel *ch); | 395 | void jsm_input(struct jsm_channel *ch); |
396 | void jsm_carrier(struct jsm_channel *ch); | ||
397 | void jsm_check_queue_flow_control(struct jsm_channel *ch); | 396 | void jsm_check_queue_flow_control(struct jsm_channel *ch); |
398 | 397 | ||
399 | #endif | 398 | #endif |
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c index 9b79c1ff6c72..3a11a69feb44 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/serial/jsm/jsm_neo.c | |||
@@ -688,7 +688,7 @@ static void neo_flush_uart_read(struct jsm_channel *ch) | |||
688 | /* | 688 | /* |
689 | * No locks are assumed to be held when calling this function. | 689 | * No locks are assumed to be held when calling this function. |
690 | */ | 690 | */ |
691 | void neo_clear_break(struct jsm_channel *ch, int force) | 691 | static void neo_clear_break(struct jsm_channel *ch, int force) |
692 | { | 692 | { |
693 | unsigned long lock_flags; | 693 | unsigned long lock_flags; |
694 | 694 | ||
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 24fe76c28833..98de2258fd06 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
@@ -31,6 +31,8 @@ | |||
31 | 31 | ||
32 | #include "jsm.h" | 32 | #include "jsm.h" |
33 | 33 | ||
34 | static void jsm_carrier(struct jsm_channel *ch); | ||
35 | |||
34 | static inline int jsm_get_mstat(struct jsm_channel *ch) | 36 | static inline int jsm_get_mstat(struct jsm_channel *ch) |
35 | { | 37 | { |
36 | unsigned char mstat; | 38 | unsigned char mstat; |
@@ -755,7 +757,7 @@ void jsm_input(struct jsm_channel *ch) | |||
755 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); | 757 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); |
756 | } | 758 | } |
757 | 759 | ||
758 | void jsm_carrier(struct jsm_channel *ch) | 760 | static void jsm_carrier(struct jsm_channel *ch) |
759 | { | 761 | { |
760 | struct jsm_board *bd; | 762 | struct jsm_board *bd; |
761 | 763 | ||
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 9034f9ad37c7..6eeb48f6a482 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -107,6 +107,13 @@ struct serial_info { | |||
107 | int line[4]; | 107 | int line[4]; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | struct serial_cfg_mem { | ||
111 | tuple_t tuple; | ||
112 | cisparse_t parse; | ||
113 | u_char buf[256]; | ||
114 | }; | ||
115 | |||
116 | |||
110 | static void serial_config(dev_link_t * link); | 117 | static void serial_config(dev_link_t * link); |
111 | static int serial_event(event_t event, int priority, | 118 | static int serial_event(event_t event, int priority, |
112 | event_callback_args_t * args); | 119 | event_callback_args_t * args); |
@@ -357,14 +364,24 @@ static int simple_config(dev_link_t *link) | |||
357 | static int size_table[2] = { 8, 16 }; | 364 | static int size_table[2] = { 8, 16 }; |
358 | client_handle_t handle = link->handle; | 365 | client_handle_t handle = link->handle; |
359 | struct serial_info *info = link->priv; | 366 | struct serial_info *info = link->priv; |
360 | tuple_t tuple; | 367 | struct serial_cfg_mem *cfg_mem; |
361 | u_char buf[256]; | 368 | tuple_t *tuple; |
362 | cisparse_t parse; | 369 | u_char *buf; |
363 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 370 | cisparse_t *parse; |
371 | cistpl_cftable_entry_t *cf; | ||
364 | config_info_t config; | 372 | config_info_t config; |
365 | int i, j, try; | 373 | int i, j, try; |
366 | int s; | 374 | int s; |
367 | 375 | ||
376 | cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); | ||
377 | if (!cfg_mem) | ||
378 | return -1; | ||
379 | |||
380 | tuple = &cfg_mem->tuple; | ||
381 | parse = &cfg_mem->parse; | ||
382 | cf = &parse->cftable_entry; | ||
383 | buf = cfg_mem->buf; | ||
384 | |||
368 | /* If the card is already configured, look up the port and irq */ | 385 | /* If the card is already configured, look up the port and irq */ |
369 | i = pcmcia_get_configuration_info(handle, &config); | 386 | i = pcmcia_get_configuration_info(handle, &config); |
370 | if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { | 387 | if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { |
@@ -377,21 +394,23 @@ static int simple_config(dev_link_t *link) | |||
377 | port = config.BasePort1 + 0x28; | 394 | port = config.BasePort1 + 0x28; |
378 | info->slave = 1; | 395 | info->slave = 1; |
379 | } | 396 | } |
380 | if (info->slave) | 397 | if (info->slave) { |
398 | kfree(cfg_mem); | ||
381 | return setup_serial(handle, info, port, config.AssignedIRQ); | 399 | return setup_serial(handle, info, port, config.AssignedIRQ); |
400 | } | ||
382 | } | 401 | } |
383 | link->conf.Vcc = config.Vcc; | 402 | link->conf.Vcc = config.Vcc; |
384 | 403 | ||
385 | /* First pass: look for a config entry that looks normal. */ | 404 | /* First pass: look for a config entry that looks normal. */ |
386 | tuple.TupleData = (cisdata_t *) buf; | 405 | tuple->TupleData = (cisdata_t *) buf; |
387 | tuple.TupleOffset = 0; | 406 | tuple->TupleOffset = 0; |
388 | tuple.TupleDataMax = 255; | 407 | tuple->TupleDataMax = 255; |
389 | tuple.Attributes = 0; | 408 | tuple->Attributes = 0; |
390 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 409 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
391 | /* Two tries: without IO aliases, then with aliases */ | 410 | /* Two tries: without IO aliases, then with aliases */ |
392 | for (s = 0; s < 2; s++) { | 411 | for (s = 0; s < 2; s++) { |
393 | for (try = 0; try < 2; try++) { | 412 | for (try = 0; try < 2; try++) { |
394 | i = first_tuple(handle, &tuple, &parse); | 413 | i = first_tuple(handle, tuple, parse); |
395 | while (i != CS_NO_MORE_ITEMS) { | 414 | while (i != CS_NO_MORE_ITEMS) { |
396 | if (i != CS_SUCCESS) | 415 | if (i != CS_SUCCESS) |
397 | goto next_entry; | 416 | goto next_entry; |
@@ -409,14 +428,14 @@ static int simple_config(dev_link_t *link) | |||
409 | goto found_port; | 428 | goto found_port; |
410 | } | 429 | } |
411 | next_entry: | 430 | next_entry: |
412 | i = next_tuple(handle, &tuple, &parse); | 431 | i = next_tuple(handle, tuple, parse); |
413 | } | 432 | } |
414 | } | 433 | } |
415 | } | 434 | } |
416 | /* Second pass: try to find an entry that isn't picky about | 435 | /* Second pass: try to find an entry that isn't picky about |
417 | its base address, then try to grab any standard serial port | 436 | its base address, then try to grab any standard serial port |
418 | address, and finally try to get any free port. */ | 437 | address, and finally try to get any free port. */ |
419 | i = first_tuple(handle, &tuple, &parse); | 438 | i = first_tuple(handle, tuple, parse); |
420 | while (i != CS_NO_MORE_ITEMS) { | 439 | while (i != CS_NO_MORE_ITEMS) { |
421 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && | 440 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && |
422 | ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { | 441 | ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { |
@@ -429,7 +448,7 @@ next_entry: | |||
429 | goto found_port; | 448 | goto found_port; |
430 | } | 449 | } |
431 | } | 450 | } |
432 | i = next_tuple(handle, &tuple, &parse); | 451 | i = next_tuple(handle, tuple, parse); |
433 | } | 452 | } |
434 | 453 | ||
435 | found_port: | 454 | found_port: |
@@ -437,6 +456,7 @@ next_entry: | |||
437 | printk(KERN_NOTICE | 456 | printk(KERN_NOTICE |
438 | "serial_cs: no usable port range found, giving up\n"); | 457 | "serial_cs: no usable port range found, giving up\n"); |
439 | cs_error(link->handle, RequestIO, i); | 458 | cs_error(link->handle, RequestIO, i); |
459 | kfree(cfg_mem); | ||
440 | return -1; | 460 | return -1; |
441 | } | 461 | } |
442 | 462 | ||
@@ -450,9 +470,10 @@ next_entry: | |||
450 | i = pcmcia_request_configuration(link->handle, &link->conf); | 470 | i = pcmcia_request_configuration(link->handle, &link->conf); |
451 | if (i != CS_SUCCESS) { | 471 | if (i != CS_SUCCESS) { |
452 | cs_error(link->handle, RequestConfiguration, i); | 472 | cs_error(link->handle, RequestConfiguration, i); |
473 | kfree(cfg_mem); | ||
453 | return -1; | 474 | return -1; |
454 | } | 475 | } |
455 | 476 | kfree(cfg_mem); | |
456 | return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); | 477 | return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); |
457 | } | 478 | } |
458 | 479 | ||
@@ -460,29 +481,39 @@ static int multi_config(dev_link_t * link) | |||
460 | { | 481 | { |
461 | client_handle_t handle = link->handle; | 482 | client_handle_t handle = link->handle; |
462 | struct serial_info *info = link->priv; | 483 | struct serial_info *info = link->priv; |
463 | tuple_t tuple; | 484 | struct serial_cfg_mem *cfg_mem; |
464 | u_char buf[256]; | 485 | tuple_t *tuple; |
465 | cisparse_t parse; | 486 | u_char *buf; |
466 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 487 | cisparse_t *parse; |
488 | cistpl_cftable_entry_t *cf; | ||
467 | config_info_t config; | 489 | config_info_t config; |
468 | int i, base2 = 0; | 490 | int i, rc, base2 = 0; |
491 | |||
492 | cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); | ||
493 | if (!cfg_mem) | ||
494 | return -1; | ||
495 | tuple = &cfg_mem->tuple; | ||
496 | parse = &cfg_mem->parse; | ||
497 | cf = &parse->cftable_entry; | ||
498 | buf = cfg_mem->buf; | ||
469 | 499 | ||
470 | i = pcmcia_get_configuration_info(handle, &config); | 500 | i = pcmcia_get_configuration_info(handle, &config); |
471 | if (i != CS_SUCCESS) { | 501 | if (i != CS_SUCCESS) { |
472 | cs_error(handle, GetConfigurationInfo, i); | 502 | cs_error(handle, GetConfigurationInfo, i); |
473 | return -1; | 503 | rc = -1; |
504 | goto free_cfg_mem; | ||
474 | } | 505 | } |
475 | link->conf.Vcc = config.Vcc; | 506 | link->conf.Vcc = config.Vcc; |
476 | 507 | ||
477 | tuple.TupleData = (cisdata_t *) buf; | 508 | tuple->TupleData = (cisdata_t *) buf; |
478 | tuple.TupleOffset = 0; | 509 | tuple->TupleOffset = 0; |
479 | tuple.TupleDataMax = 255; | 510 | tuple->TupleDataMax = 255; |
480 | tuple.Attributes = 0; | 511 | tuple->Attributes = 0; |
481 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 512 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
482 | 513 | ||
483 | /* First, look for a generic full-sized window */ | 514 | /* First, look for a generic full-sized window */ |
484 | link->io.NumPorts1 = info->multi * 8; | 515 | link->io.NumPorts1 = info->multi * 8; |
485 | i = first_tuple(handle, &tuple, &parse); | 516 | i = first_tuple(handle, tuple, parse); |
486 | while (i != CS_NO_MORE_ITEMS) { | 517 | while (i != CS_NO_MORE_ITEMS) { |
487 | /* The quad port cards have bad CIS's, so just look for a | 518 | /* The quad port cards have bad CIS's, so just look for a |
488 | window larger than 8 ports and assume it will be right */ | 519 | window larger than 8 ports and assume it will be right */ |
@@ -497,14 +528,14 @@ static int multi_config(dev_link_t * link) | |||
497 | if (i == CS_SUCCESS) | 528 | if (i == CS_SUCCESS) |
498 | break; | 529 | break; |
499 | } | 530 | } |
500 | i = next_tuple(handle, &tuple, &parse); | 531 | i = next_tuple(handle, tuple, parse); |
501 | } | 532 | } |
502 | 533 | ||
503 | /* If that didn't work, look for two windows */ | 534 | /* If that didn't work, look for two windows */ |
504 | if (i != CS_SUCCESS) { | 535 | if (i != CS_SUCCESS) { |
505 | link->io.NumPorts1 = link->io.NumPorts2 = 8; | 536 | link->io.NumPorts1 = link->io.NumPorts2 = 8; |
506 | info->multi = 2; | 537 | info->multi = 2; |
507 | i = first_tuple(handle, &tuple, &parse); | 538 | i = first_tuple(handle, tuple, parse); |
508 | while (i != CS_NO_MORE_ITEMS) { | 539 | while (i != CS_NO_MORE_ITEMS) { |
509 | if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { | 540 | if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { |
510 | link->conf.ConfigIndex = cf->index; | 541 | link->conf.ConfigIndex = cf->index; |
@@ -517,13 +548,14 @@ static int multi_config(dev_link_t * link) | |||
517 | if (i == CS_SUCCESS) | 548 | if (i == CS_SUCCESS) |
518 | break; | 549 | break; |
519 | } | 550 | } |
520 | i = next_tuple(handle, &tuple, &parse); | 551 | i = next_tuple(handle, tuple, parse); |
521 | } | 552 | } |
522 | } | 553 | } |
523 | 554 | ||
524 | if (i != CS_SUCCESS) { | 555 | if (i != CS_SUCCESS) { |
525 | cs_error(link->handle, RequestIO, i); | 556 | cs_error(link->handle, RequestIO, i); |
526 | return -1; | 557 | rc = -1; |
558 | goto free_cfg_mem; | ||
527 | } | 559 | } |
528 | 560 | ||
529 | i = pcmcia_request_irq(link->handle, &link->irq); | 561 | i = pcmcia_request_irq(link->handle, &link->irq); |
@@ -541,7 +573,8 @@ static int multi_config(dev_link_t * link) | |||
541 | i = pcmcia_request_configuration(link->handle, &link->conf); | 573 | i = pcmcia_request_configuration(link->handle, &link->conf); |
542 | if (i != CS_SUCCESS) { | 574 | if (i != CS_SUCCESS) { |
543 | cs_error(link->handle, RequestConfiguration, i); | 575 | cs_error(link->handle, RequestConfiguration, i); |
544 | return -1; | 576 | rc = -1; |
577 | goto free_cfg_mem; | ||
545 | } | 578 | } |
546 | 579 | ||
547 | /* The Oxford Semiconductor OXCF950 cards are in fact single-port: | 580 | /* The Oxford Semiconductor OXCF950 cards are in fact single-port: |
@@ -554,17 +587,23 @@ static int multi_config(dev_link_t * link) | |||
554 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); | 587 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); |
555 | outb(12, base2 + 1); | 588 | outb(12, base2 + 1); |
556 | } | 589 | } |
557 | return 0; | 590 | rc = 0; |
591 | goto free_cfg_mem; | ||
558 | } | 592 | } |
559 | 593 | ||
560 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); | 594 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); |
561 | /* The Nokia cards are not really multiport cards */ | 595 | /* The Nokia cards are not really multiport cards */ |
562 | if (info->manfid == MANFID_NOKIA) | 596 | if (info->manfid == MANFID_NOKIA) { |
563 | return 0; | 597 | rc = 0; |
598 | goto free_cfg_mem; | ||
599 | } | ||
564 | for (i = 0; i < info->multi - 1; i++) | 600 | for (i = 0; i < info->multi - 1; i++) |
565 | setup_serial(handle, info, base2 + (8 * i), link->irq.AssignedIRQ); | 601 | setup_serial(handle, info, base2 + (8 * i), |
566 | 602 | link->irq.AssignedIRQ); | |
567 | return 0; | 603 | rc = 0; |
604 | free_cfg_mem: | ||
605 | kfree(cfg_mem); | ||
606 | return rc; | ||
568 | } | 607 | } |
569 | 608 | ||
570 | /*====================================================================== | 609 | /*====================================================================== |
@@ -579,39 +618,49 @@ void serial_config(dev_link_t * link) | |||
579 | { | 618 | { |
580 | client_handle_t handle = link->handle; | 619 | client_handle_t handle = link->handle; |
581 | struct serial_info *info = link->priv; | 620 | struct serial_info *info = link->priv; |
582 | tuple_t tuple; | 621 | struct serial_cfg_mem *cfg_mem; |
583 | u_short buf[128]; | 622 | tuple_t *tuple; |
584 | cisparse_t parse; | 623 | u_char *buf; |
585 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 624 | cisparse_t *parse; |
625 | cistpl_cftable_entry_t *cf; | ||
586 | int i, last_ret, last_fn; | 626 | int i, last_ret, last_fn; |
587 | 627 | ||
588 | DEBUG(0, "serial_config(0x%p)\n", link); | 628 | DEBUG(0, "serial_config(0x%p)\n", link); |
589 | 629 | ||
590 | tuple.TupleData = (cisdata_t *) buf; | 630 | cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); |
591 | tuple.TupleOffset = 0; | 631 | if (!cfg_mem) |
592 | tuple.TupleDataMax = 255; | 632 | goto failed; |
593 | tuple.Attributes = 0; | 633 | |
634 | tuple = &cfg_mem->tuple; | ||
635 | parse = &cfg_mem->parse; | ||
636 | cf = &parse->cftable_entry; | ||
637 | buf = cfg_mem->buf; | ||
638 | |||
639 | tuple->TupleData = (cisdata_t *) buf; | ||
640 | tuple->TupleOffset = 0; | ||
641 | tuple->TupleDataMax = 255; | ||
642 | tuple->Attributes = 0; | ||
594 | /* Get configuration register information */ | 643 | /* Get configuration register information */ |
595 | tuple.DesiredTuple = CISTPL_CONFIG; | 644 | tuple->DesiredTuple = CISTPL_CONFIG; |
596 | last_ret = first_tuple(handle, &tuple, &parse); | 645 | last_ret = first_tuple(handle, tuple, parse); |
597 | if (last_ret != CS_SUCCESS) { | 646 | if (last_ret != CS_SUCCESS) { |
598 | last_fn = ParseTuple; | 647 | last_fn = ParseTuple; |
599 | goto cs_failed; | 648 | goto cs_failed; |
600 | } | 649 | } |
601 | link->conf.ConfigBase = parse.config.base; | 650 | link->conf.ConfigBase = parse->config.base; |
602 | link->conf.Present = parse.config.rmask[0]; | 651 | link->conf.Present = parse->config.rmask[0]; |
603 | 652 | ||
604 | /* Configure card */ | 653 | /* Configure card */ |
605 | link->state |= DEV_CONFIG; | 654 | link->state |= DEV_CONFIG; |
606 | 655 | ||
607 | /* Is this a compliant multifunction card? */ | 656 | /* Is this a compliant multifunction card? */ |
608 | tuple.DesiredTuple = CISTPL_LONGLINK_MFC; | 657 | tuple->DesiredTuple = CISTPL_LONGLINK_MFC; |
609 | tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; | 658 | tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; |
610 | info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS); | 659 | info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS); |
611 | 660 | ||
612 | /* Is this a multiport card? */ | 661 | /* Is this a multiport card? */ |
613 | tuple.DesiredTuple = CISTPL_MANFID; | 662 | tuple->DesiredTuple = CISTPL_MANFID; |
614 | if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { | 663 | if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { |
615 | info->manfid = le16_to_cpu(buf[0]); | 664 | info->manfid = le16_to_cpu(buf[0]); |
616 | for (i = 0; i < MULTI_COUNT; i++) | 665 | for (i = 0; i < MULTI_COUNT; i++) |
617 | if ((info->manfid == multi_id[i].manfid) && | 666 | if ((info->manfid == multi_id[i].manfid) && |
@@ -623,13 +672,13 @@ void serial_config(dev_link_t * link) | |||
623 | 672 | ||
624 | /* Another check for dual-serial cards: look for either serial or | 673 | /* Another check for dual-serial cards: look for either serial or |
625 | multifunction cards that ask for appropriate IO port ranges */ | 674 | multifunction cards that ask for appropriate IO port ranges */ |
626 | tuple.DesiredTuple = CISTPL_FUNCID; | 675 | tuple->DesiredTuple = CISTPL_FUNCID; |
627 | if ((info->multi == 0) && | 676 | if ((info->multi == 0) && |
628 | ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) || | 677 | ((first_tuple(handle, tuple, parse) != CS_SUCCESS) || |
629 | (parse.funcid.func == CISTPL_FUNCID_MULTI) || | 678 | (parse->funcid.func == CISTPL_FUNCID_MULTI) || |
630 | (parse.funcid.func == CISTPL_FUNCID_SERIAL))) { | 679 | (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { |
631 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 680 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
632 | if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { | 681 | if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { |
633 | if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) | 682 | if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) |
634 | info->multi = cf->io.win[0].len >> 3; | 683 | info->multi = cf->io.win[0].len >> 3; |
635 | if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && | 684 | if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && |
@@ -664,6 +713,7 @@ void serial_config(dev_link_t * link) | |||
664 | 713 | ||
665 | link->dev = &info->node[0]; | 714 | link->dev = &info->node[0]; |
666 | link->state &= ~DEV_CONFIG_PENDING; | 715 | link->state &= ~DEV_CONFIG_PENDING; |
716 | kfree(cfg_mem); | ||
667 | return; | 717 | return; |
668 | 718 | ||
669 | cs_failed: | 719 | cs_failed: |
@@ -671,6 +721,7 @@ void serial_config(dev_link_t * link) | |||
671 | failed: | 721 | failed: |
672 | serial_remove(link); | 722 | serial_remove(link); |
673 | link->state &= ~DEV_CONFIG_PENDING; | 723 | link->state &= ~DEV_CONFIG_PENDING; |
724 | kfree(cfg_mem); | ||
674 | } | 725 | } |
675 | 726 | ||
676 | /*====================================================================== | 727 | /*====================================================================== |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index ffaab9b90fd8..fee6418e84c4 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -787,7 +787,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port) | |||
787 | 787 | ||
788 | static void sn_sal_console_write(struct console *, const char *, unsigned); | 788 | static void sn_sal_console_write(struct console *, const char *, unsigned); |
789 | static int __init sn_sal_console_setup(struct console *, char *); | 789 | static int __init sn_sal_console_setup(struct console *, char *); |
790 | extern struct uart_driver sal_console_uart; | 790 | static struct uart_driver sal_console_uart; |
791 | extern struct tty_driver *uart_console_device(struct console *, int *); | 791 | extern struct tty_driver *uart_console_device(struct console *, int *); |
792 | 792 | ||
793 | static struct console sal_console = { | 793 | static struct console sal_console = { |
@@ -801,7 +801,7 @@ static struct console sal_console = { | |||
801 | 801 | ||
802 | #define SAL_CONSOLE &sal_console | 802 | #define SAL_CONSOLE &sal_console |
803 | 803 | ||
804 | struct uart_driver sal_console_uart = { | 804 | static struct uart_driver sal_console_uart = { |
805 | .owner = THIS_MODULE, | 805 | .owner = THIS_MODULE, |
806 | .driver_name = "sn_console", | 806 | .driver_name = "sn_console", |
807 | .dev_name = DEVICE_NAME, | 807 | .dev_name = DEVICE_NAME, |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2a1c5965de22..6be8fbec0a0e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -198,6 +198,14 @@ config FB_SA1100 | |||
198 | If you plan to use the LCD display with your SA-1100 system, say | 198 | If you plan to use the LCD display with your SA-1100 system, say |
199 | Y here. | 199 | Y here. |
200 | 200 | ||
201 | config FB_IMX | ||
202 | tristate "Motorola i.MX LCD support" | ||
203 | depends on FB && ARM && ARCH_IMX | ||
204 | select FB_CFB_FILLRECT | ||
205 | select FB_CFB_COPYAREA | ||
206 | select FB_CFB_IMAGEBLIT | ||
207 | select FB_SOFT_CURSOR | ||
208 | |||
201 | config FB_CYBER2000 | 209 | config FB_CYBER2000 |
202 | tristate "CyberPro 2000/2010/5000 support" | 210 | tristate "CyberPro 2000/2010/5000 support" |
203 | depends on FB && PCI && (BROKEN || !SPARC64) | 211 | depends on FB && PCI && (BROKEN || !SPARC64) |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 92265b741dc3..bd8dc0ffe723 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -90,6 +90,7 @@ obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o | |||
90 | obj-$(CONFIG_FB_MAXINE) += maxinefb.o | 90 | obj-$(CONFIG_FB_MAXINE) += maxinefb.o |
91 | obj-$(CONFIG_FB_TX3912) += tx3912fb.o | 91 | obj-$(CONFIG_FB_TX3912) += tx3912fb.o |
92 | obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o | 92 | obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o |
93 | obj-$(CONFIG_FB_IMX) += imxfb.o | ||
93 | 94 | ||
94 | # Platform or fallback drivers go here | 95 | # Platform or fallback drivers go here |
95 | obj-$(CONFIG_FB_VESA) += vesafb.o | 96 | obj-$(CONFIG_FB_VESA) += vesafb.o |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index acdba0c67fb8..321dbe91dc14 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -125,28 +125,28 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) | |||
125 | case 2: | 125 | case 2: |
126 | case 4: | 126 | case 4: |
127 | case 8: | 127 | case 8: |
128 | var->red.length = 8; | 128 | var->red.length = var->bits_per_pixel; |
129 | var->red.offset = 0; | 129 | var->red.offset = 0; |
130 | var->green.length = 8; | 130 | var->green.length = var->bits_per_pixel; |
131 | var->green.offset = 0; | 131 | var->green.offset = 0; |
132 | var->blue.length = 8; | 132 | var->blue.length = var->bits_per_pixel; |
133 | var->blue.offset = 0; | 133 | var->blue.offset = 0; |
134 | break; | 134 | break; |
135 | case 16: | 135 | case 16: |
136 | var->red.length = 5; | 136 | var->red.length = 5; |
137 | var->green.length = 5; | 137 | var->green.length = 6; |
138 | var->blue.length = 5; | 138 | var->blue.length = 5; |
139 | if (fb->panel->cntl & CNTL_BGR) { | 139 | if (fb->panel->cntl & CNTL_BGR) { |
140 | var->red.offset = 10; | 140 | var->red.offset = 11; |
141 | var->green.offset = 5; | 141 | var->green.offset = 5; |
142 | var->blue.offset = 0; | 142 | var->blue.offset = 0; |
143 | } else { | 143 | } else { |
144 | var->red.offset = 0; | 144 | var->red.offset = 0; |
145 | var->green.offset = 5; | 145 | var->green.offset = 5; |
146 | var->blue.offset = 10; | 146 | var->blue.offset = 11; |
147 | } | 147 | } |
148 | break; | 148 | break; |
149 | case 24: | 149 | case 32: |
150 | if (fb->panel->cntl & CNTL_LCDTFT) { | 150 | if (fb->panel->cntl & CNTL_LCDTFT) { |
151 | var->red.length = 8; | 151 | var->red.length = 8; |
152 | var->green.length = 8; | 152 | var->green.length = 8; |
@@ -178,6 +178,12 @@ static int clcdfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
178 | 178 | ||
179 | if (fb->board->check) | 179 | if (fb->board->check) |
180 | ret = fb->board->check(fb, var); | 180 | ret = fb->board->check(fb, var); |
181 | |||
182 | if (ret == 0 && | ||
183 | var->xres_virtual * var->bits_per_pixel / 8 * | ||
184 | var->yres_virtual > fb->fb.fix.smem_len) | ||
185 | ret = -EINVAL; | ||
186 | |||
181 | if (ret == 0) | 187 | if (ret == 0) |
182 | ret = clcdfb_set_bitfields(fb, var); | 188 | ret = clcdfb_set_bitfields(fb, var); |
183 | 189 | ||
@@ -250,7 +256,7 @@ clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, | |||
250 | convert_bitfield(green, &fb->fb.var.green) | | 256 | convert_bitfield(green, &fb->fb.var.green) | |
251 | convert_bitfield(red, &fb->fb.var.red); | 257 | convert_bitfield(red, &fb->fb.var.red); |
252 | 258 | ||
253 | if (fb->fb.var.bits_per_pixel == 8 && regno < 256) { | 259 | if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) { |
254 | int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3); | 260 | int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3); |
255 | u32 val, mask, newval; | 261 | u32 val, mask, newval; |
256 | 262 | ||
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index e8eb124754b1..ee25b9e8db60 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -1057,13 +1057,14 @@ static int radeonfb_blank (int blank, struct fb_info *info) | |||
1057 | return radeon_screen_blank(rinfo, blank, 0); | 1057 | return radeon_screen_blank(rinfo, blank, 0); |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | 1060 | static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, |
1061 | unsigned blue, unsigned transp, struct fb_info *info) | 1061 | unsigned blue, unsigned transp, |
1062 | struct radeonfb_info *rinfo) | ||
1062 | { | 1063 | { |
1063 | struct radeonfb_info *rinfo = info->par; | ||
1064 | u32 pindex; | 1064 | u32 pindex; |
1065 | unsigned int i; | 1065 | unsigned int i; |
1066 | 1066 | ||
1067 | |||
1067 | if (regno > 255) | 1068 | if (regno > 255) |
1068 | return 1; | 1069 | return 1; |
1069 | 1070 | ||
@@ -1078,20 +1079,7 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1078 | pindex = regno; | 1079 | pindex = regno; |
1079 | 1080 | ||
1080 | if (!rinfo->asleep) { | 1081 | if (!rinfo->asleep) { |
1081 | u32 dac_cntl2, vclk_cntl = 0; | ||
1082 | |||
1083 | radeon_fifo_wait(9); | 1082 | radeon_fifo_wait(9); |
1084 | if (rinfo->is_mobility) { | ||
1085 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1086 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1087 | } | ||
1088 | |||
1089 | /* Make sure we are on first palette */ | ||
1090 | if (rinfo->has_CRTC2) { | ||
1091 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1092 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1093 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1094 | } | ||
1095 | 1083 | ||
1096 | if (rinfo->bpp == 16) { | 1084 | if (rinfo->bpp == 16) { |
1097 | pindex = regno * 8; | 1085 | pindex = regno * 8; |
@@ -1101,24 +1089,27 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1101 | if (rinfo->depth == 15 && regno > 31) | 1089 | if (rinfo->depth == 15 && regno > 31) |
1102 | return 1; | 1090 | return 1; |
1103 | 1091 | ||
1104 | /* For 565, the green component is mixed one order below */ | 1092 | /* For 565, the green component is mixed one order |
1093 | * below | ||
1094 | */ | ||
1105 | if (rinfo->depth == 16) { | 1095 | if (rinfo->depth == 16) { |
1106 | OUTREG(PALETTE_INDEX, pindex>>1); | 1096 | OUTREG(PALETTE_INDEX, pindex>>1); |
1107 | OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) | | 1097 | OUTREG(PALETTE_DATA, |
1108 | (green << 8) | (rinfo->palette[regno>>1].blue)); | 1098 | (rinfo->palette[regno>>1].red << 16) | |
1099 | (green << 8) | | ||
1100 | (rinfo->palette[regno>>1].blue)); | ||
1109 | green = rinfo->palette[regno<<1].green; | 1101 | green = rinfo->palette[regno<<1].green; |
1110 | } | 1102 | } |
1111 | } | 1103 | } |
1112 | 1104 | ||
1113 | if (rinfo->depth != 16 || regno < 32) { | 1105 | if (rinfo->depth != 16 || regno < 32) { |
1114 | OUTREG(PALETTE_INDEX, pindex); | 1106 | OUTREG(PALETTE_INDEX, pindex); |
1115 | OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue); | 1107 | OUTREG(PALETTE_DATA, (red << 16) | |
1108 | (green << 8) | blue); | ||
1116 | } | 1109 | } |
1117 | if (rinfo->is_mobility) | ||
1118 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1119 | } | 1110 | } |
1120 | if (regno < 16) { | 1111 | if (regno < 16) { |
1121 | u32 *pal = info->pseudo_palette; | 1112 | u32 *pal = rinfo->info->pseudo_palette; |
1122 | switch (rinfo->depth) { | 1113 | switch (rinfo->depth) { |
1123 | case 15: | 1114 | case 15: |
1124 | pal[regno] = (regno << 10) | (regno << 5) | regno; | 1115 | pal[regno] = (regno << 10) | (regno << 5) | regno; |
@@ -1138,6 +1129,84 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1138 | return 0; | 1129 | return 0; |
1139 | } | 1130 | } |
1140 | 1131 | ||
1132 | static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | ||
1133 | unsigned blue, unsigned transp, | ||
1134 | struct fb_info *info) | ||
1135 | { | ||
1136 | struct radeonfb_info *rinfo = info->par; | ||
1137 | u32 dac_cntl2, vclk_cntl = 0; | ||
1138 | int rc; | ||
1139 | |||
1140 | if (!rinfo->asleep) { | ||
1141 | if (rinfo->is_mobility) { | ||
1142 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1143 | OUTPLL(VCLK_ECP_CNTL, | ||
1144 | vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1145 | } | ||
1146 | |||
1147 | /* Make sure we are on first palette */ | ||
1148 | if (rinfo->has_CRTC2) { | ||
1149 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1150 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1151 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | rc = radeon_setcolreg (regno, red, green, blue, transp, rinfo); | ||
1156 | |||
1157 | if (!rinfo->asleep && rinfo->is_mobility) | ||
1158 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1159 | |||
1160 | return rc; | ||
1161 | } | ||
1162 | |||
1163 | static int radeonfb_setcmap(struct fb_cmap *cmap, struct fb_info *info) | ||
1164 | { | ||
1165 | struct radeonfb_info *rinfo = info->par; | ||
1166 | u16 *red, *green, *blue, *transp; | ||
1167 | u32 dac_cntl2, vclk_cntl = 0; | ||
1168 | int i, start, rc = 0; | ||
1169 | |||
1170 | if (!rinfo->asleep) { | ||
1171 | if (rinfo->is_mobility) { | ||
1172 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1173 | OUTPLL(VCLK_ECP_CNTL, | ||
1174 | vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1175 | } | ||
1176 | |||
1177 | /* Make sure we are on first palette */ | ||
1178 | if (rinfo->has_CRTC2) { | ||
1179 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1180 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1181 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | red = cmap->red; | ||
1186 | green = cmap->green; | ||
1187 | blue = cmap->blue; | ||
1188 | transp = cmap->transp; | ||
1189 | start = cmap->start; | ||
1190 | |||
1191 | for (i = 0; i < cmap->len; i++) { | ||
1192 | u_int hred, hgreen, hblue, htransp = 0xffff; | ||
1193 | |||
1194 | hred = *red++; | ||
1195 | hgreen = *green++; | ||
1196 | hblue = *blue++; | ||
1197 | if (transp) | ||
1198 | htransp = *transp++; | ||
1199 | rc = radeon_setcolreg (start++, hred, hgreen, hblue, htransp, | ||
1200 | rinfo); | ||
1201 | if (rc) | ||
1202 | break; | ||
1203 | } | ||
1204 | |||
1205 | if (!rinfo->asleep && rinfo->is_mobility) | ||
1206 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1207 | |||
1208 | return rc; | ||
1209 | } | ||
1141 | 1210 | ||
1142 | static void radeon_save_state (struct radeonfb_info *rinfo, | 1211 | static void radeon_save_state (struct radeonfb_info *rinfo, |
1143 | struct radeon_regs *save) | 1212 | struct radeon_regs *save) |
@@ -1796,6 +1865,7 @@ static struct fb_ops radeonfb_ops = { | |||
1796 | .fb_check_var = radeonfb_check_var, | 1865 | .fb_check_var = radeonfb_check_var, |
1797 | .fb_set_par = radeonfb_set_par, | 1866 | .fb_set_par = radeonfb_set_par, |
1798 | .fb_setcolreg = radeonfb_setcolreg, | 1867 | .fb_setcolreg = radeonfb_setcolreg, |
1868 | .fb_setcmap = radeonfb_setcmap, | ||
1799 | .fb_pan_display = radeonfb_pan_display, | 1869 | .fb_pan_display = radeonfb_pan_display, |
1800 | .fb_blank = radeonfb_blank, | 1870 | .fb_blank = radeonfb_blank, |
1801 | .fb_ioctl = radeonfb_ioctl, | 1871 | .fb_ioctl = radeonfb_ioctl, |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 59e3b4b4e7e3..b209adbd508a 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -906,10 +906,13 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
906 | struct vc_data *svc = *default_mode; | 906 | struct vc_data *svc = *default_mode; |
907 | struct display *t, *p = &fb_display[vc->vc_num]; | 907 | struct display *t, *p = &fb_display[vc->vc_num]; |
908 | int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; | 908 | int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; |
909 | int cap = info->flags; | 909 | int cap; |
910 | 910 | ||
911 | if (info_idx == -1 || info == NULL) | 911 | if (info_idx == -1 || info == NULL) |
912 | return; | 912 | return; |
913 | |||
914 | cap = info->flags; | ||
915 | |||
913 | if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || | 916 | if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || |
914 | (info->fix.type == FB_TYPE_TEXT)) | 917 | (info->fix.type == FB_TYPE_TEXT)) |
915 | logo = 0; | 918 | logo = 0; |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 7d1ae06667c6..bcf59b28a14f 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -337,6 +337,8 @@ static void vgacon_init(struct vc_data *c, int init) | |||
337 | c->vc_scan_lines = vga_scan_lines; | 337 | c->vc_scan_lines = vga_scan_lines; |
338 | c->vc_font.height = vga_video_font_height; | 338 | c->vc_font.height = vga_video_font_height; |
339 | c->vc_complement_mask = 0x7700; | 339 | c->vc_complement_mask = 0x7700; |
340 | if (vga_512_chars) | ||
341 | c->vc_hi_font_mask = 0x0800; | ||
340 | p = *c->vc_uni_pagedir_loc; | 342 | p = *c->vc_uni_pagedir_loc; |
341 | if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir || | 343 | if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir || |
342 | !--c->vc_uni_pagedir_loc[1]) | 344 | !--c->vc_uni_pagedir_loc[1]) |
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index 8b1b7c687a99..3894b2a501d6 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c | |||
@@ -90,6 +90,8 @@ struct cfb_info { | |||
90 | */ | 90 | */ |
91 | u_char ramdac_ctrl; | 91 | u_char ramdac_ctrl; |
92 | u_char ramdac_powerdown; | 92 | u_char ramdac_powerdown; |
93 | |||
94 | u32 pseudo_palette[16]; | ||
93 | }; | 95 | }; |
94 | 96 | ||
95 | static char *default_font = "Acorn8x8"; | 97 | static char *default_font = "Acorn8x8"; |
@@ -1223,9 +1225,7 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) | |||
1223 | { | 1225 | { |
1224 | struct cfb_info *cfb; | 1226 | struct cfb_info *cfb; |
1225 | 1227 | ||
1226 | cfb = kmalloc(sizeof(struct cfb_info) + | 1228 | cfb = kmalloc(sizeof(struct cfb_info), GFP_KERNEL); |
1227 | sizeof(u32) * 16, GFP_KERNEL); | ||
1228 | |||
1229 | if (!cfb) | 1229 | if (!cfb) |
1230 | return NULL; | 1230 | return NULL; |
1231 | 1231 | ||
@@ -1281,7 +1281,7 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) | |||
1281 | 1281 | ||
1282 | cfb->fb.fbops = &cyber2000fb_ops; | 1282 | cfb->fb.fbops = &cyber2000fb_ops; |
1283 | cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 1283 | cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
1284 | cfb->fb.pseudo_palette = (void *)(cfb + 1); | 1284 | cfb->fb.pseudo_palette = cfb->pseudo_palette; |
1285 | 1285 | ||
1286 | fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); | 1286 | fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); |
1287 | 1287 | ||
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index c51f8fb5c1de..4e5ce8f7d65e 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c | |||
@@ -222,8 +222,11 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) | |||
222 | transp = cmap->transp; | 222 | transp = cmap->transp; |
223 | start = cmap->start; | 223 | start = cmap->start; |
224 | 224 | ||
225 | if (start < 0 || !info->fbops->fb_setcolreg) | 225 | if (start < 0 || (!info->fbops->fb_setcolreg && |
226 | !info->fbops->fb_setcmap)) | ||
226 | return -EINVAL; | 227 | return -EINVAL; |
228 | if (info->fbops->fb_setcmap) | ||
229 | return info->fbops->fb_setcmap(cmap, info); | ||
227 | for (i = 0; i < cmap->len; i++) { | 230 | for (i = 0; i < cmap->len; i++) { |
228 | hred = *red++; | 231 | hred = *red++; |
229 | hgreen = *green++; | 232 | hgreen = *green++; |
@@ -250,8 +253,33 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) | |||
250 | transp = cmap->transp; | 253 | transp = cmap->transp; |
251 | start = cmap->start; | 254 | start = cmap->start; |
252 | 255 | ||
253 | if (start < 0 || !info->fbops->fb_setcolreg) | 256 | if (start < 0 || (!info->fbops->fb_setcolreg && |
257 | !info->fbops->fb_setcmap)) | ||
254 | return -EINVAL; | 258 | return -EINVAL; |
259 | |||
260 | /* If we can batch, do it */ | ||
261 | if (info->fbops->fb_setcmap && cmap->len > 1) { | ||
262 | struct fb_cmap umap; | ||
263 | int size = cmap->len * sizeof(u16); | ||
264 | int rc; | ||
265 | |||
266 | memset(&umap, 0, sizeof(struct fb_cmap)); | ||
267 | rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL); | ||
268 | if (rc) | ||
269 | return rc; | ||
270 | if (copy_from_user(umap.red, red, size) || | ||
271 | copy_from_user(umap.green, green, size) || | ||
272 | copy_from_user(umap.blue, blue, size) || | ||
273 | (transp && copy_from_user(umap.transp, transp, size))) { | ||
274 | rc = -EFAULT; | ||
275 | } | ||
276 | umap.start = start; | ||
277 | if (rc == 0) | ||
278 | rc = info->fbops->fb_setcmap(&umap, info); | ||
279 | fb_dealloc_cmap(&umap); | ||
280 | return rc; | ||
281 | } | ||
282 | |||
255 | for (i = 0; i < cmap->len; i++, red++, blue++, green++) { | 283 | for (i = 0; i < cmap->len; i++, red++, blue++, green++) { |
256 | if (get_user(hred, red) || | 284 | if (get_user(hred, red) || |
257 | get_user(hgreen, green) || | 285 | get_user(hgreen, green) || |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 25f460ca0daf..208a68ceb63b 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1257,6 +1257,8 @@ int fb_new_modelist(struct fb_info *info) | |||
1257 | static char *video_options[FB_MAX]; | 1257 | static char *video_options[FB_MAX]; |
1258 | static int ofonly; | 1258 | static int ofonly; |
1259 | 1259 | ||
1260 | extern const char *global_mode_option; | ||
1261 | |||
1260 | /** | 1262 | /** |
1261 | * fb_get_options - get kernel boot parameters | 1263 | * fb_get_options - get kernel boot parameters |
1262 | * @name: framebuffer name as it would appear in | 1264 | * @name: framebuffer name as it would appear in |
@@ -1297,9 +1299,6 @@ int fb_get_options(char *name, char **option) | |||
1297 | return retval; | 1299 | return retval; |
1298 | } | 1300 | } |
1299 | 1301 | ||
1300 | |||
1301 | extern const char *global_mode_option; | ||
1302 | |||
1303 | /** | 1302 | /** |
1304 | * video_setup - process command line options | 1303 | * video_setup - process command line options |
1305 | * @options: string of options | 1304 | * @options: string of options |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 978def013587..6cd1976548d4 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
35 | #include <asm/pci-bridge.h> | 35 | #include <asm/pci-bridge.h> |
36 | #endif | 36 | #endif |
37 | #include <video/edid.h> | ||
38 | #include "edid.h" | 37 | #include "edid.h" |
39 | 38 | ||
40 | /* | 39 | /* |
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 9ec8781794c0..e04d3e8b2549 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -999,8 +999,14 @@ static int i810_check_params(struct fb_var_screeninfo *var, | |||
999 | info->monspecs.dclkmin = 15000000; | 999 | info->monspecs.dclkmin = 15000000; |
1000 | 1000 | ||
1001 | if (fb_validate_mode(var, info)) { | 1001 | if (fb_validate_mode(var, info)) { |
1002 | if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) | 1002 | if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) { |
1003 | int default_sync = (hsync1-HFMIN)|(hsync2-HFMAX) | ||
1004 | |(vsync1-VFMIN)|(vsync2-VFMAX); | ||
1005 | printk("i810fb: invalid video mode%s\n", | ||
1006 | default_sync ? "" : | ||
1007 | ". Specifying vsyncN/hsyncN parameters may help"); | ||
1003 | return -EINVAL; | 1008 | return -EINVAL; |
1009 | } | ||
1004 | } | 1010 | } |
1005 | 1011 | ||
1006 | var->xres = xres; | 1012 | var->xres = xres; |
@@ -2023,10 +2029,10 @@ MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines" | |||
2023 | " (default = 480)"); | 2029 | " (default = 480)"); |
2024 | module_param(hsync1, int, 0); | 2030 | module_param(hsync1, int, 0); |
2025 | MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz" | 2031 | MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz" |
2026 | " (default = 31)"); | 2032 | " (default = 29)"); |
2027 | module_param(hsync2, int, 0); | 2033 | module_param(hsync2, int, 0); |
2028 | MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz" | 2034 | MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz" |
2029 | " (default = 31)"); | 2035 | " (default = 30)"); |
2030 | module_param(vsync1, int, 0); | 2036 | module_param(vsync1, int, 0); |
2031 | MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz" | 2037 | MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz" |
2032 | " (default = 50)"); | 2038 | " (default = 50)"); |
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c new file mode 100644 index 000000000000..8fe1c12a17bd --- /dev/null +++ b/drivers/video/imxfb.c | |||
@@ -0,0 +1,695 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/imxfb.c | ||
3 | * | ||
4 | * Freescale i.MX Frame Buffer device driver | ||
5 | * | ||
6 | * Copyright (C) 2004 Sascha Hauer, Pengutronix | ||
7 | * Based on acornfb.c Copyright (C) Russell King. | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file COPYING in the main directory of this archive for | ||
11 | * more details. | ||
12 | * | ||
13 | * Please direct your questions and comments on this driver to the following | ||
14 | * email address: | ||
15 | * | ||
16 | * linux-arm-kernel@lists.arm.linux.org.uk | ||
17 | */ | ||
18 | |||
19 | //#define DEBUG 1 | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/string.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/fb.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/ioport.h> | ||
33 | #include <linux/cpufreq.h> | ||
34 | #include <linux/device.h> | ||
35 | #include <linux/dma-mapping.h> | ||
36 | |||
37 | #include <asm/hardware.h> | ||
38 | #include <asm/io.h> | ||
39 | #include <asm/mach-types.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | #include <asm/arch/imxfb.h> | ||
42 | |||
43 | /* | ||
44 | * Complain if VAR is out of range. | ||
45 | */ | ||
46 | #define DEBUG_VAR 1 | ||
47 | |||
48 | #include "imxfb.h" | ||
49 | |||
50 | static struct imxfb_rgb def_rgb_16 = { | ||
51 | .red = { .offset = 8, .length = 4, }, | ||
52 | .green = { .offset = 4, .length = 4, }, | ||
53 | .blue = { .offset = 0, .length = 4, }, | ||
54 | .transp = { .offset = 0, .length = 0, }, | ||
55 | }; | ||
56 | |||
57 | static struct imxfb_rgb def_rgb_8 = { | ||
58 | .red = { .offset = 0, .length = 8, }, | ||
59 | .green = { .offset = 0, .length = 8, }, | ||
60 | .blue = { .offset = 0, .length = 8, }, | ||
61 | .transp = { .offset = 0, .length = 0, }, | ||
62 | }; | ||
63 | |||
64 | static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info); | ||
65 | |||
66 | static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) | ||
67 | { | ||
68 | chan &= 0xffff; | ||
69 | chan >>= 16 - bf->length; | ||
70 | return chan << bf->offset; | ||
71 | } | ||
72 | |||
73 | #define LCDC_PALETTE(x) __REG2(IMX_LCDC_BASE+0x800, (x)<<2) | ||
74 | static int | ||
75 | imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, | ||
76 | u_int trans, struct fb_info *info) | ||
77 | { | ||
78 | struct imxfb_info *fbi = info->par; | ||
79 | u_int val, ret = 1; | ||
80 | |||
81 | #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) | ||
82 | if (regno < fbi->palette_size) { | ||
83 | val = (CNVT_TOHW(red, 4) << 8) | | ||
84 | (CNVT_TOHW(green,4) << 4) | | ||
85 | CNVT_TOHW(blue, 4); | ||
86 | |||
87 | LCDC_PALETTE(regno) = val; | ||
88 | ret = 0; | ||
89 | } | ||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | static int | ||
94 | imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
95 | u_int trans, struct fb_info *info) | ||
96 | { | ||
97 | struct imxfb_info *fbi = info->par; | ||
98 | unsigned int val; | ||
99 | int ret = 1; | ||
100 | |||
101 | /* | ||
102 | * If inverse mode was selected, invert all the colours | ||
103 | * rather than the register number. The register number | ||
104 | * is what you poke into the framebuffer to produce the | ||
105 | * colour you requested. | ||
106 | */ | ||
107 | if (fbi->cmap_inverse) { | ||
108 | red = 0xffff - red; | ||
109 | green = 0xffff - green; | ||
110 | blue = 0xffff - blue; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * If greyscale is true, then we convert the RGB value | ||
115 | * to greyscale no mater what visual we are using. | ||
116 | */ | ||
117 | if (info->var.grayscale) | ||
118 | red = green = blue = (19595 * red + 38470 * green + | ||
119 | 7471 * blue) >> 16; | ||
120 | |||
121 | switch (info->fix.visual) { | ||
122 | case FB_VISUAL_TRUECOLOR: | ||
123 | /* | ||
124 | * 12 or 16-bit True Colour. We encode the RGB value | ||
125 | * according to the RGB bitfield information. | ||
126 | */ | ||
127 | if (regno < 16) { | ||
128 | u32 *pal = info->pseudo_palette; | ||
129 | |||
130 | val = chan_to_field(red, &info->var.red); | ||
131 | val |= chan_to_field(green, &info->var.green); | ||
132 | val |= chan_to_field(blue, &info->var.blue); | ||
133 | |||
134 | pal[regno] = val; | ||
135 | ret = 0; | ||
136 | } | ||
137 | break; | ||
138 | |||
139 | case FB_VISUAL_STATIC_PSEUDOCOLOR: | ||
140 | case FB_VISUAL_PSEUDOCOLOR: | ||
141 | ret = imxfb_setpalettereg(regno, red, green, blue, trans, info); | ||
142 | break; | ||
143 | } | ||
144 | |||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * imxfb_check_var(): | ||
150 | * Round up in the following order: bits_per_pixel, xres, | ||
151 | * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, | ||
152 | * bitfields, horizontal timing, vertical timing. | ||
153 | */ | ||
154 | static int | ||
155 | imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
156 | { | ||
157 | struct imxfb_info *fbi = info->par; | ||
158 | int rgbidx; | ||
159 | |||
160 | if (var->xres < MIN_XRES) | ||
161 | var->xres = MIN_XRES; | ||
162 | if (var->yres < MIN_YRES) | ||
163 | var->yres = MIN_YRES; | ||
164 | if (var->xres > fbi->max_xres) | ||
165 | var->xres = fbi->max_xres; | ||
166 | if (var->yres > fbi->max_yres) | ||
167 | var->yres = fbi->max_yres; | ||
168 | var->xres_virtual = max(var->xres_virtual, var->xres); | ||
169 | var->yres_virtual = max(var->yres_virtual, var->yres); | ||
170 | |||
171 | pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); | ||
172 | switch (var->bits_per_pixel) { | ||
173 | case 16: | ||
174 | rgbidx = RGB_16; | ||
175 | break; | ||
176 | case 8: | ||
177 | rgbidx = RGB_8; | ||
178 | break; | ||
179 | default: | ||
180 | rgbidx = RGB_16; | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * Copy the RGB parameters for this display | ||
185 | * from the machine specific parameters. | ||
186 | */ | ||
187 | var->red = fbi->rgb[rgbidx]->red; | ||
188 | var->green = fbi->rgb[rgbidx]->green; | ||
189 | var->blue = fbi->rgb[rgbidx]->blue; | ||
190 | var->transp = fbi->rgb[rgbidx]->transp; | ||
191 | |||
192 | pr_debug("RGBT length = %d:%d:%d:%d\n", | ||
193 | var->red.length, var->green.length, var->blue.length, | ||
194 | var->transp.length); | ||
195 | |||
196 | pr_debug("RGBT offset = %d:%d:%d:%d\n", | ||
197 | var->red.offset, var->green.offset, var->blue.offset, | ||
198 | var->transp.offset); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * imxfb_set_par(): | ||
205 | * Set the user defined part of the display for the specified console | ||
206 | */ | ||
207 | static int imxfb_set_par(struct fb_info *info) | ||
208 | { | ||
209 | struct imxfb_info *fbi = info->par; | ||
210 | struct fb_var_screeninfo *var = &info->var; | ||
211 | |||
212 | pr_debug("set_par\n"); | ||
213 | |||
214 | if (var->bits_per_pixel == 16) | ||
215 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
216 | else if (!fbi->cmap_static) | ||
217 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
218 | else { | ||
219 | /* | ||
220 | * Some people have weird ideas about wanting static | ||
221 | * pseudocolor maps. I suspect their user space | ||
222 | * applications are broken. | ||
223 | */ | ||
224 | info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; | ||
225 | } | ||
226 | |||
227 | info->fix.line_length = var->xres_virtual * | ||
228 | var->bits_per_pixel / 8; | ||
229 | fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; | ||
230 | |||
231 | imxfb_activate_var(var, info); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static void imxfb_enable_controller(struct imxfb_info *fbi) | ||
237 | { | ||
238 | pr_debug("Enabling LCD controller\n"); | ||
239 | |||
240 | /* initialize LCDC */ | ||
241 | LCDC_RMCR &= ~RMCR_LCDC_EN; /* just to be safe... */ | ||
242 | |||
243 | LCDC_SSA = fbi->screen_dma; | ||
244 | /* physical screen start address */ | ||
245 | LCDC_VPW = VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4); | ||
246 | |||
247 | LCDC_POS = 0x00000000; /* panning offset 0 (0 pixel offset) */ | ||
248 | |||
249 | /* disable hardware cursor */ | ||
250 | LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1); | ||
251 | |||
252 | /* fixed burst length (see erratum 11) */ | ||
253 | LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2); | ||
254 | |||
255 | LCDC_RMCR = RMCR_LCDC_EN; | ||
256 | |||
257 | if(fbi->backlight_power) | ||
258 | fbi->backlight_power(1); | ||
259 | if(fbi->lcd_power) | ||
260 | fbi->lcd_power(1); | ||
261 | } | ||
262 | |||
263 | static void imxfb_disable_controller(struct imxfb_info *fbi) | ||
264 | { | ||
265 | pr_debug("Disabling LCD controller\n"); | ||
266 | |||
267 | if(fbi->backlight_power) | ||
268 | fbi->backlight_power(0); | ||
269 | if(fbi->lcd_power) | ||
270 | fbi->lcd_power(0); | ||
271 | |||
272 | LCDC_RMCR = 0; | ||
273 | } | ||
274 | |||
275 | static int imxfb_blank(int blank, struct fb_info *info) | ||
276 | { | ||
277 | struct imxfb_info *fbi = info->par; | ||
278 | |||
279 | pr_debug("imxfb_blank: blank=%d\n", blank); | ||
280 | |||
281 | switch (blank) { | ||
282 | case FB_BLANK_POWERDOWN: | ||
283 | case FB_BLANK_VSYNC_SUSPEND: | ||
284 | case FB_BLANK_HSYNC_SUSPEND: | ||
285 | case FB_BLANK_NORMAL: | ||
286 | imxfb_disable_controller(fbi); | ||
287 | break; | ||
288 | |||
289 | case FB_BLANK_UNBLANK: | ||
290 | imxfb_enable_controller(fbi); | ||
291 | break; | ||
292 | } | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static struct fb_ops imxfb_ops = { | ||
297 | .owner = THIS_MODULE, | ||
298 | .fb_check_var = imxfb_check_var, | ||
299 | .fb_set_par = imxfb_set_par, | ||
300 | .fb_setcolreg = imxfb_setcolreg, | ||
301 | .fb_fillrect = cfb_fillrect, | ||
302 | .fb_copyarea = cfb_copyarea, | ||
303 | .fb_imageblit = cfb_imageblit, | ||
304 | .fb_blank = imxfb_blank, | ||
305 | .fb_cursor = soft_cursor, /* FIXME: i.MX can do hardware cursor */ | ||
306 | }; | ||
307 | |||
308 | /* | ||
309 | * imxfb_activate_var(): | ||
310 | * Configures LCD Controller based on entries in var parameter. Settings are | ||
311 | * only written to the controller if changes were made. | ||
312 | */ | ||
313 | static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
314 | { | ||
315 | struct imxfb_info *fbi = info->par; | ||
316 | pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", | ||
317 | var->xres, var->hsync_len, | ||
318 | var->left_margin, var->right_margin); | ||
319 | pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n", | ||
320 | var->yres, var->vsync_len, | ||
321 | var->upper_margin, var->lower_margin); | ||
322 | |||
323 | #if DEBUG_VAR | ||
324 | if (var->xres < 16 || var->xres > 1024) | ||
325 | printk(KERN_ERR "%s: invalid xres %d\n", | ||
326 | info->fix.id, var->xres); | ||
327 | if (var->hsync_len < 1 || var->hsync_len > 64) | ||
328 | printk(KERN_ERR "%s: invalid hsync_len %d\n", | ||
329 | info->fix.id, var->hsync_len); | ||
330 | if (var->left_margin > 255) | ||
331 | printk(KERN_ERR "%s: invalid left_margin %d\n", | ||
332 | info->fix.id, var->left_margin); | ||
333 | if (var->right_margin > 255) | ||
334 | printk(KERN_ERR "%s: invalid right_margin %d\n", | ||
335 | info->fix.id, var->right_margin); | ||
336 | if (var->yres < 1 || var->yres > 511) | ||
337 | printk(KERN_ERR "%s: invalid yres %d\n", | ||
338 | info->fix.id, var->yres); | ||
339 | if (var->vsync_len > 100) | ||
340 | printk(KERN_ERR "%s: invalid vsync_len %d\n", | ||
341 | info->fix.id, var->vsync_len); | ||
342 | if (var->upper_margin > 63) | ||
343 | printk(KERN_ERR "%s: invalid upper_margin %d\n", | ||
344 | info->fix.id, var->upper_margin); | ||
345 | if (var->lower_margin > 255) | ||
346 | printk(KERN_ERR "%s: invalid lower_margin %d\n", | ||
347 | info->fix.id, var->lower_margin); | ||
348 | #endif | ||
349 | |||
350 | LCDC_HCR = HCR_H_WIDTH(var->hsync_len) | | ||
351 | HCR_H_WAIT_1(var->left_margin) | | ||
352 | HCR_H_WAIT_2(var->right_margin); | ||
353 | |||
354 | LCDC_VCR = VCR_V_WIDTH(var->vsync_len) | | ||
355 | VCR_V_WAIT_1(var->upper_margin) | | ||
356 | VCR_V_WAIT_2(var->lower_margin); | ||
357 | |||
358 | LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres); | ||
359 | LCDC_PCR = fbi->pcr; | ||
360 | LCDC_PWMR = fbi->pwmr; | ||
361 | LCDC_LSCR1 = fbi->lscr1; | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static void imxfb_setup_gpio(struct imxfb_info *fbi) | ||
367 | { | ||
368 | int width; | ||
369 | |||
370 | LCDC_RMCR &= ~(RMCR_LCDC_EN | RMCR_SELF_REF); | ||
371 | |||
372 | if( fbi->pcr & PCR_TFT ) | ||
373 | width = 16; | ||
374 | else | ||
375 | width = 1 << ((fbi->pcr >> 28) & 0x3); | ||
376 | |||
377 | switch(width) { | ||
378 | case 16: | ||
379 | imx_gpio_mode(PD30_PF_LD15); | ||
380 | imx_gpio_mode(PD29_PF_LD14); | ||
381 | imx_gpio_mode(PD28_PF_LD13); | ||
382 | imx_gpio_mode(PD27_PF_LD12); | ||
383 | imx_gpio_mode(PD26_PF_LD11); | ||
384 | imx_gpio_mode(PD25_PF_LD10); | ||
385 | imx_gpio_mode(PD24_PF_LD9); | ||
386 | imx_gpio_mode(PD23_PF_LD8); | ||
387 | case 8: | ||
388 | imx_gpio_mode(PD22_PF_LD7); | ||
389 | imx_gpio_mode(PD21_PF_LD6); | ||
390 | imx_gpio_mode(PD20_PF_LD5); | ||
391 | imx_gpio_mode(PD19_PF_LD4); | ||
392 | case 4: | ||
393 | imx_gpio_mode(PD18_PF_LD3); | ||
394 | imx_gpio_mode(PD17_PF_LD2); | ||
395 | case 2: | ||
396 | imx_gpio_mode(PD16_PF_LD1); | ||
397 | case 1: | ||
398 | imx_gpio_mode(PD15_PF_LD0); | ||
399 | } | ||
400 | |||
401 | /* initialize GPIOs */ | ||
402 | imx_gpio_mode(PD6_PF_LSCLK); | ||
403 | imx_gpio_mode(PD10_PF_SPL_SPR); | ||
404 | imx_gpio_mode(PD11_PF_CONTRAST); | ||
405 | imx_gpio_mode(PD14_PF_FLM_VSYNC); | ||
406 | imx_gpio_mode(PD13_PF_LP_HSYNC); | ||
407 | imx_gpio_mode(PD7_PF_REV); | ||
408 | imx_gpio_mode(PD8_PF_CLS); | ||
409 | |||
410 | #ifndef CONFIG_MACH_PIMX1 | ||
411 | /* on PiMX1 used as buffers enable signal | ||
412 | */ | ||
413 | imx_gpio_mode(PD9_PF_PS); | ||
414 | #endif | ||
415 | |||
416 | #ifndef CONFIG_MACH_MX1FS2 | ||
417 | /* on mx1fs2 this pin is used to (de)activate the display, so we need | ||
418 | * it as a normal gpio | ||
419 | */ | ||
420 | imx_gpio_mode(PD12_PF_ACD_OE); | ||
421 | #endif | ||
422 | |||
423 | } | ||
424 | |||
425 | #ifdef CONFIG_PM | ||
426 | /* | ||
427 | * Power management hooks. Note that we won't be called from IRQ context, | ||
428 | * unlike the blank functions above, so we may sleep. | ||
429 | */ | ||
430 | static int imxfb_suspend(struct device *dev, u32 state, u32 level) | ||
431 | { | ||
432 | struct imxfb_info *fbi = dev_get_drvdata(dev); | ||
433 | pr_debug("%s\n",__FUNCTION__); | ||
434 | |||
435 | if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) | ||
436 | imxfb_disable_controller(fbi); | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | static int imxfb_resume(struct device *dev, u32 level) | ||
441 | { | ||
442 | struct imxfb_info *fbi = dev_get_drvdata(dev); | ||
443 | pr_debug("%s\n",__FUNCTION__); | ||
444 | |||
445 | if (level == RESUME_ENABLE) | ||
446 | imxfb_enable_controller(fbi); | ||
447 | return 0; | ||
448 | } | ||
449 | #else | ||
450 | #define imxfb_suspend NULL | ||
451 | #define imxfb_resume NULL | ||
452 | #endif | ||
453 | |||
454 | static int __init imxfb_init_fbinfo(struct device *dev) | ||
455 | { | ||
456 | struct imxfb_mach_info *inf = dev->platform_data; | ||
457 | struct fb_info *info = dev_get_drvdata(dev); | ||
458 | struct imxfb_info *fbi = info->par; | ||
459 | |||
460 | pr_debug("%s\n",__FUNCTION__); | ||
461 | |||
462 | info->pseudo_palette = kmalloc( sizeof(u32) * 16, GFP_KERNEL); | ||
463 | if (!info->pseudo_palette) | ||
464 | return -ENOMEM; | ||
465 | |||
466 | memset(fbi, 0, sizeof(struct imxfb_info)); | ||
467 | fbi->dev = dev; | ||
468 | |||
469 | strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id)); | ||
470 | |||
471 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
472 | info->fix.type_aux = 0; | ||
473 | info->fix.xpanstep = 0; | ||
474 | info->fix.ypanstep = 0; | ||
475 | info->fix.ywrapstep = 0; | ||
476 | info->fix.accel = FB_ACCEL_NONE; | ||
477 | |||
478 | info->var.nonstd = 0; | ||
479 | info->var.activate = FB_ACTIVATE_NOW; | ||
480 | info->var.height = -1; | ||
481 | info->var.width = -1; | ||
482 | info->var.accel_flags = 0; | ||
483 | info->var.vmode = FB_VMODE_NONINTERLACED; | ||
484 | |||
485 | info->fbops = &imxfb_ops; | ||
486 | info->flags = FBINFO_FLAG_DEFAULT; | ||
487 | info->pseudo_palette = (fbi + 1); | ||
488 | |||
489 | fbi->rgb[RGB_16] = &def_rgb_16; | ||
490 | fbi->rgb[RGB_8] = &def_rgb_8; | ||
491 | |||
492 | fbi->max_xres = inf->xres; | ||
493 | info->var.xres = inf->xres; | ||
494 | info->var.xres_virtual = inf->xres; | ||
495 | fbi->max_yres = inf->yres; | ||
496 | info->var.yres = inf->yres; | ||
497 | info->var.yres_virtual = inf->yres; | ||
498 | fbi->max_bpp = inf->bpp; | ||
499 | info->var.bits_per_pixel = inf->bpp; | ||
500 | info->var.pixclock = inf->pixclock; | ||
501 | info->var.hsync_len = inf->hsync_len; | ||
502 | info->var.left_margin = inf->left_margin; | ||
503 | info->var.right_margin = inf->right_margin; | ||
504 | info->var.vsync_len = inf->vsync_len; | ||
505 | info->var.upper_margin = inf->upper_margin; | ||
506 | info->var.lower_margin = inf->lower_margin; | ||
507 | info->var.sync = inf->sync; | ||
508 | info->var.grayscale = inf->cmap_greyscale; | ||
509 | fbi->cmap_inverse = inf->cmap_inverse; | ||
510 | fbi->pcr = inf->pcr; | ||
511 | fbi->lscr1 = inf->lscr1; | ||
512 | fbi->pwmr = inf->pwmr; | ||
513 | fbi->lcd_power = inf->lcd_power; | ||
514 | fbi->backlight_power = inf->backlight_power; | ||
515 | info->fix.smem_len = fbi->max_xres * fbi->max_yres * | ||
516 | fbi->max_bpp / 8; | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * Allocates the DRAM memory for the frame buffer. This buffer is | ||
523 | * remapped into a non-cached, non-buffered, memory region to | ||
524 | * allow pixel writes to occur without flushing the cache. | ||
525 | * Once this area is remapped, all virtual memory access to the | ||
526 | * video memory should occur at the new region. | ||
527 | */ | ||
528 | static int __init imxfb_map_video_memory(struct fb_info *info) | ||
529 | { | ||
530 | struct imxfb_info *fbi = info->par; | ||
531 | |||
532 | fbi->map_size = PAGE_ALIGN(info->fix.smem_len); | ||
533 | fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size, | ||
534 | &fbi->map_dma,GFP_KERNEL); | ||
535 | |||
536 | if (fbi->map_cpu) { | ||
537 | info->screen_base = fbi->map_cpu; | ||
538 | fbi->screen_cpu = fbi->map_cpu; | ||
539 | fbi->screen_dma = fbi->map_dma; | ||
540 | info->fix.smem_start = fbi->screen_dma; | ||
541 | } | ||
542 | |||
543 | return fbi->map_cpu ? 0 : -ENOMEM; | ||
544 | } | ||
545 | |||
546 | static int __init imxfb_probe(struct device *dev) | ||
547 | { | ||
548 | struct platform_device *pdev = to_platform_device(dev); | ||
549 | struct imxfb_info *fbi; | ||
550 | struct fb_info *info; | ||
551 | struct imxfb_mach_info *inf; | ||
552 | struct resource *res; | ||
553 | int ret; | ||
554 | |||
555 | printk("i.MX Framebuffer driver\n"); | ||
556 | |||
557 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
558 | if(!res) | ||
559 | return -ENODEV; | ||
560 | |||
561 | inf = dev->platform_data; | ||
562 | if(!inf) { | ||
563 | dev_err(dev,"No platform_data available\n"); | ||
564 | return -ENOMEM; | ||
565 | } | ||
566 | |||
567 | info = framebuffer_alloc(sizeof(struct imxfb_info), dev); | ||
568 | if(!info) | ||
569 | return -ENOMEM; | ||
570 | |||
571 | fbi = info->par; | ||
572 | |||
573 | dev_set_drvdata(dev, info); | ||
574 | |||
575 | ret = imxfb_init_fbinfo(dev); | ||
576 | if( ret < 0 ) | ||
577 | goto failed_init; | ||
578 | |||
579 | res = request_mem_region(res->start, res->end - res->start + 1, "IMXFB"); | ||
580 | if (!res) { | ||
581 | ret = -EBUSY; | ||
582 | goto failed_regs; | ||
583 | } | ||
584 | |||
585 | if (!inf->fixed_screen_cpu) { | ||
586 | ret = imxfb_map_video_memory(info); | ||
587 | if (ret) { | ||
588 | dev_err(dev, "Failed to allocate video RAM: %d\n", ret); | ||
589 | ret = -ENOMEM; | ||
590 | goto failed_map; | ||
591 | } | ||
592 | } else { | ||
593 | /* Fixed framebuffer mapping enables location of the screen in eSRAM */ | ||
594 | fbi->map_cpu = inf->fixed_screen_cpu; | ||
595 | fbi->map_dma = inf->fixed_screen_dma; | ||
596 | info->screen_base = fbi->map_cpu; | ||
597 | fbi->screen_cpu = fbi->map_cpu; | ||
598 | fbi->screen_dma = fbi->map_dma; | ||
599 | info->fix.smem_start = fbi->screen_dma; | ||
600 | } | ||
601 | |||
602 | /* | ||
603 | * This makes sure that our colour bitfield | ||
604 | * descriptors are correctly initialised. | ||
605 | */ | ||
606 | imxfb_check_var(&info->var, info); | ||
607 | |||
608 | ret = fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); | ||
609 | if (ret < 0) | ||
610 | goto failed_cmap; | ||
611 | |||
612 | imxfb_setup_gpio(fbi); | ||
613 | |||
614 | imxfb_set_par(info); | ||
615 | ret = register_framebuffer(info); | ||
616 | if (ret < 0) { | ||
617 | dev_err(dev, "failed to register framebuffer\n"); | ||
618 | goto failed_register; | ||
619 | } | ||
620 | |||
621 | imxfb_enable_controller(fbi); | ||
622 | |||
623 | return 0; | ||
624 | |||
625 | failed_register: | ||
626 | fb_dealloc_cmap(&info->cmap); | ||
627 | failed_cmap: | ||
628 | if (!inf->fixed_screen_cpu) | ||
629 | dma_free_writecombine(dev,fbi->map_size,fbi->map_cpu, | ||
630 | fbi->map_dma); | ||
631 | failed_map: | ||
632 | kfree(info->pseudo_palette); | ||
633 | failed_regs: | ||
634 | release_mem_region(res->start, res->end - res->start); | ||
635 | failed_init: | ||
636 | dev_set_drvdata(dev, NULL); | ||
637 | framebuffer_release(info); | ||
638 | return ret; | ||
639 | } | ||
640 | |||
641 | static int imxfb_remove(struct device *dev) | ||
642 | { | ||
643 | struct platform_device *pdev = to_platform_device(dev); | ||
644 | struct fb_info *info = dev_get_drvdata(dev); | ||
645 | struct resource *res; | ||
646 | |||
647 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
648 | |||
649 | /* disable LCD controller */ | ||
650 | LCDC_RMCR &= ~RMCR_LCDC_EN; | ||
651 | |||
652 | unregister_framebuffer(info); | ||
653 | |||
654 | fb_dealloc_cmap(&info->cmap); | ||
655 | kfree(info->pseudo_palette); | ||
656 | framebuffer_release(info); | ||
657 | |||
658 | release_mem_region(res->start, res->end - res->start + 1); | ||
659 | dev_set_drvdata(dev, NULL); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | void imxfb_shutdown(struct device * dev) | ||
665 | { | ||
666 | /* disable LCD Controller */ | ||
667 | LCDC_RMCR &= ~RMCR_LCDC_EN; | ||
668 | } | ||
669 | |||
670 | static struct device_driver imxfb_driver = { | ||
671 | .name = "imx-fb", | ||
672 | .bus = &platform_bus_type, | ||
673 | .probe = imxfb_probe, | ||
674 | .suspend = imxfb_suspend, | ||
675 | .resume = imxfb_resume, | ||
676 | .remove = imxfb_remove, | ||
677 | .shutdown = imxfb_shutdown, | ||
678 | }; | ||
679 | |||
680 | int __init imxfb_init(void) | ||
681 | { | ||
682 | return driver_register(&imxfb_driver); | ||
683 | } | ||
684 | |||
685 | static void __exit imxfb_cleanup(void) | ||
686 | { | ||
687 | driver_unregister(&imxfb_driver); | ||
688 | } | ||
689 | |||
690 | module_init(imxfb_init); | ||
691 | module_exit(imxfb_cleanup); | ||
692 | |||
693 | MODULE_DESCRIPTION("Motorola i.MX framebuffer driver"); | ||
694 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | ||
695 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h new file mode 100644 index 000000000000..128c3ee515c7 --- /dev/null +++ b/drivers/video/imxfb.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/imxfb.h | ||
3 | * | ||
4 | * Freescale i.MX Frame Buffer device driver | ||
5 | * | ||
6 | * Copyright (C) 2004 S.Hauer, Pengutronix | ||
7 | * | ||
8 | * Copyright (C) 1999 Eric A. Thomas | ||
9 | * Based on acornfb.c Copyright (C) Russell King. | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file COPYING in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * These are the bitfields for each | ||
18 | * display depth that we support. | ||
19 | */ | ||
20 | struct imxfb_rgb { | ||
21 | struct fb_bitfield red; | ||
22 | struct fb_bitfield green; | ||
23 | struct fb_bitfield blue; | ||
24 | struct fb_bitfield transp; | ||
25 | }; | ||
26 | |||
27 | #define RGB_16 (0) | ||
28 | #define RGB_8 (1) | ||
29 | #define NR_RGB 2 | ||
30 | |||
31 | struct imxfb_info { | ||
32 | struct device *dev; | ||
33 | struct imxfb_rgb *rgb[NR_RGB]; | ||
34 | |||
35 | u_int max_bpp; | ||
36 | u_int max_xres; | ||
37 | u_int max_yres; | ||
38 | |||
39 | /* | ||
40 | * These are the addresses we mapped | ||
41 | * the framebuffer memory region to. | ||
42 | */ | ||
43 | dma_addr_t map_dma; | ||
44 | u_char * map_cpu; | ||
45 | u_int map_size; | ||
46 | |||
47 | u_char * screen_cpu; | ||
48 | dma_addr_t screen_dma; | ||
49 | u_int palette_size; | ||
50 | |||
51 | dma_addr_t dbar1; | ||
52 | dma_addr_t dbar2; | ||
53 | |||
54 | u_int pcr; | ||
55 | u_int pwmr; | ||
56 | u_int lscr1; | ||
57 | u_int cmap_inverse:1, | ||
58 | cmap_static:1, | ||
59 | unused:30; | ||
60 | |||
61 | void (*lcd_power)(int); | ||
62 | void (*backlight_power)(int); | ||
63 | }; | ||
64 | |||
65 | #define IMX_NAME "IMX" | ||
66 | |||
67 | /* | ||
68 | * Minimum X and Y resolutions | ||
69 | */ | ||
70 | #define MIN_XRES 64 | ||
71 | #define MIN_YRES 64 | ||
72 | |||
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 6a05b7000830..549e22939260 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -135,9 +135,45 @@ | |||
135 | #endif | 135 | #endif |
136 | 136 | ||
137 | #include "intelfb.h" | 137 | #include "intelfb.h" |
138 | #include "intelfbdrv.h" | ||
139 | #include "intelfbhw.h" | 138 | #include "intelfbhw.h" |
140 | 139 | ||
140 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); | ||
141 | static void update_dinfo(struct intelfb_info *dinfo, | ||
142 | struct fb_var_screeninfo *var); | ||
143 | static int intelfb_get_fix(struct fb_fix_screeninfo *fix, | ||
144 | struct fb_info *info); | ||
145 | |||
146 | static int intelfb_check_var(struct fb_var_screeninfo *var, | ||
147 | struct fb_info *info); | ||
148 | static int intelfb_set_par(struct fb_info *info); | ||
149 | static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
150 | unsigned blue, unsigned transp, | ||
151 | struct fb_info *info); | ||
152 | |||
153 | static int intelfb_blank(int blank, struct fb_info *info); | ||
154 | static int intelfb_pan_display(struct fb_var_screeninfo *var, | ||
155 | struct fb_info *info); | ||
156 | |||
157 | static void intelfb_fillrect(struct fb_info *info, | ||
158 | const struct fb_fillrect *rect); | ||
159 | static void intelfb_copyarea(struct fb_info *info, | ||
160 | const struct fb_copyarea *region); | ||
161 | static void intelfb_imageblit(struct fb_info *info, | ||
162 | const struct fb_image *image); | ||
163 | static int intelfb_cursor(struct fb_info *info, | ||
164 | struct fb_cursor *cursor); | ||
165 | |||
166 | static int intelfb_sync(struct fb_info *info); | ||
167 | |||
168 | static int intelfb_ioctl(struct inode *inode, struct file *file, | ||
169 | unsigned int cmd, unsigned long arg, | ||
170 | struct fb_info *info); | ||
171 | |||
172 | static int __devinit intelfb_pci_register(struct pci_dev *pdev, | ||
173 | const struct pci_device_id *ent); | ||
174 | static void __devexit intelfb_pci_unregister(struct pci_dev *pdev); | ||
175 | static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo); | ||
176 | |||
141 | /* | 177 | /* |
142 | * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the | 178 | * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the |
143 | * mobile chipsets from being registered. | 179 | * mobile chipsets from being registered. |
diff --git a/drivers/video/intelfb/intelfbdrv.h b/drivers/video/intelfb/intelfbdrv.h deleted file mode 100644 index cc3058128884..000000000000 --- a/drivers/video/intelfb/intelfbdrv.h +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | #ifndef _INTELFBDRV_H | ||
2 | #define _INTELFBDRV_H | ||
3 | |||
4 | /* | ||
5 | ****************************************************************************** | ||
6 | * intelfb | ||
7 | * | ||
8 | * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G | ||
9 | * integrated graphics chips. | ||
10 | * | ||
11 | * Copyright © 2004 Sylvain Meyer | ||
12 | * | ||
13 | * Author: Sylvain Meyer | ||
14 | * | ||
15 | ****************************************************************************** | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); | ||
32 | static void update_dinfo(struct intelfb_info *dinfo, | ||
33 | struct fb_var_screeninfo *var); | ||
34 | static int intelfb_get_fix(struct fb_fix_screeninfo *fix, | ||
35 | struct fb_info *info); | ||
36 | |||
37 | static int intelfb_check_var(struct fb_var_screeninfo *var, | ||
38 | struct fb_info *info); | ||
39 | static int intelfb_set_par(struct fb_info *info); | ||
40 | static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
41 | unsigned blue, unsigned transp, | ||
42 | struct fb_info *info); | ||
43 | |||
44 | static int intelfb_blank(int blank, struct fb_info *info); | ||
45 | static int intelfb_pan_display(struct fb_var_screeninfo *var, | ||
46 | struct fb_info *info); | ||
47 | |||
48 | static void intelfb_fillrect(struct fb_info *info, | ||
49 | const struct fb_fillrect *rect); | ||
50 | static void intelfb_copyarea(struct fb_info *info, | ||
51 | const struct fb_copyarea *region); | ||
52 | static void intelfb_imageblit(struct fb_info *info, | ||
53 | const struct fb_image *image); | ||
54 | static int intelfb_cursor(struct fb_info *info, | ||
55 | struct fb_cursor *cursor); | ||
56 | |||
57 | static int intelfb_sync(struct fb_info *info); | ||
58 | |||
59 | static int intelfb_ioctl(struct inode *inode, struct file *file, | ||
60 | unsigned int cmd, unsigned long arg, | ||
61 | struct fb_info *info); | ||
62 | |||
63 | static int __devinit intelfb_pci_register(struct pci_dev *pdev, | ||
64 | const struct pci_device_id *ent); | ||
65 | static void __devexit intelfb_pci_unregister(struct pci_dev *pdev); | ||
66 | static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo); | ||
67 | |||
68 | #endif | ||
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 3a6555a8aaa2..47733f58153b 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -408,6 +408,7 @@ static int hwcur __devinitdata = 0; | |||
408 | static int noaccel __devinitdata = 0; | 408 | static int noaccel __devinitdata = 0; |
409 | static int noscale __devinitdata = 0; | 409 | static int noscale __devinitdata = 0; |
410 | static int paneltweak __devinitdata = 0; | 410 | static int paneltweak __devinitdata = 0; |
411 | static int vram __devinitdata = 0; | ||
411 | #ifdef CONFIG_MTRR | 412 | #ifdef CONFIG_MTRR |
412 | static int nomtrr __devinitdata = 0; | 413 | static int nomtrr __devinitdata = 0; |
413 | #endif | 414 | #endif |
@@ -1180,7 +1181,7 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var, | |||
1180 | 1181 | ||
1181 | var->xres_virtual = (var->xres_virtual + 63) & ~63; | 1182 | var->xres_virtual = (var->xres_virtual + 63) & ~63; |
1182 | 1183 | ||
1183 | vramlen = info->fix.smem_len; | 1184 | vramlen = info->screen_size; |
1184 | pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8; | 1185 | pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8; |
1185 | memlen = pitch * var->yres_virtual; | 1186 | memlen = pitch * var->yres_virtual; |
1186 | 1187 | ||
@@ -1343,7 +1344,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) | |||
1343 | /* maximize virtual vertical length */ | 1344 | /* maximize virtual vertical length */ |
1344 | lpitch = info->var.xres_virtual * | 1345 | lpitch = info->var.xres_virtual * |
1345 | ((info->var.bits_per_pixel + 7) >> 3); | 1346 | ((info->var.bits_per_pixel + 7) >> 3); |
1346 | info->var.yres_virtual = info->fix.smem_len / lpitch; | 1347 | info->var.yres_virtual = info->screen_size / lpitch; |
1347 | 1348 | ||
1348 | info->pixmap.scan_align = 4; | 1349 | info->pixmap.scan_align = 4; |
1349 | info->pixmap.buf_align = 4; | 1350 | info->pixmap.buf_align = 4; |
@@ -1507,12 +1508,20 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1507 | 1508 | ||
1508 | par->FbAddress = nvidiafb_fix.smem_start; | 1509 | par->FbAddress = nvidiafb_fix.smem_start; |
1509 | par->FbMapSize = par->RamAmountKBytes * 1024; | 1510 | par->FbMapSize = par->RamAmountKBytes * 1024; |
1511 | if (vram && vram * 1024 * 1024 < par->FbMapSize) | ||
1512 | par->FbMapSize = vram * 1024 * 1024; | ||
1513 | |||
1514 | /* Limit amount of vram to 64 MB */ | ||
1515 | if (par->FbMapSize > 64 * 1024 * 1024) | ||
1516 | par->FbMapSize = 64 * 1024 * 1024; | ||
1517 | |||
1510 | par->FbUsableSize = par->FbMapSize - (128 * 1024); | 1518 | par->FbUsableSize = par->FbMapSize - (128 * 1024); |
1511 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : | 1519 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : |
1512 | 16 * 1024; | 1520 | 16 * 1024; |
1513 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; | 1521 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; |
1514 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); | 1522 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); |
1515 | nvidiafb_fix.smem_len = par->FbUsableSize; | 1523 | info->screen_size = par->FbUsableSize; |
1524 | nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; | ||
1516 | 1525 | ||
1517 | if (!info->screen_base) { | 1526 | if (!info->screen_base) { |
1518 | printk(KERN_ERR PFX "cannot ioremap FB base\n"); | 1527 | printk(KERN_ERR PFX "cannot ioremap FB base\n"); |
@@ -1524,7 +1533,8 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1524 | #ifdef CONFIG_MTRR | 1533 | #ifdef CONFIG_MTRR |
1525 | if (!nomtrr) { | 1534 | if (!nomtrr) { |
1526 | par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start, | 1535 | par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start, |
1527 | par->FbMapSize, MTRR_TYPE_WRCOMB, 1); | 1536 | par->RamAmountKBytes * 1024, |
1537 | MTRR_TYPE_WRCOMB, 1); | ||
1528 | if (par->mtrr.vram < 0) { | 1538 | if (par->mtrr.vram < 0) { |
1529 | printk(KERN_ERR PFX "unable to setup MTRR\n"); | 1539 | printk(KERN_ERR PFX "unable to setup MTRR\n"); |
1530 | } else { | 1540 | } else { |
@@ -1566,9 +1576,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1566 | 1576 | ||
1567 | err_out_iounmap_fb: | 1577 | err_out_iounmap_fb: |
1568 | iounmap(info->screen_base); | 1578 | iounmap(info->screen_base); |
1579 | err_out_free_base1: | ||
1569 | fb_destroy_modedb(info->monspecs.modedb); | 1580 | fb_destroy_modedb(info->monspecs.modedb); |
1570 | nvidia_delete_i2c_busses(par); | 1581 | nvidia_delete_i2c_busses(par); |
1571 | err_out_free_base1: | ||
1572 | iounmap(par->REGS); | 1582 | iounmap(par->REGS); |
1573 | err_out_free_base0: | 1583 | err_out_free_base0: |
1574 | pci_release_regions(pd); | 1584 | pci_release_regions(pd); |
@@ -1645,6 +1655,8 @@ static int __devinit nvidiafb_setup(char *options) | |||
1645 | noscale = 1; | 1655 | noscale = 1; |
1646 | } else if (!strncmp(this_opt, "paneltweak:", 11)) { | 1656 | } else if (!strncmp(this_opt, "paneltweak:", 11)) { |
1647 | paneltweak = simple_strtoul(this_opt+11, NULL, 0); | 1657 | paneltweak = simple_strtoul(this_opt+11, NULL, 0); |
1658 | } else if (!strncmp(this_opt, "vram:", 5)) { | ||
1659 | vram = simple_strtoul(this_opt+5, NULL, 0); | ||
1648 | #ifdef CONFIG_MTRR | 1660 | #ifdef CONFIG_MTRR |
1649 | } else if (!strncmp(this_opt, "nomtrr", 6)) { | 1661 | } else if (!strncmp(this_opt, "nomtrr", 6)) { |
1650 | nomtrr = 1; | 1662 | nomtrr = 1; |
@@ -1716,6 +1728,10 @@ module_param(forceCRTC, int, 0); | |||
1716 | MODULE_PARM_DESC(forceCRTC, | 1728 | MODULE_PARM_DESC(forceCRTC, |
1717 | "Forces usage of a particular CRTC in case autodetection " | 1729 | "Forces usage of a particular CRTC in case autodetection " |
1718 | "fails. (0 or 1) (default=autodetect)"); | 1730 | "fails. (0 or 1) (default=autodetect)"); |
1731 | module_param(vram, int, 0); | ||
1732 | MODULE_PARM_DESC(vram, | ||
1733 | "amount of framebuffer memory to remap in MiB" | ||
1734 | "(default=0 - remap entire memory)"); | ||
1719 | #ifdef CONFIG_MTRR | 1735 | #ifdef CONFIG_MTRR |
1720 | module_param(nomtrr, bool, 0); | 1736 | module_param(nomtrr, bool, 0); |
1721 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " | 1737 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " |
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c index d9a084e77a63..c46387024b1d 100644 --- a/drivers/video/radeonfb.c +++ b/drivers/video/radeonfb.c | |||
@@ -2107,7 +2107,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo, | |||
2107 | 2107 | ||
2108 | 2108 | ||
2109 | if (rinfo->arch == RADEON_M6) { | 2109 | if (rinfo->arch == RADEON_M6) { |
2110 | for (i=0; i<8; i++) | 2110 | for (i=0; i<7; i++) |
2111 | OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val); | 2111 | OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val); |
2112 | } else { | 2112 | } else { |
2113 | for (i=0; i<9; i++) | 2113 | for (i=0; i<9; i++) |
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index c34ba39b6f7e..7044226c5d4c 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
@@ -317,30 +317,49 @@ static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c) | |||
317 | 317 | ||
318 | static u32 do_calc_pll(int freq, int* freq_out) | 318 | static u32 do_calc_pll(int freq, int* freq_out) |
319 | { | 319 | { |
320 | int m, n, k, best_m, best_n, best_k, f_cur, best_error; | 320 | int m, n, k, best_m, best_n, best_k, best_error; |
321 | int fref = 14318; | 321 | int fref = 14318; |
322 | 322 | ||
323 | /* this really could be done with more intelligence -- | ||
324 | 255*63*4 = 64260 iterations is silly */ | ||
325 | best_error = freq; | 323 | best_error = freq; |
326 | best_n = best_m = best_k = 0; | 324 | best_n = best_m = best_k = 0; |
327 | for (n = 1; n < 256; n++) { | 325 | |
328 | for (m = 1; m < 64; m++) { | 326 | for (k = 3; k >= 0; k--) { |
329 | for (k = 0; k < 4; k++) { | 327 | for (m = 63; m >= 0; m--) { |
330 | f_cur = fref*(n + 2)/(m + 2)/(1 << k); | 328 | /* |
331 | if (abs(f_cur - freq) < best_error) { | 329 | * Estimate value of n that produces target frequency |
332 | best_error = abs(f_cur-freq); | 330 | * with current m and k |
333 | best_n = n; | 331 | */ |
334 | best_m = m; | 332 | int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2; |
335 | best_k = k; | 333 | |
334 | /* Search neighborhood of estimated n */ | ||
335 | for (n = max(0, n_estimated - 1); | ||
336 | n <= min(255, n_estimated + 1); n++) { | ||
337 | /* | ||
338 | * Calculate PLL freqency with current m, k and | ||
339 | * estimated n | ||
340 | */ | ||
341 | int f = fref * (n + 2) / (m + 2) / (1 << k); | ||
342 | int error = abs (f - freq); | ||
343 | |||
344 | /* | ||
345 | * If this is the closest we've come to the | ||
346 | * target frequency then remember n, m and k | ||
347 | */ | ||
348 | if (error < best_error) { | ||
349 | best_error = error; | ||
350 | best_n = n; | ||
351 | best_m = m; | ||
352 | best_k = k; | ||
336 | } | 353 | } |
337 | } | 354 | } |
338 | } | 355 | } |
339 | } | 356 | } |
357 | |||
340 | n = best_n; | 358 | n = best_n; |
341 | m = best_m; | 359 | m = best_m; |
342 | k = best_k; | 360 | k = best_k; |
343 | *freq_out = fref*(n + 2)/(m + 2)/(1 << k); | 361 | *freq_out = fref*(n + 2)/(m + 2)/(1 << k); |
362 | |||
344 | return (n << 8) | (m << 2) | k; | 363 | return (n << 8) | (m << 2) | k; |
345 | } | 364 | } |
346 | 365 | ||
@@ -411,36 +430,35 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) | |||
411 | 430 | ||
412 | static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) | 431 | static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) |
413 | { | 432 | { |
414 | u32 draminit0 = 0; | 433 | u32 draminit0; |
415 | u32 draminit1 = 0; | 434 | u32 draminit1; |
416 | u32 miscinit1 = 0; | 435 | u32 miscinit1; |
417 | u32 lfbsize = 0; | 436 | |
418 | int sgram_p = 0; | 437 | int num_chips; |
438 | int chip_size; /* in MB */ | ||
439 | u32 lfbsize; | ||
440 | int has_sgram; | ||
419 | 441 | ||
420 | draminit0 = tdfx_inl(par, DRAMINIT0); | 442 | draminit0 = tdfx_inl(par, DRAMINIT0); |
421 | draminit1 = tdfx_inl(par, DRAMINIT1); | 443 | draminit1 = tdfx_inl(par, DRAMINIT1); |
444 | |||
445 | num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4; | ||
422 | 446 | ||
423 | if ((dev_id == PCI_DEVICE_ID_3DFX_BANSHEE) || | 447 | if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) { |
424 | (dev_id == PCI_DEVICE_ID_3DFX_VOODOO3)) { | 448 | /* Banshee/Voodoo3 */ |
425 | sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1; | 449 | has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM; |
426 | 450 | chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1) | |
427 | lfbsize = sgram_p ? | 451 | : 2; |
428 | (((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) * | ||
429 | ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) : | ||
430 | 16 * 1024 * 1024; | ||
431 | } else { | 452 | } else { |
432 | /* Voodoo4/5 */ | 453 | /* Voodoo4/5 */ |
433 | u32 chips, psize, banks; | 454 | has_sgram = 0; |
434 | 455 | chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT); | |
435 | chips = ((draminit0 & (1 << 26)) == 0) ? 4 : 8; | 456 | } |
436 | psize = 1 << ((draminit0 & 0x38000000) >> 28); | 457 | lfbsize = num_chips * chip_size * 1024 * 1024; |
437 | banks = ((draminit0 & (1 << 30)) == 0) ? 2 : 4; | 458 | |
438 | lfbsize = chips * psize * banks; | 459 | /* disable block writes for SDRAM */ |
439 | lfbsize <<= 20; | ||
440 | } | ||
441 | /* disable block writes for SDRAM (why?) */ | ||
442 | miscinit1 = tdfx_inl(par, MISCINIT1); | 460 | miscinit1 = tdfx_inl(par, MISCINIT1); |
443 | miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS; | 461 | miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS; |
444 | miscinit1 |= MISCINIT1_CLUT_INV; | 462 | miscinit1 |= MISCINIT1_CLUT_INV; |
445 | 463 | ||
446 | banshee_make_room(par, 1); | 464 | banshee_make_room(par, 1); |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 8fc1278d7fbd..3027841f9c24 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -19,9 +19,6 @@ | |||
19 | #include <linux/fb.h> | 19 | #include <linux/fb.h> |
20 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #ifdef __i386__ | ||
23 | #include <video/edid.h> | ||
24 | #endif | ||
25 | #include <asm/io.h> | 22 | #include <asm/io.h> |
26 | #include <asm/mtrr.h> | 23 | #include <asm/mtrr.h> |
27 | 24 | ||
diff --git a/fs/afs/file.c b/fs/afs/file.c index 6b6bb7c8abf6..23c125128024 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -131,8 +131,7 @@ static int afs_file_readpage(struct file *file, struct page *page) | |||
131 | 131 | ||
132 | vnode = AFS_FS_I(inode); | 132 | vnode = AFS_FS_I(inode); |
133 | 133 | ||
134 | if (!PageLocked(page)) | 134 | BUG_ON(!PageLocked(page)); |
135 | PAGE_BUG(page); | ||
136 | 135 | ||
137 | ret = -ESTALE; | 136 | ret = -ESTALE; |
138 | if (vnode->flags & AFS_VNODE_DELETED) | 137 | if (vnode->flags & AFS_VNODE_DELETED) |
@@ -40,9 +40,6 @@ | |||
40 | #define dprintk(x...) do { ; } while (0) | 40 | #define dprintk(x...) do { ; } while (0) |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | static long aio_run = 0; /* for testing only */ | ||
44 | static long aio_wakeups = 0; /* for testing only */ | ||
45 | |||
46 | /*------ sysctl variables----*/ | 43 | /*------ sysctl variables----*/ |
47 | atomic_t aio_nr = ATOMIC_INIT(0); /* current system wide number of aio requests */ | 44 | atomic_t aio_nr = ATOMIC_INIT(0); /* current system wide number of aio requests */ |
48 | unsigned aio_max_nr = 0x10000; /* system wide maximum number of aio requests */ | 45 | unsigned aio_max_nr = 0x10000; /* system wide maximum number of aio requests */ |
@@ -405,7 +402,6 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx) | |||
405 | req->ki_ctx = ctx; | 402 | req->ki_ctx = ctx; |
406 | req->ki_cancel = NULL; | 403 | req->ki_cancel = NULL; |
407 | req->ki_retry = NULL; | 404 | req->ki_retry = NULL; |
408 | req->ki_obj.user = NULL; | ||
409 | req->ki_dtor = NULL; | 405 | req->ki_dtor = NULL; |
410 | req->private = NULL; | 406 | req->private = NULL; |
411 | INIT_LIST_HEAD(&req->ki_run_list); | 407 | INIT_LIST_HEAD(&req->ki_run_list); |
@@ -451,11 +447,6 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) | |||
451 | { | 447 | { |
452 | if (req->ki_dtor) | 448 | if (req->ki_dtor) |
453 | req->ki_dtor(req); | 449 | req->ki_dtor(req); |
454 | req->ki_ctx = NULL; | ||
455 | req->ki_filp = NULL; | ||
456 | req->ki_obj.user = NULL; | ||
457 | req->ki_dtor = NULL; | ||
458 | req->private = NULL; | ||
459 | kmem_cache_free(kiocb_cachep, req); | 450 | kmem_cache_free(kiocb_cachep, req); |
460 | ctx->reqs_active--; | 451 | ctx->reqs_active--; |
461 | 452 | ||
@@ -623,7 +614,6 @@ static inline int __queue_kicked_iocb(struct kiocb *iocb) | |||
623 | if (list_empty(&iocb->ki_run_list)) { | 614 | if (list_empty(&iocb->ki_run_list)) { |
624 | list_add_tail(&iocb->ki_run_list, | 615 | list_add_tail(&iocb->ki_run_list, |
625 | &ctx->run_list); | 616 | &ctx->run_list); |
626 | iocb->ki_queued++; | ||
627 | return 1; | 617 | return 1; |
628 | } | 618 | } |
629 | return 0; | 619 | return 0; |
@@ -664,10 +654,8 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) | |||
664 | } | 654 | } |
665 | 655 | ||
666 | if (!(iocb->ki_retried & 0xff)) { | 656 | if (!(iocb->ki_retried & 0xff)) { |
667 | pr_debug("%ld retry: %d of %d (kick %ld, Q %ld run %ld, wake %ld)\n", | 657 | pr_debug("%ld retry: %d of %d\n", iocb->ki_retried, |
668 | iocb->ki_retried, | 658 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); |
669 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes, | ||
670 | iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups); | ||
671 | } | 659 | } |
672 | 660 | ||
673 | if (!(retry = iocb->ki_retry)) { | 661 | if (!(retry = iocb->ki_retry)) { |
@@ -774,7 +762,6 @@ out: | |||
774 | static int __aio_run_iocbs(struct kioctx *ctx) | 762 | static int __aio_run_iocbs(struct kioctx *ctx) |
775 | { | 763 | { |
776 | struct kiocb *iocb; | 764 | struct kiocb *iocb; |
777 | int count = 0; | ||
778 | LIST_HEAD(run_list); | 765 | LIST_HEAD(run_list); |
779 | 766 | ||
780 | list_splice_init(&ctx->run_list, &run_list); | 767 | list_splice_init(&ctx->run_list, &run_list); |
@@ -789,9 +776,7 @@ static int __aio_run_iocbs(struct kioctx *ctx) | |||
789 | aio_run_iocb(iocb); | 776 | aio_run_iocb(iocb); |
790 | if (__aio_put_req(ctx, iocb)) /* drop extra ref */ | 777 | if (__aio_put_req(ctx, iocb)) /* drop extra ref */ |
791 | put_ioctx(ctx); | 778 | put_ioctx(ctx); |
792 | count++; | ||
793 | } | 779 | } |
794 | aio_run++; | ||
795 | if (!list_empty(&ctx->run_list)) | 780 | if (!list_empty(&ctx->run_list)) |
796 | return 1; | 781 | return 1; |
797 | return 0; | 782 | return 0; |
@@ -890,10 +875,8 @@ static void queue_kicked_iocb(struct kiocb *iocb) | |||
890 | spin_lock_irqsave(&ctx->ctx_lock, flags); | 875 | spin_lock_irqsave(&ctx->ctx_lock, flags); |
891 | run = __queue_kicked_iocb(iocb); | 876 | run = __queue_kicked_iocb(iocb); |
892 | spin_unlock_irqrestore(&ctx->ctx_lock, flags); | 877 | spin_unlock_irqrestore(&ctx->ctx_lock, flags); |
893 | if (run) { | 878 | if (run) |
894 | aio_queue_work(ctx); | 879 | aio_queue_work(ctx); |
895 | aio_wakeups++; | ||
896 | } | ||
897 | } | 880 | } |
898 | 881 | ||
899 | /* | 882 | /* |
@@ -913,7 +896,6 @@ void fastcall kick_iocb(struct kiocb *iocb) | |||
913 | return; | 896 | return; |
914 | } | 897 | } |
915 | 898 | ||
916 | iocb->ki_kicked++; | ||
917 | /* If its already kicked we shouldn't queue it again */ | 899 | /* If its already kicked we shouldn't queue it again */ |
918 | if (!kiocbTryKick(iocb)) { | 900 | if (!kiocbTryKick(iocb)) { |
919 | queue_kicked_iocb(iocb); | 901 | queue_kicked_iocb(iocb); |
@@ -984,7 +966,8 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2) | |||
984 | 966 | ||
985 | tail = info->tail; | 967 | tail = info->tail; |
986 | event = aio_ring_event(info, tail, KM_IRQ0); | 968 | event = aio_ring_event(info, tail, KM_IRQ0); |
987 | tail = (tail + 1) % info->nr; | 969 | if (++tail >= info->nr) |
970 | tail = 0; | ||
988 | 971 | ||
989 | event->obj = (u64)(unsigned long)iocb->ki_obj.user; | 972 | event->obj = (u64)(unsigned long)iocb->ki_obj.user; |
990 | event->data = iocb->ki_user_data; | 973 | event->data = iocb->ki_user_data; |
@@ -1008,10 +991,8 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2) | |||
1008 | 991 | ||
1009 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); | 992 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); |
1010 | 993 | ||
1011 | pr_debug("%ld retries: %d of %d (kicked %ld, Q %ld run %ld wake %ld)\n", | 994 | pr_debug("%ld retries: %d of %d\n", iocb->ki_retried, |
1012 | iocb->ki_retried, | 995 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); |
1013 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes, | ||
1014 | iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups); | ||
1015 | put_rq: | 996 | put_rq: |
1016 | /* everything turned out well, dispose of the aiocb. */ | 997 | /* everything turned out well, dispose of the aiocb. */ |
1017 | ret = __aio_put_req(ctx, iocb); | 998 | ret = __aio_put_req(ctx, iocb); |
@@ -1119,7 +1100,6 @@ static int read_events(struct kioctx *ctx, | |||
1119 | int i = 0; | 1100 | int i = 0; |
1120 | struct io_event ent; | 1101 | struct io_event ent; |
1121 | struct aio_timeout to; | 1102 | struct aio_timeout to; |
1122 | int event_loop = 0; /* testing only */ | ||
1123 | int retry = 0; | 1103 | int retry = 0; |
1124 | 1104 | ||
1125 | /* needed to zero any padding within an entry (there shouldn't be | 1105 | /* needed to zero any padding within an entry (there shouldn't be |
@@ -1186,7 +1166,6 @@ retry: | |||
1186 | if (to.timed_out) /* Only check after read evt */ | 1166 | if (to.timed_out) /* Only check after read evt */ |
1187 | break; | 1167 | break; |
1188 | schedule(); | 1168 | schedule(); |
1189 | event_loop++; | ||
1190 | if (signal_pending(tsk)) { | 1169 | if (signal_pending(tsk)) { |
1191 | ret = -EINTR; | 1170 | ret = -EINTR; |
1192 | break; | 1171 | break; |
@@ -1214,9 +1193,6 @@ retry: | |||
1214 | if (timeout) | 1193 | if (timeout) |
1215 | clear_timeout(&to); | 1194 | clear_timeout(&to); |
1216 | out: | 1195 | out: |
1217 | pr_debug("event loop executed %d times\n", event_loop); | ||
1218 | pr_debug("aio_run %ld\n", aio_run); | ||
1219 | pr_debug("aio_wakeups %ld\n", aio_wakeups); | ||
1220 | return i ? i : ret; | 1196 | return i ? i : ret; |
1221 | } | 1197 | } |
1222 | 1198 | ||
@@ -1515,8 +1491,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1515 | } | 1491 | } |
1516 | 1492 | ||
1517 | req->ki_filp = file; | 1493 | req->ki_filp = file; |
1518 | iocb->aio_key = req->ki_key; | 1494 | ret = put_user(req->ki_key, &user_iocb->aio_key); |
1519 | ret = put_user(iocb->aio_key, &user_iocb->aio_key); | ||
1520 | if (unlikely(ret)) { | 1495 | if (unlikely(ret)) { |
1521 | dprintk("EFAULT: aio_key\n"); | 1496 | dprintk("EFAULT: aio_key\n"); |
1522 | goto out_put_req; | 1497 | goto out_put_req; |
@@ -1531,13 +1506,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1531 | req->ki_opcode = iocb->aio_lio_opcode; | 1506 | req->ki_opcode = iocb->aio_lio_opcode; |
1532 | init_waitqueue_func_entry(&req->ki_wait, aio_wake_function); | 1507 | init_waitqueue_func_entry(&req->ki_wait, aio_wake_function); |
1533 | INIT_LIST_HEAD(&req->ki_wait.task_list); | 1508 | INIT_LIST_HEAD(&req->ki_wait.task_list); |
1534 | req->ki_run_list.next = req->ki_run_list.prev = NULL; | ||
1535 | req->ki_retry = NULL; | ||
1536 | req->ki_retried = 0; | 1509 | req->ki_retried = 0; |
1537 | req->ki_kicked = 0; | ||
1538 | req->ki_queued = 0; | ||
1539 | aio_run = 0; | ||
1540 | aio_wakeups = 0; | ||
1541 | 1510 | ||
1542 | ret = aio_setup_iocb(req); | 1511 | ret = aio_setup_iocb(req); |
1543 | 1512 | ||
@@ -1545,10 +1514,14 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1545 | goto out_put_req; | 1514 | goto out_put_req; |
1546 | 1515 | ||
1547 | spin_lock_irq(&ctx->ctx_lock); | 1516 | spin_lock_irq(&ctx->ctx_lock); |
1548 | list_add_tail(&req->ki_run_list, &ctx->run_list); | 1517 | if (likely(list_empty(&ctx->run_list))) { |
1549 | /* drain the run list */ | 1518 | aio_run_iocb(req); |
1550 | while (__aio_run_iocbs(ctx)) | 1519 | } else { |
1551 | ; | 1520 | list_add_tail(&req->ki_run_list, &ctx->run_list); |
1521 | /* drain the run list */ | ||
1522 | while (__aio_run_iocbs(ctx)) | ||
1523 | ; | ||
1524 | } | ||
1552 | spin_unlock_irq(&ctx->ctx_lock); | 1525 | spin_unlock_irq(&ctx->ctx_lock); |
1553 | aio_put_req(req); /* drop extra ref to req */ | 1526 | aio_put_req(req); /* drop extra ref to req */ |
1554 | return 0; | 1527 | return 0; |
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index f5a52c871726..c7b2b8890188 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -84,6 +84,7 @@ struct autofs_wait_queue { | |||
84 | char *name; | 84 | char *name; |
85 | /* This is for status reporting upon return */ | 85 | /* This is for status reporting upon return */ |
86 | int status; | 86 | int status; |
87 | atomic_t notified; | ||
87 | atomic_t wait_ctr; | 88 | atomic_t wait_ctr; |
88 | }; | 89 | }; |
89 | 90 | ||
@@ -101,6 +102,7 @@ struct autofs_sb_info { | |||
101 | int needs_reghost; | 102 | int needs_reghost; |
102 | struct super_block *sb; | 103 | struct super_block *sb; |
103 | struct semaphore wq_sem; | 104 | struct semaphore wq_sem; |
105 | spinlock_t fs_lock; | ||
104 | struct autofs_wait_queue *queues; /* Wait queue pointer */ | 106 | struct autofs_wait_queue *queues; /* Wait queue pointer */ |
105 | }; | 107 | }; |
106 | 108 | ||
@@ -126,9 +128,18 @@ static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) { | |||
126 | static inline int autofs4_ispending(struct dentry *dentry) | 128 | static inline int autofs4_ispending(struct dentry *dentry) |
127 | { | 129 | { |
128 | struct autofs_info *inf = autofs4_dentry_ino(dentry); | 130 | struct autofs_info *inf = autofs4_dentry_ino(dentry); |
131 | int pending = 0; | ||
129 | 132 | ||
130 | return (dentry->d_flags & DCACHE_AUTOFS_PENDING) || | 133 | if (dentry->d_flags & DCACHE_AUTOFS_PENDING) |
131 | (inf != NULL && inf->flags & AUTOFS_INF_EXPIRING); | 134 | return 1; |
135 | |||
136 | if (inf) { | ||
137 | spin_lock(&inf->sbi->fs_lock); | ||
138 | pending = inf->flags & AUTOFS_INF_EXPIRING; | ||
139 | spin_unlock(&inf->sbi->fs_lock); | ||
140 | } | ||
141 | |||
142 | return pending; | ||
132 | } | 143 | } |
133 | 144 | ||
134 | static inline void autofs4_copy_atime(struct file *src, struct file *dst) | 145 | static inline void autofs4_copy_atime(struct file *src, struct file *dst) |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 31540a6404d9..500425e24fba 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -99,6 +99,10 @@ static int autofs4_check_tree(struct vfsmount *mnt, | |||
99 | if (!autofs4_can_expire(top, timeout, do_now)) | 99 | if (!autofs4_can_expire(top, timeout, do_now)) |
100 | return 0; | 100 | return 0; |
101 | 101 | ||
102 | /* Is someone visiting anywhere in the tree ? */ | ||
103 | if (may_umount_tree(mnt)) | ||
104 | return 0; | ||
105 | |||
102 | spin_lock(&dcache_lock); | 106 | spin_lock(&dcache_lock); |
103 | repeat: | 107 | repeat: |
104 | next = this_parent->d_subdirs.next; | 108 | next = this_parent->d_subdirs.next; |
@@ -270,10 +274,18 @@ static struct dentry *autofs4_expire(struct super_block *sb, | |||
270 | 274 | ||
271 | /* Case 2: tree mount, expire iff entire tree is not busy */ | 275 | /* Case 2: tree mount, expire iff entire tree is not busy */ |
272 | if (!exp_leaves) { | 276 | if (!exp_leaves) { |
277 | /* Lock the tree as we must expire as a whole */ | ||
278 | spin_lock(&sbi->fs_lock); | ||
273 | if (autofs4_check_tree(mnt, dentry, timeout, do_now)) { | 279 | if (autofs4_check_tree(mnt, dentry, timeout, do_now)) { |
274 | expired = dentry; | 280 | struct autofs_info *inf = autofs4_dentry_ino(dentry); |
275 | break; | 281 | |
282 | /* Set this flag early to catch sys_chdir and the like */ | ||
283 | inf->flags |= AUTOFS_INF_EXPIRING; | ||
284 | spin_unlock(&sbi->fs_lock); | ||
285 | expired = dentry; | ||
286 | break; | ||
276 | } | 287 | } |
288 | spin_unlock(&sbi->fs_lock); | ||
277 | /* Case 3: direct mount, expire individual leaves */ | 289 | /* Case 3: direct mount, expire individual leaves */ |
278 | } else { | 290 | } else { |
279 | expired = autofs4_check_leaves(mnt, dentry, timeout, do_now); | 291 | expired = autofs4_check_leaves(mnt, dentry, timeout, do_now); |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index a52560746628..4bb14cc68040 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -206,6 +206,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
206 | sbi->version = 0; | 206 | sbi->version = 0; |
207 | sbi->sub_version = 0; | 207 | sbi->sub_version = 0; |
208 | init_MUTEX(&sbi->wq_sem); | 208 | init_MUTEX(&sbi->wq_sem); |
209 | spin_lock_init(&sbi->fs_lock); | ||
209 | sbi->queues = NULL; | 210 | sbi->queues = NULL; |
210 | s->s_blocksize = 1024; | 211 | s->s_blocksize = 1024; |
211 | s->s_blocksize_bits = 10; | 212 | s->s_blocksize_bits = 10; |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 1ab24a662e09..5a40d36e5a51 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -210,17 +210,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
210 | wq->len = len; | 210 | wq->len = len; |
211 | wq->status = -EINTR; /* Status return if interrupted */ | 211 | wq->status = -EINTR; /* Status return if interrupted */ |
212 | atomic_set(&wq->wait_ctr, 2); | 212 | atomic_set(&wq->wait_ctr, 2); |
213 | atomic_set(&wq->notified, 1); | ||
213 | up(&sbi->wq_sem); | 214 | up(&sbi->wq_sem); |
214 | |||
215 | DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d", | ||
216 | (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); | ||
217 | /* autofs4_notify_daemon() may block */ | ||
218 | if (notify != NFY_NONE) { | ||
219 | autofs4_notify_daemon(sbi,wq, | ||
220 | notify == NFY_MOUNT ? | ||
221 | autofs_ptype_missing : | ||
222 | autofs_ptype_expire_multi); | ||
223 | } | ||
224 | } else { | 215 | } else { |
225 | atomic_inc(&wq->wait_ctr); | 216 | atomic_inc(&wq->wait_ctr); |
226 | up(&sbi->wq_sem); | 217 | up(&sbi->wq_sem); |
@@ -229,6 +220,17 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
229 | (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); | 220 | (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); |
230 | } | 221 | } |
231 | 222 | ||
223 | if (notify != NFY_NONE && atomic_dec_and_test(&wq->notified)) { | ||
224 | int type = (notify == NFY_MOUNT ? | ||
225 | autofs_ptype_missing : autofs_ptype_expire_multi); | ||
226 | |||
227 | DPRINTK(("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", | ||
228 | (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify)); | ||
229 | |||
230 | /* autofs4_notify_daemon() may block */ | ||
231 | autofs4_notify_daemon(sbi, wq, type); | ||
232 | } | ||
233 | |||
232 | /* wq->name is NULL if and only if the lock is already released */ | 234 | /* wq->name is NULL if and only if the lock is already released */ |
233 | 235 | ||
234 | if ( sbi->catatonic ) { | 236 | if ( sbi->catatonic ) { |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6ae62cbf7c2e..ce9423bb2de3 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -945,7 +945,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
945 | retval = arch_setup_additional_pages(bprm, executable_stack); | 945 | retval = arch_setup_additional_pages(bprm, executable_stack); |
946 | if (retval < 0) { | 946 | if (retval < 0) { |
947 | send_sig(SIGKILL, current, 0); | 947 | send_sig(SIGKILL, current, 0); |
948 | goto out_free_dentry; | 948 | goto out; |
949 | } | 949 | } |
950 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ | 950 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ |
951 | 951 | ||
@@ -140,6 +140,7 @@ inline void bio_init(struct bio *bio) | |||
140 | * bio_alloc_bioset - allocate a bio for I/O | 140 | * bio_alloc_bioset - allocate a bio for I/O |
141 | * @gfp_mask: the GFP_ mask given to the slab allocator | 141 | * @gfp_mask: the GFP_ mask given to the slab allocator |
142 | * @nr_iovecs: number of iovecs to pre-allocate | 142 | * @nr_iovecs: number of iovecs to pre-allocate |
143 | * @bs: the bio_set to allocate from | ||
143 | * | 144 | * |
144 | * Description: | 145 | * Description: |
145 | * bio_alloc_bioset will first try it's on mempool to satisfy the allocation. | 146 | * bio_alloc_bioset will first try it's on mempool to satisfy the allocation. |
@@ -629,6 +630,7 @@ out: | |||
629 | 630 | ||
630 | /** | 631 | /** |
631 | * bio_map_user - map user address into bio | 632 | * bio_map_user - map user address into bio |
633 | * @q: the request_queue_t for the bio | ||
632 | * @bdev: destination block device | 634 | * @bdev: destination block device |
633 | * @uaddr: start of user address | 635 | * @uaddr: start of user address |
634 | * @len: length in bytes | 636 | * @len: length in bytes |
diff --git a/fs/buffer.c b/fs/buffer.c index 3b12cf947aba..5f525b3c6d9f 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -218,7 +218,7 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
218 | sb = get_super(bdev); | 218 | sb = get_super(bdev); |
219 | if (sb && !(sb->s_flags & MS_RDONLY)) { | 219 | if (sb && !(sb->s_flags & MS_RDONLY)) { |
220 | sb->s_frozen = SB_FREEZE_WRITE; | 220 | sb->s_frozen = SB_FREEZE_WRITE; |
221 | wmb(); | 221 | smp_wmb(); |
222 | 222 | ||
223 | sync_inodes_sb(sb, 0); | 223 | sync_inodes_sb(sb, 0); |
224 | DQUOT_SYNC(sb); | 224 | DQUOT_SYNC(sb); |
@@ -235,7 +235,7 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
235 | sync_inodes_sb(sb, 1); | 235 | sync_inodes_sb(sb, 1); |
236 | 236 | ||
237 | sb->s_frozen = SB_FREEZE_TRANS; | 237 | sb->s_frozen = SB_FREEZE_TRANS; |
238 | wmb(); | 238 | smp_wmb(); |
239 | 239 | ||
240 | sync_blockdev(sb->s_bdev); | 240 | sync_blockdev(sb->s_bdev); |
241 | 241 | ||
@@ -263,7 +263,7 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb) | |||
263 | if (sb->s_op->unlockfs) | 263 | if (sb->s_op->unlockfs) |
264 | sb->s_op->unlockfs(sb); | 264 | sb->s_op->unlockfs(sb); |
265 | sb->s_frozen = SB_UNFROZEN; | 265 | sb->s_frozen = SB_UNFROZEN; |
266 | wmb(); | 266 | smp_wmb(); |
267 | wake_up(&sb->s_wait_unfrozen); | 267 | wake_up(&sb->s_wait_unfrozen); |
268 | drop_super(sb); | 268 | drop_super(sb); |
269 | } | 269 | } |
@@ -774,15 +774,14 @@ repeat: | |||
774 | /** | 774 | /** |
775 | * sync_mapping_buffers - write out and wait upon a mapping's "associated" | 775 | * sync_mapping_buffers - write out and wait upon a mapping's "associated" |
776 | * buffers | 776 | * buffers |
777 | * @buffer_mapping - the mapping which backs the buffers' data | 777 | * @mapping: the mapping which wants those buffers written |
778 | * @mapping - the mapping which wants those buffers written | ||
779 | * | 778 | * |
780 | * Starts I/O against the buffers at mapping->private_list, and waits upon | 779 | * Starts I/O against the buffers at mapping->private_list, and waits upon |
781 | * that I/O. | 780 | * that I/O. |
782 | * | 781 | * |
783 | * Basically, this is a convenience function for fsync(). @buffer_mapping is | 782 | * Basically, this is a convenience function for fsync(). |
784 | * the blockdev which "owns" the buffers and @mapping is a file or directory | 783 | * @mapping is a file or directory which needs those buffers to be written for |
785 | * which needs those buffers to be written for a successful fsync(). | 784 | * a successful fsync(). |
786 | */ | 785 | */ |
787 | int sync_mapping_buffers(struct address_space *mapping) | 786 | int sync_mapping_buffers(struct address_space *mapping) |
788 | { | 787 | { |
@@ -1263,6 +1262,7 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) | |||
1263 | 1262 | ||
1264 | /** | 1263 | /** |
1265 | * mark_buffer_dirty - mark a buffer_head as needing writeout | 1264 | * mark_buffer_dirty - mark a buffer_head as needing writeout |
1265 | * @bh: the buffer_head to mark dirty | ||
1266 | * | 1266 | * |
1267 | * mark_buffer_dirty() will set the dirty bit against the buffer, then set its | 1267 | * mark_buffer_dirty() will set the dirty bit against the buffer, then set its |
1268 | * backing page dirty, then tag the page as dirty in its address_space's radix | 1268 | * backing page dirty, then tag the page as dirty in its address_space's radix |
@@ -1501,6 +1501,7 @@ EXPORT_SYMBOL(__breadahead); | |||
1501 | 1501 | ||
1502 | /** | 1502 | /** |
1503 | * __bread() - reads a specified block and returns the bh | 1503 | * __bread() - reads a specified block and returns the bh |
1504 | * @bdev: the block_device to read from | ||
1504 | * @block: number of block | 1505 | * @block: number of block |
1505 | * @size: size (in bytes) to read | 1506 | * @size: size (in bytes) to read |
1506 | * | 1507 | * |
@@ -2078,8 +2079,7 @@ int block_read_full_page(struct page *page, get_block_t *get_block) | |||
2078 | int nr, i; | 2079 | int nr, i; |
2079 | int fully_mapped = 1; | 2080 | int fully_mapped = 1; |
2080 | 2081 | ||
2081 | if (!PageLocked(page)) | 2082 | BUG_ON(!PageLocked(page)); |
2082 | PAGE_BUG(page); | ||
2083 | blocksize = 1 << inode->i_blkbits; | 2083 | blocksize = 1 << inode->i_blkbits; |
2084 | if (!page_has_buffers(page)) | 2084 | if (!page_has_buffers(page)) |
2085 | create_empty_buffers(page, blocksize, 0); | 2085 | create_empty_buffers(page, blocksize, 0); |
@@ -2917,7 +2917,7 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free) | |||
2917 | 2917 | ||
2918 | bh = head; | 2918 | bh = head; |
2919 | do { | 2919 | do { |
2920 | if (buffer_write_io_error(bh)) | 2920 | if (buffer_write_io_error(bh) && page->mapping) |
2921 | set_bit(AS_EIO, &page->mapping->flags); | 2921 | set_bit(AS_EIO, &page->mapping->flags); |
2922 | if (buffer_busy(bh)) | 2922 | if (buffer_busy(bh)) |
2923 | goto failed; | 2923 | goto failed; |
diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS index acce36e25d2e..72fdc10dfdd7 100644 --- a/fs/cifs/AUTHORS +++ b/fs/cifs/AUTHORS | |||
@@ -4,13 +4,16 @@ Steve French (sfrench@samba.org) | |||
4 | 4 | ||
5 | The author wishes to express his appreciation and thanks to: | 5 | The author wishes to express his appreciation and thanks to: |
6 | Andrew Tridgell (Samba team) for his early suggestions about smb/cifs VFS | 6 | Andrew Tridgell (Samba team) for his early suggestions about smb/cifs VFS |
7 | improvements. Thanks to IBM for allowing me the time and test resources to pursue | 7 | improvements. Thanks to IBM for allowing me time and test resources to pursue |
8 | this project. Jim McDonough from IBM (and the Samba Team) for his help. | 8 | this project, to Jim McDonough from IBM (and the Samba Team) for his help, to |
9 | The IBM Linux JFS team for explaining many esoteric Linux filesystem features. | 9 | the IBM Linux JFS team for explaining many esoteric Linux filesystem features. |
10 | Jeremy Allison of the Samba team has done invaluable work in adding the server | ||
11 | side of the original CIFS Unix extensions and reviewing and implementing | ||
12 | portions of the newer CIFS POSIX extensions into the Samba 3 file server. Thank | ||
10 | Dave Boutcher of IBM Rochester (author of the OS/400 smb/cifs filesystem client) | 13 | Dave Boutcher of IBM Rochester (author of the OS/400 smb/cifs filesystem client) |
11 | for proving years ago that a very good smb/cifs client could be done on a Unix like | 14 | for proving years ago that very good smb/cifs clients could be done on Unix-like |
12 | operating system. Volker Lendecke, Andrew Tridgell, Urban Widmark, John Newbigin | 15 | operating systems. Volker Lendecke, Andrew Tridgell, Urban Widmark, John |
13 | and others for their work on the Linux smbfs module over the years. Thanks to | 16 | Newbigin and others for their work on the Linux smbfs module. Thanks to |
14 | the other members of the Storage Network Industry Association CIFS Technical | 17 | the other members of the Storage Network Industry Association CIFS Technical |
15 | Workgroup for their work specifying this highly complex protocol and finally | 18 | Workgroup for their work specifying this highly complex protocol and finally |
16 | thanks to the Samba team for their technical advice and encouragement. | 19 | thanks to the Samba team for their technical advice and encouragement. |
@@ -24,9 +27,11 @@ Shobhit Dayal | |||
24 | Sergey Vlasov | 27 | Sergey Vlasov |
25 | Richard Hughes | 28 | Richard Hughes |
26 | Yury Umanets | 29 | Yury Umanets |
27 | Mark Hamzy | 30 | Mark Hamzy (for some of the early cifs IPv6 work) |
28 | Domen Puncer | 31 | Domen Puncer |
29 | Jesper Juhl | 32 | Jesper Juhl (in particular for lots of whitespace/formatting cleanup) |
33 | Vince Negri and Dave Stahl (for finding an important caching bug) | ||
34 | Adrian Bunk (kcalloc cleanups) | ||
30 | 35 | ||
31 | Test case and Bug Report contributors | 36 | Test case and Bug Report contributors |
32 | ------------------------------------- | 37 | ------------------------------------- |
@@ -36,7 +41,8 @@ Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori, | |||
36 | Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen, | 41 | Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen, |
37 | Olaf Kirch, Kieron Briggs, Nick Millington and others. Also special | 42 | Olaf Kirch, Kieron Briggs, Nick Millington and others. Also special |
38 | mention to the Stanford Checker (SWAT) which pointed out many minor | 43 | mention to the Stanford Checker (SWAT) which pointed out many minor |
39 | bugs in error paths. | 44 | bugs in error paths. Valuable suggestions also have come from Al Viro |
45 | and Dave Miller. | ||
40 | 46 | ||
41 | And thanks to the IBM LTC and Power test teams and SuSE testers for | 47 | And thanks to the IBM LTC and Power test teams and SuSE testers for |
42 | finding multiple bugs during excellent stress test runs. | 48 | finding multiple bugs during excellent stress test runs. |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 5316c8dd6bff..95483baab706 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,7 +1,44 @@ | |||
1 | Version 1.31 | 1 | Version 1.34 |
2 | ------------ | ||
3 | Fix error mapping of the TOO_MANY_LINKS (hardlinks) case. | ||
4 | Do not oops if root user kills cifs oplock kernel thread or | ||
5 | kills the cifsd thread (NB: killing the cifs kernel threads is not | ||
6 | recommended, unmount and rmmod cifs will kill them when they are | ||
7 | no longer needed). Fix readdir to ASCII servers (ie older servers | ||
8 | which do not support Unicode) and also require asterik. | ||
9 | |||
10 | |||
11 | Version 1.33 | ||
12 | ------------ | ||
13 | Fix caching problem, in which readdir of directory containing a file | ||
14 | which was cached could cause the file's time stamp to be updated | ||
15 | without invalidating the readahead data (so we could get stale | ||
16 | file data on the client for that file even as the server copy changed). | ||
17 | Cleanup response processing so cifsd can not loop when abnormally | ||
18 | terminated. | ||
19 | |||
20 | |||
21 | Version 1.32 | ||
2 | ------------ | 22 | ------------ |
3 | Fix oops in ls when Transact2 FindFirst (or FindNext) returns more than one | 23 | Fix oops in ls when Transact2 FindFirst (or FindNext) returns more than one |
4 | transact response for an SMB request and search entry split across two frames. | 24 | transact response for an SMB request and search entry split across two frames. |
25 | Add support for lsattr (getting ext2/ext3/reiserfs attr flags from the server) | ||
26 | as new protocol extensions. Do not send Get/Set calls for POSIX ACLs | ||
27 | unless server explicitly claims to support them in CIFS Unix extensions | ||
28 | POSIX ACL capability bit. Fix packet signing when multiuser mounting with | ||
29 | different users from the same client to the same server. Fix oops in | ||
30 | cifs_close. Add mount option for remapping reserved characters in | ||
31 | filenames (also allow recognizing files with created by SFU which have any | ||
32 | of these seven reserved characters, except backslash, to be recognized). | ||
33 | Fix invalid transact2 message (we were sometimes trying to interpret | ||
34 | oplock breaks as SMB responses). Add ioctl for checking that the | ||
35 | current uid matches the uid of the mounter (needed by umount.cifs). | ||
36 | Reduce the number of large buffer allocations in cifs response processing | ||
37 | (significantly reduces memory pressure under heavy stress with multiple | ||
38 | processes accessing the same server at the same time). | ||
39 | |||
40 | Version 1.31 | ||
41 | ------------ | ||
5 | Fix updates of DOS attributes and time fields so that files on NT4 servers | 42 | Fix updates of DOS attributes and time fields so that files on NT4 servers |
6 | do not get marked delete on close. Display sizes of cifs buffer pools in | 43 | do not get marked delete on close. Display sizes of cifs buffer pools in |
7 | cifs stats. Fix oops in unmount when cifsd thread being killed by | 44 | cifs stats. Fix oops in unmount when cifsd thread being killed by |
diff --git a/fs/cifs/README b/fs/cifs/README index 0f20edc935b5..7b4ac096cd11 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -75,7 +75,7 @@ Allowing User Mounts | |||
75 | ==================== | 75 | ==================== |
76 | To permit users to mount and unmount over directories they own is possible | 76 | To permit users to mount and unmount over directories they own is possible |
77 | with the cifs vfs. A way to enable such mounting is to mark the mount.cifs | 77 | with the cifs vfs. A way to enable such mounting is to mark the mount.cifs |
78 | utility as suid (e.g. "chmod +s /sbin/mount/cifs). To enable users to | 78 | utility as suid (e.g. "chmod +s /sbin/mount.cifs). To enable users to |
79 | umount shares they mount requires | 79 | umount shares they mount requires |
80 | 1) mount.cifs version 1.4 or later | 80 | 1) mount.cifs version 1.4 or later |
81 | 2) an entry for the share in /etc/fstab indicating that a user may | 81 | 2) an entry for the share in /etc/fstab indicating that a user may |
@@ -97,6 +97,26 @@ mount.cifs with the following flag: | |||
97 | There is a corresponding manual page for cifs mounting in the Samba 3.0 and | 97 | There is a corresponding manual page for cifs mounting in the Samba 3.0 and |
98 | later source tree in docs/manpages/mount.cifs.8 | 98 | later source tree in docs/manpages/mount.cifs.8 |
99 | 99 | ||
100 | Allowing User Unmounts | ||
101 | ====================== | ||
102 | To permit users to ummount directories that they have user mounted (see above), | ||
103 | the utility umount.cifs may be used. It may be invoked directly, or if | ||
104 | umount.cifs is placed in /sbin, umount can invoke the cifs umount helper | ||
105 | (at least for most versions of the umount utility) for umount of cifs | ||
106 | mounts, unless umount is invoked with -i (which will avoid invoking a umount | ||
107 | helper). As with mount.cifs, to enable user unmounts umount.cifs must be marked | ||
108 | as suid (e.g. "chmod +s /sbin/umount.cifs") or equivalent (some distributions | ||
109 | allow adding entries to a file to the /etc/permissions file to achieve the | ||
110 | equivalent suid effect). For this utility to succeed the target path | ||
111 | must be a cifs mount, and the uid of the current user must match the uid | ||
112 | of the user who mounted the resource. | ||
113 | |||
114 | Also note that the customary way of allowing user mounts and unmounts is | ||
115 | (instead of using mount.cifs and unmount.cifs as suid) to add a line | ||
116 | to the file /etc/fstab for each //server/share you wish to mount, but | ||
117 | this can become unwieldy when potential mount targets include many | ||
118 | or unpredictable UNC names. | ||
119 | |||
100 | Samba Considerations | 120 | Samba Considerations |
101 | ==================== | 121 | ==================== |
102 | To get the maximum benefit from the CIFS VFS, we recommend using a server that | 122 | To get the maximum benefit from the CIFS VFS, we recommend using a server that |
@@ -376,6 +396,19 @@ A partial list of the supported mount options follows: | |||
376 | attributes) to the server (default) e.g. via setfattr | 396 | attributes) to the server (default) e.g. via setfattr |
377 | and getfattr utilities. | 397 | and getfattr utilities. |
378 | nouser_xattr Do not allow getfattr/setfattr to get/set xattrs | 398 | nouser_xattr Do not allow getfattr/setfattr to get/set xattrs |
399 | mapchars Translate six of the seven reserved characters (not backslash) | ||
400 | *?<>|: | ||
401 | to the remap range (above 0xF000), which also | ||
402 | allows the CIFS client to recognize files created with | ||
403 | such characters by Windows's POSIX emulation. This can | ||
404 | also be useful when mounting to most versions of Samba | ||
405 | (which also forbids creating and opening files | ||
406 | whose names contain any of these seven characters). | ||
407 | This has no effect if the server does not support | ||
408 | Unicode on the wire. | ||
409 | nomapchars Do not translate any of these seven characters (default). | ||
410 | remount remount the share (often used to change from ro to rw mounts | ||
411 | or vice versa) | ||
379 | 412 | ||
380 | The mount.cifs mount helper also accepts a few mount options before -o | 413 | The mount.cifs mount helper also accepts a few mount options before -o |
381 | including: | 414 | including: |
@@ -392,7 +425,7 @@ Misc /proc/fs/cifs Flags and Debug Info | |||
392 | ======================================= | 425 | ======================================= |
393 | Informational pseudo-files: | 426 | Informational pseudo-files: |
394 | DebugData Displays information about active CIFS sessions | 427 | DebugData Displays information about active CIFS sessions |
395 | and shares. | 428 | and shares, as well as the cifs.ko version. |
396 | Stats Lists summary resource usage information as well as per | 429 | Stats Lists summary resource usage information as well as per |
397 | share statistics, if CONFIG_CIFS_STATS in enabled | 430 | share statistics, if CONFIG_CIFS_STATS in enabled |
398 | in the kernel configuration. | 431 | in the kernel configuration. |
@@ -449,7 +482,7 @@ and for more extensive tracing including the start of smb requests and responses | |||
449 | Two other experimental features are under development and to test | 482 | Two other experimental features are under development and to test |
450 | require enabling CONFIG_CIFS_EXPERIMENTAL | 483 | require enabling CONFIG_CIFS_EXPERIMENTAL |
451 | 484 | ||
452 | More efficient write operations and SMB buffer handling | 485 | More efficient write operations |
453 | 486 | ||
454 | DNOTIFY fcntl: needed for support of directory change | 487 | DNOTIFY fcntl: needed for support of directory change |
455 | notification and perhaps later for file leases) | 488 | notification and perhaps later for file leases) |
@@ -467,8 +500,8 @@ returned success. | |||
467 | 500 | ||
468 | Also note that "cat /proc/fs/cifs/DebugData" will display information about | 501 | Also note that "cat /proc/fs/cifs/DebugData" will display information about |
469 | the active sessions and the shares that are mounted. Note: NTLMv2 enablement | 502 | the active sessions and the shares that are mounted. Note: NTLMv2 enablement |
470 | will not work since they its implementation is not quite complete yet. | 503 | will not work since its implementation is not quite complete yet. Do not alter |
471 | Do not alter these configuration values unless you are doing specific testing. | 504 | the ExtendedSecurity configuration value unless you are doing specific testing. |
472 | Enabling extended security works to Windows 2000 Workstations and XP but not to | 505 | Enabling extended security works to Windows 2000 Workstations and XP but not to |
473 | Windows 2000 server or Samba since it does not usually send "raw NTLMSSP" | 506 | Windows 2000 server or Samba since it does not usually send "raw NTLMSSP" |
474 | (instead it sends NTLMSSP encapsulated in SPNEGO/GSSAPI, which support is not | 507 | (instead it sends NTLMSSP encapsulated in SPNEGO/GSSAPI, which support is not |
diff --git a/fs/cifs/TODO b/fs/cifs/TODO index f4e3e1f67ee4..8cc881694e29 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO | |||
@@ -1,4 +1,4 @@ | |||
1 | version 1.22 July 30, 2004 | 1 | version 1.34 April 29, 2005 |
2 | 2 | ||
3 | A Partial List of Missing Features | 3 | A Partial List of Missing Features |
4 | ================================== | 4 | ================================== |
@@ -14,7 +14,7 @@ b) Better pam/winbind integration (e.g. to handle uid mapping | |||
14 | better) | 14 | better) |
15 | 15 | ||
16 | c) multi-user mounts - multiplexed sessionsetups over single vc | 16 | c) multi-user mounts - multiplexed sessionsetups over single vc |
17 | (ie tcp session) - prettying up needed, and more testing needed | 17 | (ie tcp session) - more testing needed |
18 | 18 | ||
19 | d) Kerberos/SPNEGO session setup support - (started) | 19 | d) Kerberos/SPNEGO session setup support - (started) |
20 | 20 | ||
@@ -67,12 +67,26 @@ q) implement support for security and trusted categories of xattrs | |||
67 | 67 | ||
68 | r) Implement O_DIRECT flag on open (already supported on mount) | 68 | r) Implement O_DIRECT flag on open (already supported on mount) |
69 | 69 | ||
70 | KNOWN BUGS (updated December 10, 2004) | 70 | s) Allow remapping of last remaining character (\) to +0xF000 which |
71 | (this character is valid for POSIX but not for Windows) | ||
72 | |||
73 | t) Create UID mapping facility so server UIDs can be mapped on a per | ||
74 | mount or a per server basis to client UIDs or nobody if no mapping | ||
75 | exists. This is helpful when Unix extensions are negotiated to | ||
76 | allow better permission checking when UIDs differ on the server | ||
77 | and client. Add new protocol request to the CIFS protocol | ||
78 | standard for asking the server for the corresponding name of a | ||
79 | particular uid. | ||
80 | |||
81 | KNOWN BUGS (updated April 29, 2005) | ||
71 | ==================================== | 82 | ==================================== |
83 | See http://bugzilla.samba.org - search on product "CifsVFS" for | ||
84 | current bug list. | ||
85 | |||
72 | 1) existing symbolic links (Windows reparse points) are recognized but | 86 | 1) existing symbolic links (Windows reparse points) are recognized but |
73 | can not be created remotely. They are implemented for Samba and those that | 87 | can not be created remotely. They are implemented for Samba and those that |
74 | support the CIFS Unix extensions but Samba has a bug currently handling | 88 | support the CIFS Unix extensions, although earlier versions of Samba |
75 | symlink text beginning with slash | 89 | overly restrict the pathnames. |
76 | 2) follow_link and readdir code does not follow dfs junctions | 90 | 2) follow_link and readdir code does not follow dfs junctions |
77 | but recognizes them | 91 | but recognizes them |
78 | 3) create of new files to FAT partitions on Windows servers can | 92 | 3) create of new files to FAT partitions on Windows servers can |
@@ -98,7 +112,5 @@ there are some easy changes that can be done to parallelize sequential writes, | |||
98 | and when signing is disabled to request larger read sizes (larger than | 112 | and when signing is disabled to request larger read sizes (larger than |
99 | negotiated size) and send larger write sizes to modern servers. | 113 | negotiated size) and send larger write sizes to modern servers. |
100 | 114 | ||
101 | 4) More exhaustively test the recently added NT4 support against various | 115 | 4) More exhaustively test against less common servers. More testing |
102 | NT4 service pack levels, and fix cifs_setattr for setting file times and | 116 | against Windows 9x, Windows ME servers. |
103 | size to fall back to level 1 when error invalid level returned. | ||
104 | |||
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index db28b561cd4b..4061e43471c1 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs_debug.c | 2 | * fs/cifs_debug.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2000,2003 | 4 | * Copyright (C) International Business Machines Corp., 2000,2005 |
5 | * | 5 | * |
6 | * Modified by Steve French (sfrench@us.ibm.com) | 6 | * Modified by Steve French (sfrench@us.ibm.com) |
7 | * | 7 | * |
@@ -29,6 +29,7 @@ | |||
29 | #include "cifsglob.h" | 29 | #include "cifsglob.h" |
30 | #include "cifsproto.h" | 30 | #include "cifsproto.h" |
31 | #include "cifs_debug.h" | 31 | #include "cifs_debug.h" |
32 | #include "cifsfs.h" | ||
32 | 33 | ||
33 | void | 34 | void |
34 | cifs_dump_mem(char *label, void *data, int length) | 35 | cifs_dump_mem(char *label, void *data, int length) |
@@ -78,8 +79,9 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
78 | "Display Internal CIFS Data Structures for Debugging\n" | 79 | "Display Internal CIFS Data Structures for Debugging\n" |
79 | "---------------------------------------------------\n"); | 80 | "---------------------------------------------------\n"); |
80 | buf += length; | 81 | buf += length; |
81 | 82 | length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION); | |
82 | length = sprintf(buf, "Servers:\n"); | 83 | buf += length; |
84 | length = sprintf(buf, "Servers:"); | ||
83 | buf += length; | 85 | buf += length; |
84 | 86 | ||
85 | i = 0; | 87 | i = 0; |
@@ -87,12 +89,21 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
87 | list_for_each(tmp, &GlobalSMBSessionList) { | 89 | list_for_each(tmp, &GlobalSMBSessionList) { |
88 | i++; | 90 | i++; |
89 | ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); | 91 | ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); |
90 | length = | 92 | if((ses->serverDomain == NULL) || (ses->serverOS == NULL) || |
91 | sprintf(buf, | 93 | (ses->serverNOS == NULL)) { |
92 | "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\t", | 94 | buf += sprintf("\nentry for %s not fully displayed\n\t", |
93 | i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse), | 95 | ses->serverName); |
94 | ses->serverOS, ses->serverNOS, ses->capabilities,ses->status); | 96 | |
95 | buf += length; | 97 | } else { |
98 | length = | ||
99 | sprintf(buf, | ||
100 | "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\t", | ||
101 | i, ses->serverName, ses->serverDomain, | ||
102 | atomic_read(&ses->inUse), | ||
103 | ses->serverOS, ses->serverNOS, | ||
104 | ses->capabilities,ses->status); | ||
105 | buf += length; | ||
106 | } | ||
96 | if(ses->server) { | 107 | if(ses->server) { |
97 | buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d", | 108 | buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d", |
98 | ses->server->tcpStatus, | 109 | ses->server->tcpStatus, |
@@ -100,7 +111,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
100 | ses->server->secMode, | 111 | ses->server->secMode, |
101 | atomic_read(&ses->server->inFlight)); | 112 | atomic_read(&ses->server->inFlight)); |
102 | 113 | ||
103 | length = sprintf(buf, "\nMIDs: \n"); | 114 | length = sprintf(buf, "\nMIDs:\n"); |
104 | buf += length; | 115 | buf += length; |
105 | 116 | ||
106 | spin_lock(&GlobalMid_Lock); | 117 | spin_lock(&GlobalMid_Lock); |
@@ -109,7 +120,12 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
109 | mid_q_entry, | 120 | mid_q_entry, |
110 | qhead); | 121 | qhead); |
111 | if(mid_entry) { | 122 | if(mid_entry) { |
112 | length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p mid %d\n",mid_entry->midState,mid_entry->command,mid_entry->pid,mid_entry->tsk,mid_entry->mid); | 123 | length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p mid %d\n", |
124 | mid_entry->midState, | ||
125 | (int)mid_entry->command, | ||
126 | mid_entry->pid, | ||
127 | mid_entry->tsk, | ||
128 | mid_entry->mid); | ||
113 | buf += length; | 129 | buf += length; |
114 | } | 130 | } |
115 | } | 131 | } |
@@ -121,7 +137,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
121 | sprintf(buf, "\n"); | 137 | sprintf(buf, "\n"); |
122 | buf++; | 138 | buf++; |
123 | 139 | ||
124 | length = sprintf(buf, "\nShares:\n"); | 140 | length = sprintf(buf, "Shares:"); |
125 | buf += length; | 141 | buf += length; |
126 | 142 | ||
127 | i = 0; | 143 | i = 0; |
@@ -200,7 +216,8 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
200 | buf += item_length; | 216 | buf += item_length; |
201 | item_length = | 217 | item_length = |
202 | sprintf(buf,"SMB Request/Response Buffer: %d Pool size: %d\n", | 218 | sprintf(buf,"SMB Request/Response Buffer: %d Pool size: %d\n", |
203 | bufAllocCount.counter,cifs_min_rcv + tcpSesAllocCount.counter); | 219 | bufAllocCount.counter, |
220 | cifs_min_rcv + tcpSesAllocCount.counter); | ||
204 | length += item_length; | 221 | length += item_length; |
205 | buf += item_length; | 222 | buf += item_length; |
206 | item_length = | 223 | item_length = |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 77da902d8f32..ec00d61d5308 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ | 23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ |
24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ | 24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ |
25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ | 25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ |
26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ | ||
26 | 27 | ||
27 | struct cifs_sb_info { | 28 | struct cifs_sb_info { |
28 | struct cifsTconInfo *tcon; /* primary mount */ | 29 | struct cifsTconInfo *tcon; /* primary mount */ |
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index a17adf4cb9ba..99a096d3f84d 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
@@ -76,8 +76,8 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len, | |||
76 | charlen)); | 76 | charlen)); |
77 | to[i] = cpu_to_le16(0x003f); /* a question mark */ | 77 | to[i] = cpu_to_le16(0x003f); /* a question mark */ |
78 | charlen = 1; | 78 | charlen = 1; |
79 | } | 79 | } else |
80 | to[i] = cpu_to_le16(to[i]); | 80 | to[i] = cpu_to_le16(to[i]); |
81 | 81 | ||
82 | } | 82 | } |
83 | 83 | ||
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 78829e7d8cd0..1959c7c4b185 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -50,7 +50,7 @@ static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses, | 53 | int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server, |
54 | __u32 * pexpected_response_sequence_number) | 54 | __u32 * pexpected_response_sequence_number) |
55 | { | 55 | { |
56 | int rc = 0; | 56 | int rc = 0; |
@@ -59,21 +59,21 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses, | |||
59 | /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */ | 59 | /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */ |
60 | /* BB remember to add code to save expected sequence number in midQ entry BB */ | 60 | /* BB remember to add code to save expected sequence number in midQ entry BB */ |
61 | 61 | ||
62 | if((cifs_pdu == NULL) || (ses == NULL)) | 62 | if((cifs_pdu == NULL) || (server == NULL)) |
63 | return -EINVAL; | 63 | return -EINVAL; |
64 | 64 | ||
65 | if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) | 65 | if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) |
66 | return rc; | 66 | return rc; |
67 | 67 | ||
68 | spin_lock(&GlobalMid_Lock); | 68 | spin_lock(&GlobalMid_Lock); |
69 | cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(ses->sequence_number); | 69 | cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(server->sequence_number); |
70 | cifs_pdu->Signature.Sequence.Reserved = 0; | 70 | cifs_pdu->Signature.Sequence.Reserved = 0; |
71 | 71 | ||
72 | *pexpected_response_sequence_number = ses->sequence_number++; | 72 | *pexpected_response_sequence_number = server->sequence_number++; |
73 | ses->sequence_number++; | 73 | server->sequence_number++; |
74 | spin_unlock(&GlobalMid_Lock); | 74 | spin_unlock(&GlobalMid_Lock); |
75 | 75 | ||
76 | rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature); | 76 | rc = cifs_calculate_signature(cifs_pdu, server->mac_signing_key,smb_signature); |
77 | if(rc) | 77 | if(rc) |
78 | memset(cifs_pdu->Signature.SecuritySignature, 0, 8); | 78 | memset(cifs_pdu->Signature.SecuritySignature, 0, 8); |
79 | else | 79 | else |
@@ -190,7 +190,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_ | |||
190 | hmac_md5_update((const unsigned char *) unicode_buf, | 190 | hmac_md5_update((const unsigned char *) unicode_buf, |
191 | (user_name_len+dom_name_len)*2,&ctx); | 191 | (user_name_len+dom_name_len)*2,&ctx); |
192 | 192 | ||
193 | hmac_md5_final(ses->mac_signing_key,&ctx); | 193 | hmac_md5_final(ses->server->mac_signing_key,&ctx); |
194 | kfree(ucase_buf); | 194 | kfree(ucase_buf); |
195 | kfree(unicode_buf); | 195 | kfree(unicode_buf); |
196 | return 0; | 196 | return 0; |
@@ -200,7 +200,7 @@ void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_respon | |||
200 | struct HMACMD5Context context; | 200 | struct HMACMD5Context context; |
201 | memcpy(v2_session_response + 8, ses->server->cryptKey,8); | 201 | memcpy(v2_session_response + 8, ses->server->cryptKey,8); |
202 | /* gen_blob(v2_session_response + 16); */ | 202 | /* gen_blob(v2_session_response + 16); */ |
203 | hmac_md5_init_limK_to_64(ses->mac_signing_key, 16, &context); | 203 | hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context); |
204 | 204 | ||
205 | hmac_md5_update(ses->server->cryptKey,8,&context); | 205 | hmac_md5_update(ses->server->cryptKey,8,&context); |
206 | /* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */ | 206 | /* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5082fce3c566..8cc23e7d0d5d 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -169,7 +169,8 @@ cifs_put_super(struct super_block *sb) | |||
169 | static int | 169 | static int |
170 | cifs_statfs(struct super_block *sb, struct kstatfs *buf) | 170 | cifs_statfs(struct super_block *sb, struct kstatfs *buf) |
171 | { | 171 | { |
172 | int xid, rc = -EOPNOTSUPP; | 172 | int xid; |
173 | int rc = -EOPNOTSUPP; | ||
173 | struct cifs_sb_info *cifs_sb; | 174 | struct cifs_sb_info *cifs_sb; |
174 | struct cifsTconInfo *pTcon; | 175 | struct cifsTconInfo *pTcon; |
175 | 176 | ||
@@ -181,31 +182,34 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf) | |||
181 | buf->f_type = CIFS_MAGIC_NUMBER; | 182 | buf->f_type = CIFS_MAGIC_NUMBER; |
182 | 183 | ||
183 | /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */ | 184 | /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */ |
184 | buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would presumably | 185 | buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would |
185 | be length of total path, note that some servers may be | 186 | presumably be total path, but note |
186 | able to support more than this, but best to be safe | 187 | that some servers (includinng Samba 3) |
187 | since Win2k and others can not handle very long filenames */ | 188 | have a shorter maximum path */ |
188 | buf->f_files = 0; /* undefined */ | 189 | buf->f_files = 0; /* undefined */ |
189 | buf->f_ffree = 0; /* unlimited */ | 190 | buf->f_ffree = 0; /* unlimited */ |
190 | 191 | ||
191 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 192 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
192 | /* BB we could add a second check for a QFS Unix capability bit */ | 193 | /* BB we could add a second check for a QFS Unix capability bit */ |
193 | if (pTcon->ses->capabilities & CAP_UNIX) | 194 | /* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */ |
194 | rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf, cifs_sb->local_nls); | 195 | if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS & |
196 | le64_to_cpu(pTcon->fsUnixInfo.Capability))) | ||
197 | rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf); | ||
195 | 198 | ||
196 | /* Only need to call the old QFSInfo if failed | 199 | /* Only need to call the old QFSInfo if failed |
197 | on newer one */ | 200 | on newer one */ |
198 | if(rc) | 201 | if(rc) |
199 | #endif /* CIFS_EXPERIMENTAL */ | 202 | #endif /* CIFS_EXPERIMENTAL */ |
200 | rc = CIFSSMBQFSInfo(xid, pTcon, buf, cifs_sb->local_nls); | 203 | rc = CIFSSMBQFSInfo(xid, pTcon, buf); |
201 | 204 | ||
202 | /* | 205 | /* |
203 | int f_type; | 206 | int f_type; |
204 | __fsid_t f_fsid; | 207 | __fsid_t f_fsid; |
205 | int f_namelen; */ | 208 | int f_namelen; */ |
206 | /* BB get from info put in tcon struct at mount time with call to QFSAttrInfo */ | 209 | /* BB get from info in tcon struct at mount time call to QFSAttrInfo */ |
207 | FreeXid(xid); | 210 | FreeXid(xid); |
208 | return 0; /* always return success? what if volume is no longer available? */ | 211 | return 0; /* always return success? what if volume is no |
212 | longer available? */ | ||
209 | } | 213 | } |
210 | 214 | ||
211 | static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) | 215 | static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) |
@@ -559,6 +563,10 @@ struct file_operations cifs_file_ops = { | |||
559 | .flush = cifs_flush, | 563 | .flush = cifs_flush, |
560 | .mmap = cifs_file_mmap, | 564 | .mmap = cifs_file_mmap, |
561 | .sendfile = generic_file_sendfile, | 565 | .sendfile = generic_file_sendfile, |
566 | #ifdef CONFIG_CIFS_POSIX | ||
567 | .ioctl = cifs_ioctl, | ||
568 | #endif /* CONFIG_CIFS_POSIX */ | ||
569 | |||
562 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 570 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
563 | .readv = generic_file_readv, | 571 | .readv = generic_file_readv, |
564 | .writev = generic_file_writev, | 572 | .writev = generic_file_writev, |
@@ -579,6 +587,10 @@ struct file_operations cifs_file_direct_ops = { | |||
579 | .fsync = cifs_fsync, | 587 | .fsync = cifs_fsync, |
580 | .flush = cifs_flush, | 588 | .flush = cifs_flush, |
581 | .sendfile = generic_file_sendfile, /* BB removeme BB */ | 589 | .sendfile = generic_file_sendfile, /* BB removeme BB */ |
590 | #ifdef CONFIG_CIFS_POSIX | ||
591 | .ioctl = cifs_ioctl, | ||
592 | #endif /* CONFIG_CIFS_POSIX */ | ||
593 | |||
582 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 594 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
583 | .dir_notify = cifs_dir_notify, | 595 | .dir_notify = cifs_dir_notify, |
584 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 596 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
@@ -591,6 +603,7 @@ struct file_operations cifs_dir_ops = { | |||
591 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 603 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
592 | .dir_notify = cifs_dir_notify, | 604 | .dir_notify = cifs_dir_notify, |
593 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 605 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
606 | .ioctl = cifs_ioctl, | ||
594 | }; | 607 | }; |
595 | 608 | ||
596 | static void | 609 | static void |
@@ -822,6 +835,7 @@ static int cifs_oplock_thread(void * dummyarg) | |||
822 | } | 835 | } |
823 | } while(!signal_pending(current)); | 836 | } while(!signal_pending(current)); |
824 | complete_and_exit (&cifs_oplock_exited, 0); | 837 | complete_and_exit (&cifs_oplock_exited, 0); |
838 | oplockThread = NULL; | ||
825 | } | 839 | } |
826 | 840 | ||
827 | static int __init | 841 | static int __init |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 451f18af3206..d00b3bfe1a52 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsfs.h | 2 | * fs/cifs/cifsfs.h |
3 | * | 3 | * |
4 | * Copyright (c) International Business Machines Corp., 2002 | 4 | * Copyright (c) International Business Machines Corp., 2002, 2005 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -91,8 +91,10 @@ extern int cifs_symlink(struct inode *inode, struct dentry *direntry, | |||
91 | const char *symname); | 91 | const char *symname); |
92 | extern int cifs_removexattr(struct dentry *, const char *); | 92 | extern int cifs_removexattr(struct dentry *, const char *); |
93 | extern int cifs_setxattr(struct dentry *, const char *, const void *, | 93 | extern int cifs_setxattr(struct dentry *, const char *, const void *, |
94 | size_t, int); | 94 | size_t, int); |
95 | extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | 95 | extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); |
96 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 96 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
97 | #define CIFS_VERSION "1.31" | 97 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
98 | unsigned int command, unsigned long arg); | ||
99 | #define CIFS_VERSION "1.34" | ||
98 | #endif /* _CIFSFS_H */ | 100 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 69aff1a7da9b..81babab265e1 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsglob.h | 2 | * fs/cifs/cifsglob.h |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2003 | 4 | * Copyright (C) International Business Machines Corp., 2002,2005 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -149,6 +149,8 @@ struct TCP_Server_Info { | |||
149 | __u16 timeZone; | 149 | __u16 timeZone; |
150 | char cryptKey[CIFS_CRYPTO_KEY_SIZE]; | 150 | char cryptKey[CIFS_CRYPTO_KEY_SIZE]; |
151 | char workstation_RFC1001_name[16]; /* 16th byte is always zero */ | 151 | char workstation_RFC1001_name[16]; /* 16th byte is always zero */ |
152 | __u32 sequence_number; /* needed for CIFS PDU signature */ | ||
153 | char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; | ||
152 | }; | 154 | }; |
153 | 155 | ||
154 | /* | 156 | /* |
@@ -174,17 +176,16 @@ struct cifsSesInfo { | |||
174 | struct TCP_Server_Info *server; /* pointer to server info */ | 176 | struct TCP_Server_Info *server; /* pointer to server info */ |
175 | atomic_t inUse; /* # of mounts (tree connections) on this ses */ | 177 | atomic_t inUse; /* # of mounts (tree connections) on this ses */ |
176 | enum statusEnum status; | 178 | enum statusEnum status; |
177 | __u32 sequence_number; /* needed for CIFS PDU signature */ | ||
178 | __u16 ipc_tid; /* special tid for connection to IPC share */ | 179 | __u16 ipc_tid; /* special tid for connection to IPC share */ |
179 | __u16 flags; | 180 | __u16 flags; |
180 | char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; | 181 | char *serverOS; /* name of operating system underlying server */ |
181 | char *serverOS; /* name of operating system underlying the server */ | 182 | char *serverNOS; /* name of network operating system of server */ |
182 | char *serverNOS; /* name of network operating system that the server is running */ | ||
183 | char *serverDomain; /* security realm of server */ | 183 | char *serverDomain; /* security realm of server */ |
184 | int Suid; /* remote smb uid */ | 184 | int Suid; /* remote smb uid */ |
185 | uid_t linux_uid; /* local Linux uid */ | 185 | uid_t linux_uid; /* local Linux uid */ |
186 | int capabilities; | 186 | int capabilities; |
187 | char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for tcp names - will ipv6 and sctp addresses fit here?? */ | 187 | char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for |
188 | TCP names - will ipv6 and sctp addresses fit? */ | ||
188 | char userName[MAX_USERNAME_SIZE + 1]; | 189 | char userName[MAX_USERNAME_SIZE + 1]; |
189 | char domainName[MAX_USERNAME_SIZE + 1]; | 190 | char domainName[MAX_USERNAME_SIZE + 1]; |
190 | char * password; | 191 | char * password; |
@@ -312,12 +313,15 @@ struct mid_q_entry { | |||
312 | __u16 mid; /* multiplex id */ | 313 | __u16 mid; /* multiplex id */ |
313 | __u16 pid; /* process id */ | 314 | __u16 pid; /* process id */ |
314 | __u32 sequence_number; /* for CIFS signing */ | 315 | __u32 sequence_number; /* for CIFS signing */ |
315 | __u16 command; /* smb command code */ | ||
316 | struct timeval when_sent; /* time when smb sent */ | 316 | struct timeval when_sent; /* time when smb sent */ |
317 | struct cifsSesInfo *ses; /* smb was sent to this server */ | 317 | struct cifsSesInfo *ses; /* smb was sent to this server */ |
318 | struct task_struct *tsk; /* task waiting for response */ | 318 | struct task_struct *tsk; /* task waiting for response */ |
319 | struct smb_hdr *resp_buf; /* response buffer */ | 319 | struct smb_hdr *resp_buf; /* response buffer */ |
320 | int midState; /* wish this were enum but can not pass to wait_event */ | 320 | int midState; /* wish this were enum but can not pass to wait_event */ |
321 | __u8 command; /* smb command code */ | ||
322 | unsigned multiPart:1; /* multiple responses to one SMB request */ | ||
323 | unsigned largeBuf:1; /* if valid response, is pointer to large buf */ | ||
324 | unsigned multiResp:1; /* multiple trans2 responses for one request */ | ||
321 | }; | 325 | }; |
322 | 326 | ||
323 | struct oplock_q_entry { | 327 | struct oplock_q_entry { |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index bcd4a6136f08..aede6a813167 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -330,7 +330,7 @@ struct smb_hdr { | |||
330 | }; | 330 | }; |
331 | /* given a pointer to an smb_hdr retrieve the value of byte count */ | 331 | /* given a pointer to an smb_hdr retrieve the value of byte count */ |
332 | #define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) | 332 | #define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) |
333 | 333 | #define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) | |
334 | /* given a pointer to an smb_hdr retrieve the pointer to the byte area */ | 334 | /* given a pointer to an smb_hdr retrieve the pointer to the byte area */ |
335 | #define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 ) | 335 | #define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 ) |
336 | 336 | ||
@@ -762,6 +762,16 @@ typedef struct smb_com_lock_req { | |||
762 | LOCKING_ANDX_RANGE Locks[1]; | 762 | LOCKING_ANDX_RANGE Locks[1]; |
763 | } LOCK_REQ; | 763 | } LOCK_REQ; |
764 | 764 | ||
765 | |||
766 | typedef struct cifs_posix_lock { | ||
767 | __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */ | ||
768 | __le16 lock_flags; /* 1 = Wait (only valid for setlock) */ | ||
769 | __le32 pid; | ||
770 | __le64 start; | ||
771 | __le64 length; | ||
772 | /* BB what about additional owner info to identify network client */ | ||
773 | } CIFS_POSIX_LOCK; | ||
774 | |||
765 | typedef struct smb_com_lock_rsp { | 775 | typedef struct smb_com_lock_rsp { |
766 | struct smb_hdr hdr; /* wct = 2 */ | 776 | struct smb_hdr hdr; /* wct = 2 */ |
767 | __u8 AndXCommand; | 777 | __u8 AndXCommand; |
@@ -1098,6 +1108,8 @@ struct smb_t2_rsp { | |||
1098 | #define SMB_QUERY_POSIX_ACL 0x204 | 1108 | #define SMB_QUERY_POSIX_ACL 0x204 |
1099 | #define SMB_QUERY_XATTR 0x205 | 1109 | #define SMB_QUERY_XATTR 0x205 |
1100 | #define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ | 1110 | #define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ |
1111 | #define SMB_QUERY_POSIX_PERMISSION 0x207 | ||
1112 | #define SMB_QUERY_POSIX_LOCK 0x208 | ||
1101 | #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee | 1113 | #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee |
1102 | #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 | 1114 | #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 |
1103 | #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ | 1115 | #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ |
@@ -1116,6 +1128,7 @@ struct smb_t2_rsp { | |||
1116 | #define SMB_SET_POSIX_ACL 0x204 | 1128 | #define SMB_SET_POSIX_ACL 0x204 |
1117 | #define SMB_SET_XATTR 0x205 | 1129 | #define SMB_SET_XATTR 0x205 |
1118 | #define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ | 1130 | #define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ |
1131 | #define SMB_SET_POSIX_LOCK 0x208 | ||
1119 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec | 1132 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec |
1120 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ | 1133 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ |
1121 | #define SMB_FILE_ALL_INFO2 0x3fa | 1134 | #define SMB_FILE_ALL_INFO2 0x3fa |
@@ -1237,9 +1250,25 @@ struct smb_com_transaction2_sfi_rsp { | |||
1237 | struct smb_hdr hdr; /* wct = 10 + SetupCount */ | 1250 | struct smb_hdr hdr; /* wct = 10 + SetupCount */ |
1238 | struct trans2_resp t2; | 1251 | struct trans2_resp t2; |
1239 | __u16 ByteCount; | 1252 | __u16 ByteCount; |
1240 | __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ | 1253 | __u16 Reserved2; /* parameter word reserved - |
1254 | present for infolevels > 100 */ | ||
1255 | }; | ||
1256 | |||
1257 | struct smb_t2_qfi_req { | ||
1258 | struct smb_hdr hdr; | ||
1259 | struct trans2_req t2; | ||
1260 | __u8 Pad; | ||
1261 | __u16 Fid; | ||
1262 | __le16 InformationLevel; | ||
1241 | }; | 1263 | }; |
1242 | 1264 | ||
1265 | struct smb_t2_qfi_rsp { | ||
1266 | struct smb_hdr hdr; /* wct = 10 + SetupCount */ | ||
1267 | struct trans2_resp t2; | ||
1268 | __u16 ByteCount; | ||
1269 | __u16 Reserved2; /* parameter word reserved - | ||
1270 | present for infolevels > 100 */ | ||
1271 | }; | ||
1243 | 1272 | ||
1244 | /* | 1273 | /* |
1245 | * Flags on T2 FINDFIRST and FINDNEXT | 1274 | * Flags on T2 FINDFIRST and FINDNEXT |
@@ -1524,9 +1553,10 @@ typedef struct { | |||
1524 | } FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ | 1553 | } FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ |
1525 | /* Linux/Unix extensions capability flags */ | 1554 | /* Linux/Unix extensions capability flags */ |
1526 | #define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */ | 1555 | #define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */ |
1527 | #define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 | 1556 | #define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */ |
1528 | #define CIFS_UNIX_XATTR_CAP 0x00000004 /*support for new namespace*/ | 1557 | #define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */ |
1529 | 1558 | #define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */ | |
1559 | #define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */ | ||
1530 | typedef struct { | 1560 | typedef struct { |
1531 | /* For undefined recommended transfer size return -1 in that field */ | 1561 | /* For undefined recommended transfer size return -1 in that field */ |
1532 | __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ | 1562 | __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ |
@@ -1971,14 +2001,39 @@ struct xsymlink { | |||
1971 | char path[1024]; | 2001 | char path[1024]; |
1972 | }; | 2002 | }; |
1973 | 2003 | ||
1974 | typedef struct { | 2004 | typedef struct file_xattr_info { |
1975 | /* BB do we need another field for flags? BB */ | 2005 | /* BB do we need another field for flags? BB */ |
1976 | __u32 xattr_name_len; | 2006 | __u32 xattr_name_len; |
1977 | __u32 xattr_value_len; | 2007 | __u32 xattr_value_len; |
1978 | char xattr_name[0]; | 2008 | char xattr_name[0]; |
1979 | /* followed by xattr_value[xattr_value_len], no pad */ | 2009 | /* followed by xattr_value[xattr_value_len], no pad */ |
1980 | } FILE_XATTR_INFO; /* extended attribute, info level 205 */ | 2010 | } FILE_XATTR_INFO; /* extended attribute, info level 0x205 */ |
1981 | 2011 | ||
2012 | |||
2013 | /* flags for chattr command */ | ||
2014 | #define EXT_SECURE_DELETE 0x00000001 /* EXT3_SECRM_FL */ | ||
2015 | #define EXT_ENABLE_UNDELETE 0x00000002 /* EXT3_UNRM_FL */ | ||
2016 | /* Reserved for compress file 0x4 */ | ||
2017 | #define EXT_SYNCHRONOUS 0x00000008 /* EXT3_SYNC_FL */ | ||
2018 | #define EXT_IMMUTABLE_FL 0x00000010 /* EXT3_IMMUTABLE_FL */ | ||
2019 | #define EXT_OPEN_APPEND_ONLY 0x00000020 /* EXT3_APPEND_FL */ | ||
2020 | #define EXT_DO_NOT_BACKUP 0x00000040 /* EXT3_NODUMP_FL */ | ||
2021 | #define EXT_NO_UPDATE_ATIME 0x00000080 /* EXT3_NOATIME_FL */ | ||
2022 | /* 0x100 through 0x800 reserved for compression flags and are GET-ONLY */ | ||
2023 | #define EXT_HASH_TREE_INDEXED_DIR 0x00001000 /* GET-ONLY EXT3_INDEX_FL */ | ||
2024 | /* 0x2000 reserved for IMAGIC_FL */ | ||
2025 | #define EXT_JOURNAL_THIS_FILE 0x00004000 /* GET-ONLY EXT3_JOURNAL_DATA_FL */ | ||
2026 | /* 0x8000 reserved for EXT3_NOTAIL_FL */ | ||
2027 | #define EXT_SYNCHRONOUS_DIR 0x00010000 /* EXT3_DIRSYNC_FL */ | ||
2028 | #define EXT_TOPDIR 0x00020000 /* EXT3_TOPDIR_FL */ | ||
2029 | |||
2030 | #define EXT_SET_MASK 0x000300FF | ||
2031 | #define EXT_GET_MASK 0x0003DFFF | ||
2032 | |||
2033 | typedef struct file_chattr_info { | ||
2034 | __le64 mask; /* list of all possible attribute bits */ | ||
2035 | __le64 mode; /* list of actual attribute bits on this inode */ | ||
2036 | } FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ | ||
1982 | 2037 | ||
1983 | #endif | 2038 | #endif |
1984 | 2039 | ||
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 787eef4d86d3..0010511083fc 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -57,10 +57,11 @@ extern int decode_negTokenInit(unsigned char *security_blob, int length, | |||
57 | extern int cifs_inet_pton(int, char * source, void *dst); | 57 | extern int cifs_inet_pton(int, char * source, void *dst); |
58 | extern int map_smb_to_linux_error(struct smb_hdr *smb); | 58 | extern int map_smb_to_linux_error(struct smb_hdr *smb); |
59 | extern void header_assemble(struct smb_hdr *, char /* command */ , | 59 | extern void header_assemble(struct smb_hdr *, char /* command */ , |
60 | const struct cifsTconInfo *, int | 60 | const struct cifsTconInfo *, int /* specifies length |
61 | /* length of fixed section (word count) in two byte units */ | 61 | of fixed section (word count) in two byte units */ |
62 | ); | 62 | ); |
63 | extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *); | 63 | extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, |
64 | struct cifsTconInfo *); | ||
64 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 65 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
65 | extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); | 66 | extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); |
66 | extern u64 cifs_UnixTimeToNT(struct timespec); | 67 | extern u64 cifs_UnixTimeToNT(struct timespec); |
@@ -88,7 +89,7 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
88 | 89 | ||
89 | extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, | 90 | extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, |
90 | const char *searchName, const struct nls_table *nls_codepage, | 91 | const char *searchName, const struct nls_table *nls_codepage, |
91 | __u16 *searchHandle, struct cifs_search_info * psrch_inf); | 92 | __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map); |
92 | 93 | ||
93 | extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, | 94 | extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, |
94 | __u16 searchHandle, struct cifs_search_info * psrch_inf); | 95 | __u16 searchHandle, struct cifs_search_info * psrch_inf); |
@@ -99,42 +100,42 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, | |||
99 | extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, | 100 | extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, |
100 | const unsigned char *searchName, | 101 | const unsigned char *searchName, |
101 | FILE_ALL_INFO * findData, | 102 | FILE_ALL_INFO * findData, |
102 | const struct nls_table *nls_codepage); | 103 | const struct nls_table *nls_codepage, int remap); |
103 | 104 | ||
104 | extern int CIFSSMBUnixQPathInfo(const int xid, | 105 | extern int CIFSSMBUnixQPathInfo(const int xid, |
105 | struct cifsTconInfo *tcon, | 106 | struct cifsTconInfo *tcon, |
106 | const unsigned char *searchName, | 107 | const unsigned char *searchName, |
107 | FILE_UNIX_BASIC_INFO * pFindData, | 108 | FILE_UNIX_BASIC_INFO * pFindData, |
108 | const struct nls_table *nls_codepage); | 109 | const struct nls_table *nls_codepage, int remap); |
109 | 110 | ||
110 | extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, | 111 | extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, |
111 | const unsigned char *searchName, | 112 | const unsigned char *searchName, |
112 | unsigned char **targetUNCs, | 113 | unsigned char **targetUNCs, |
113 | unsigned int *number_of_UNC_in_array, | 114 | unsigned int *number_of_UNC_in_array, |
114 | const struct nls_table *nls_codepage); | 115 | const struct nls_table *nls_codepage, int remap); |
115 | 116 | ||
116 | extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | 117 | extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, |
117 | const char *old_path, | 118 | const char *old_path, |
118 | const struct nls_table *nls_codepage); | 119 | const struct nls_table *nls_codepage, int remap); |
119 | extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | 120 | extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, |
120 | const char *old_path, const struct nls_table *nls_codepage, | 121 | const char *old_path, |
121 | unsigned int *pnum_referrals, unsigned char ** preferrals); | 122 | const struct nls_table *nls_codepage, |
123 | unsigned int *pnum_referrals, | ||
124 | unsigned char ** preferrals, | ||
125 | int remap); | ||
122 | extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, | 126 | extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, |
123 | struct kstatfs *FSData, | 127 | struct kstatfs *FSData); |
124 | const struct nls_table *nls_codepage); | ||
125 | extern int CIFSSMBQFSAttributeInfo(const int xid, | 128 | extern int CIFSSMBQFSAttributeInfo(const int xid, |
126 | struct cifsTconInfo *tcon, | 129 | struct cifsTconInfo *tcon); |
127 | const struct nls_table *nls_codepage); | 130 | extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon); |
128 | extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon, | 131 | extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon); |
129 | const struct nls_table *nls_codepage); | ||
130 | extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon, | ||
131 | const struct nls_table *nls_codepage); | ||
132 | extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, | 132 | extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, |
133 | struct kstatfs *FSData, const struct nls_table *nls_codepage); | 133 | struct kstatfs *FSData); |
134 | 134 | ||
135 | extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, | 135 | extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, |
136 | const char *fileName, const FILE_BASIC_INFO * data, | 136 | const char *fileName, const FILE_BASIC_INFO * data, |
137 | const struct nls_table *nls_codepage); | 137 | const struct nls_table *nls_codepage, |
138 | int remap_special_chars); | ||
138 | extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, | 139 | extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, |
139 | const FILE_BASIC_INFO * data, __u16 fid); | 140 | const FILE_BASIC_INFO * data, __u16 fid); |
140 | #if 0 | 141 | #if 0 |
@@ -143,36 +144,49 @@ extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, | |||
143 | const struct nls_table *nls_codepage); | 144 | const struct nls_table *nls_codepage); |
144 | #endif /* possibly unneeded function */ | 145 | #endif /* possibly unneeded function */ |
145 | extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, | 146 | extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, |
146 | const char *fileName, __u64 size,int setAllocationSizeFlag, | 147 | const char *fileName, __u64 size, |
147 | const struct nls_table *nls_codepage); | 148 | int setAllocationSizeFlag, |
149 | const struct nls_table *nls_codepage, | ||
150 | int remap_special_chars); | ||
148 | extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, | 151 | extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, |
149 | __u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag); | 152 | __u64 size, __u16 fileHandle,__u32 opener_pid, |
153 | int AllocSizeFlag); | ||
150 | extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, | 154 | extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, |
151 | char *full_path, __u64 mode, __u64 uid, | 155 | char *full_path, __u64 mode, __u64 uid, |
152 | __u64 gid, dev_t dev, const struct nls_table *nls_codepage); | 156 | __u64 gid, dev_t dev, |
157 | const struct nls_table *nls_codepage, | ||
158 | int remap_special_chars); | ||
153 | 159 | ||
154 | extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, | 160 | extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, |
155 | const char *newName, | 161 | const char *newName, |
156 | const struct nls_table *nls_codepage); | 162 | const struct nls_table *nls_codepage, |
163 | int remap_special_chars); | ||
157 | extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, | 164 | extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, |
158 | const char *name, const struct nls_table *nls_codepage); | 165 | const char *name, const struct nls_table *nls_codepage, |
166 | int remap_special_chars); | ||
159 | 167 | ||
160 | extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, | 168 | extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, |
161 | const char *name, | 169 | const char *name, |
162 | const struct nls_table *nls_codepage); | 170 | const struct nls_table *nls_codepage, |
171 | int remap_special_chars); | ||
163 | extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, | 172 | extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, |
164 | const char *fromName, const char *toName, | 173 | const char *fromName, const char *toName, |
165 | const struct nls_table *nls_codepage); | 174 | const struct nls_table *nls_codepage, |
175 | int remap_special_chars); | ||
166 | extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, | 176 | extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, |
167 | int netfid, char * target_name, const struct nls_table *nls_codepage); | 177 | int netfid, char * target_name, |
178 | const struct nls_table *nls_codepage, | ||
179 | int remap_special_chars); | ||
168 | extern int CIFSCreateHardLink(const int xid, | 180 | extern int CIFSCreateHardLink(const int xid, |
169 | struct cifsTconInfo *tcon, | 181 | struct cifsTconInfo *tcon, |
170 | const char *fromName, const char *toName, | 182 | const char *fromName, const char *toName, |
171 | const struct nls_table *nls_codepage); | 183 | const struct nls_table *nls_codepage, |
184 | int remap_special_chars); | ||
172 | extern int CIFSUnixCreateHardLink(const int xid, | 185 | extern int CIFSUnixCreateHardLink(const int xid, |
173 | struct cifsTconInfo *tcon, | 186 | struct cifsTconInfo *tcon, |
174 | const char *fromName, const char *toName, | 187 | const char *fromName, const char *toName, |
175 | const struct nls_table *nls_codepage); | 188 | const struct nls_table *nls_codepage, |
189 | int remap_special_chars); | ||
176 | extern int CIFSUnixCreateSymLink(const int xid, | 190 | extern int CIFSUnixCreateSymLink(const int xid, |
177 | struct cifsTconInfo *tcon, | 191 | struct cifsTconInfo *tcon, |
178 | const char *fromName, const char *toName, | 192 | const char *fromName, const char *toName, |
@@ -192,7 +206,7 @@ extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, | |||
192 | const char *fileName, const int disposition, | 206 | const char *fileName, const int disposition, |
193 | const int access_flags, const int omode, | 207 | const int access_flags, const int omode, |
194 | __u16 * netfid, int *pOplock, FILE_ALL_INFO *, | 208 | __u16 * netfid, int *pOplock, FILE_ALL_INFO *, |
195 | const struct nls_table *nls_codepage); | 209 | const struct nls_table *nls_codepage, int remap); |
196 | extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, | 210 | extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, |
197 | const int smb_file_id); | 211 | const int smb_file_id); |
198 | 212 | ||
@@ -211,8 +225,13 @@ extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
211 | const char __user *buf,const int long_op); | 225 | const char __user *buf,const int long_op); |
212 | extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, | 226 | extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, |
213 | const unsigned char *searchName, __u64 * inode_number, | 227 | const unsigned char *searchName, __u64 * inode_number, |
214 | const struct nls_table *nls_codepage); | 228 | const struct nls_table *nls_codepage, |
229 | int remap_special_chars); | ||
215 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 230 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
231 | extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen, | ||
232 | const struct nls_table * codepage); | ||
233 | extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, | ||
234 | const struct nls_table * cp, int mapChars); | ||
216 | 235 | ||
217 | extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | 236 | extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, |
218 | const __u16 netfid, const __u64 len, | 237 | const __u16 netfid, const __u64 len, |
@@ -230,7 +249,7 @@ extern void tconInfoFree(struct cifsTconInfo *); | |||
230 | 249 | ||
231 | extern int cifs_reconnect(struct TCP_Server_Info *server); | 250 | extern int cifs_reconnect(struct TCP_Server_Info *server); |
232 | 251 | ||
233 | extern int cifs_sign_smb(struct smb_hdr *, struct cifsSesInfo *,__u32 *); | 252 | extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); |
234 | extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, | 253 | extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, |
235 | __u32 expected_sequence_number); | 254 | __u32 expected_sequence_number); |
236 | extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); | 255 | extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); |
@@ -241,29 +260,31 @@ extern int CIFSSMBCopy(int xid, | |||
241 | const char *fromName, | 260 | const char *fromName, |
242 | const __u16 target_tid, | 261 | const __u16 target_tid, |
243 | const char *toName, const int flags, | 262 | const char *toName, const int flags, |
244 | const struct nls_table *nls_codepage); | 263 | const struct nls_table *nls_codepage, |
264 | int remap_special_chars); | ||
245 | extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, | 265 | extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, |
246 | const int notify_subdirs,const __u16 netfid,__u32 filter, | 266 | const int notify_subdirs,const __u16 netfid, |
247 | const struct nls_table *nls_codepage); | 267 | __u32 filter, const struct nls_table *nls_codepage); |
248 | extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, | 268 | extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, |
249 | const unsigned char *searchName, char * EAData, | 269 | const unsigned char *searchName, char * EAData, |
250 | size_t bufsize, const struct nls_table *nls_codepage); | 270 | size_t bufsize, const struct nls_table *nls_codepage, |
271 | int remap_special_chars); | ||
251 | extern ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, | 272 | extern ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, |
252 | const unsigned char * searchName,const unsigned char * ea_name, | 273 | const unsigned char * searchName,const unsigned char * ea_name, |
253 | unsigned char * ea_value, size_t buf_size, | 274 | unsigned char * ea_value, size_t buf_size, |
254 | const struct nls_table *nls_codepage); | 275 | const struct nls_table *nls_codepage, int remap_special_chars); |
255 | extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, | 276 | extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, |
256 | const char *fileName, const char * ea_name, | 277 | const char *fileName, const char * ea_name, |
257 | const void * ea_value, const __u16 ea_value_len, | 278 | const void * ea_value, const __u16 ea_value_len, |
258 | const struct nls_table *nls_codepage); | 279 | const struct nls_table *nls_codepage, int remap_special_chars); |
259 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, | 280 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, |
260 | const unsigned char *searchName, | 281 | const unsigned char *searchName, |
261 | char *acl_inf, const int buflen,const int acl_type, | 282 | char *acl_inf, const int buflen,const int acl_type, |
262 | const struct nls_table *nls_codepage); | 283 | const struct nls_table *nls_codepage, int remap_special_chars); |
263 | extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, | 284 | extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, |
264 | const unsigned char *fileName, | 285 | const unsigned char *fileName, |
265 | const char *local_acl, const int buflen, const int acl_type, | 286 | const char *local_acl, const int buflen, const int acl_type, |
266 | const struct nls_table *nls_codepage); | 287 | const struct nls_table *nls_codepage, int remap_special_chars); |
267 | int cifs_ioctl (struct inode * inode, struct file * filep, | 288 | extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, |
268 | unsigned int command, unsigned long arg); | 289 | const int netfid, __u64 * pExtAttrBits, __u64 *pMask); |
269 | #endif /* _CIFSPROTO_H */ | 290 | #endif /* _CIFSPROTO_H */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index df6a619a6821..741ff0c69f37 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -75,7 +75,8 @@ static void mark_open_files_invalid(struct cifsTconInfo * pTcon) | |||
75 | } | 75 | } |
76 | } | 76 | } |
77 | write_unlock(&GlobalSMBSeslock); | 77 | write_unlock(&GlobalSMBSeslock); |
78 | /* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */ | 78 | /* BB Add call to invalidate_inodes(sb) for all superblocks mounted |
79 | to this tcon */ | ||
79 | } | 80 | } |
80 | 81 | ||
81 | /* If the return code is zero, this function must fill in request_buf pointer */ | 82 | /* If the return code is zero, this function must fill in request_buf pointer */ |
@@ -89,11 +90,12 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
89 | check for tcp and smb session status done differently | 90 | check for tcp and smb session status done differently |
90 | for those three - in the calling routine */ | 91 | for those three - in the calling routine */ |
91 | if(tcon) { | 92 | if(tcon) { |
92 | if((tcon->ses) && (tcon->ses->server)){ | 93 | if((tcon->ses) && (tcon->ses->status != CifsExiting) && |
94 | (tcon->ses->server)){ | ||
93 | struct nls_table *nls_codepage; | 95 | struct nls_table *nls_codepage; |
94 | /* Give Demultiplex thread up to 10 seconds to | 96 | /* Give Demultiplex thread up to 10 seconds to |
95 | reconnect, should be greater than cifs socket | 97 | reconnect, should be greater than cifs socket |
96 | timeout which is 7 seconds */ | 98 | timeout which is 7 seconds */ |
97 | while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { | 99 | while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { |
98 | wait_event_interruptible_timeout(tcon->ses->server->response_q, | 100 | wait_event_interruptible_timeout(tcon->ses->server->response_q, |
99 | (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); | 101 | (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); |
@@ -103,8 +105,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
103 | (tcon->ses->status == CifsExiting)) { | 105 | (tcon->ses->status == CifsExiting)) { |
104 | cFYI(1,("gave up waiting on reconnect in smb_init")); | 106 | cFYI(1,("gave up waiting on reconnect in smb_init")); |
105 | return -EHOSTDOWN; | 107 | return -EHOSTDOWN; |
106 | } /* else "hard" mount - keep retrying until | 108 | } /* else "hard" mount - keep retrying |
107 | process is killed or server comes back up */ | 109 | until process is killed or server |
110 | comes back on-line */ | ||
108 | } else /* TCP session is reestablished now */ | 111 | } else /* TCP session is reestablished now */ |
109 | break; | 112 | break; |
110 | 113 | ||
@@ -115,23 +118,24 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
115 | simultaneously reconnect the same SMB session */ | 118 | simultaneously reconnect the same SMB session */ |
116 | down(&tcon->ses->sesSem); | 119 | down(&tcon->ses->sesSem); |
117 | if(tcon->ses->status == CifsNeedReconnect) | 120 | if(tcon->ses->status == CifsNeedReconnect) |
118 | rc = cifs_setup_session(0, tcon->ses, nls_codepage); | 121 | rc = cifs_setup_session(0, tcon->ses, |
122 | nls_codepage); | ||
119 | if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { | 123 | if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { |
120 | mark_open_files_invalid(tcon); | 124 | mark_open_files_invalid(tcon); |
121 | rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, | 125 | rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon |
122 | nls_codepage); | 126 | , nls_codepage); |
123 | up(&tcon->ses->sesSem); | 127 | up(&tcon->ses->sesSem); |
124 | if(rc == 0) | 128 | if(rc == 0) |
125 | atomic_inc(&tconInfoReconnectCount); | 129 | atomic_inc(&tconInfoReconnectCount); |
126 | 130 | ||
127 | cFYI(1, ("reconnect tcon rc = %d", rc)); | 131 | cFYI(1, ("reconnect tcon rc = %d", rc)); |
128 | /* Removed call to reopen open files here - | 132 | /* Removed call to reopen open files here - |
129 | it is safer (and faster) to reopen files | 133 | it is safer (and faster) to reopen files |
130 | one at a time as needed in read and write */ | 134 | one at a time as needed in read and write */ |
131 | 135 | ||
132 | /* Check if handle based operation so we | 136 | /* Check if handle based operation so we |
133 | know whether we can continue or not without | 137 | know whether we can continue or not without |
134 | returning to caller to reset file handle */ | 138 | returning to caller to reset file handle */ |
135 | switch(smb_command) { | 139 | switch(smb_command) { |
136 | case SMB_COM_READ_ANDX: | 140 | case SMB_COM_READ_ANDX: |
137 | case SMB_COM_WRITE_ANDX: | 141 | case SMB_COM_WRITE_ANDX: |
@@ -182,22 +186,25 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
182 | check for tcp and smb session status done differently | 186 | check for tcp and smb session status done differently |
183 | for those three - in the calling routine */ | 187 | for those three - in the calling routine */ |
184 | if(tcon) { | 188 | if(tcon) { |
185 | if((tcon->ses) && (tcon->ses->server)){ | 189 | if((tcon->ses) && (tcon->ses->status != CifsExiting) && |
190 | (tcon->ses->server)){ | ||
186 | struct nls_table *nls_codepage; | 191 | struct nls_table *nls_codepage; |
187 | /* Give Demultiplex thread up to 10 seconds to | 192 | /* Give Demultiplex thread up to 10 seconds to |
188 | reconnect, should be greater than cifs socket | 193 | reconnect, should be greater than cifs socket |
189 | timeout which is 7 seconds */ | 194 | timeout which is 7 seconds */ |
190 | while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { | 195 | while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { |
191 | wait_event_interruptible_timeout(tcon->ses->server->response_q, | 196 | wait_event_interruptible_timeout(tcon->ses->server->response_q, |
192 | (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); | 197 | (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); |
193 | if(tcon->ses->server->tcpStatus == CifsNeedReconnect) { | 198 | if(tcon->ses->server->tcpStatus == |
199 | CifsNeedReconnect) { | ||
194 | /* on "soft" mounts we wait once */ | 200 | /* on "soft" mounts we wait once */ |
195 | if((tcon->retry == FALSE) || | 201 | if((tcon->retry == FALSE) || |
196 | (tcon->ses->status == CifsExiting)) { | 202 | (tcon->ses->status == CifsExiting)) { |
197 | cFYI(1,("gave up waiting on reconnect in smb_init")); | 203 | cFYI(1,("gave up waiting on reconnect in smb_init")); |
198 | return -EHOSTDOWN; | 204 | return -EHOSTDOWN; |
199 | } /* else "hard" mount - keep retrying until | 205 | } /* else "hard" mount - keep retrying |
200 | process is killed or server comes back up */ | 206 | until process is killed or server |
207 | comes on-line */ | ||
201 | } else /* TCP session is reestablished now */ | 208 | } else /* TCP session is reestablished now */ |
202 | break; | 209 | break; |
203 | 210 | ||
@@ -208,23 +215,24 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
208 | simultaneously reconnect the same SMB session */ | 215 | simultaneously reconnect the same SMB session */ |
209 | down(&tcon->ses->sesSem); | 216 | down(&tcon->ses->sesSem); |
210 | if(tcon->ses->status == CifsNeedReconnect) | 217 | if(tcon->ses->status == CifsNeedReconnect) |
211 | rc = cifs_setup_session(0, tcon->ses, nls_codepage); | 218 | rc = cifs_setup_session(0, tcon->ses, |
219 | nls_codepage); | ||
212 | if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { | 220 | if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { |
213 | mark_open_files_invalid(tcon); | 221 | mark_open_files_invalid(tcon); |
214 | rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, | 222 | rc = CIFSTCon(0, tcon->ses, tcon->treeName, |
215 | nls_codepage); | 223 | tcon, nls_codepage); |
216 | up(&tcon->ses->sesSem); | 224 | up(&tcon->ses->sesSem); |
217 | if(rc == 0) | 225 | if(rc == 0) |
218 | atomic_inc(&tconInfoReconnectCount); | 226 | atomic_inc(&tconInfoReconnectCount); |
219 | 227 | ||
220 | cFYI(1, ("reconnect tcon rc = %d", rc)); | 228 | cFYI(1, ("reconnect tcon rc = %d", rc)); |
221 | /* Removed call to reopen open files here - | 229 | /* Removed call to reopen open files here - |
222 | it is safer (and faster) to reopen files | 230 | it is safer (and faster) to reopen files |
223 | one at a time as needed in read and write */ | 231 | one at a time as needed in read and write */ |
224 | 232 | ||
225 | /* Check if handle based operation so we | 233 | /* Check if handle based operation so we |
226 | know whether we can continue or not without | 234 | know whether we can continue or not without |
227 | returning to caller to reset file handle */ | 235 | returning to caller to reset file handle */ |
228 | switch(smb_command) { | 236 | switch(smb_command) { |
229 | case SMB_COM_READ_ANDX: | 237 | case SMB_COM_READ_ANDX: |
230 | case SMB_COM_WRITE_ANDX: | 238 | case SMB_COM_WRITE_ANDX: |
@@ -286,7 +294,8 @@ static int validate_t2(struct smb_t2_rsp * pSMB) | |||
286 | if(total_size < 512) { | 294 | if(total_size < 512) { |
287 | total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount); | 295 | total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount); |
288 | /* BCC le converted in SendReceive */ | 296 | /* BCC le converted in SendReceive */ |
289 | pBCC = (pSMB->hdr.WordCount * 2) + sizeof(struct smb_hdr) + | 297 | pBCC = (pSMB->hdr.WordCount * 2) + |
298 | sizeof(struct smb_hdr) + | ||
290 | (char *)pSMB; | 299 | (char *)pSMB; |
291 | if((total_size <= (*(u16 *)pBCC)) && | 300 | if((total_size <= (*(u16 *)pBCC)) && |
292 | (total_size < | 301 | (total_size < |
@@ -337,8 +346,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
337 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 346 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
338 | if (rc == 0) { | 347 | if (rc == 0) { |
339 | server->secMode = pSMBr->SecurityMode; | 348 | server->secMode = pSMBr->SecurityMode; |
340 | server->secType = NTLM; /* BB override default for NTLMv2 or krb*/ | 349 | server->secType = NTLM; /* BB override default for |
341 | /* one byte - no need to convert this or EncryptionKeyLen from le,*/ | 350 | NTLMv2 or kerberos v5 */ |
351 | /* one byte - no need to convert this or EncryptionKeyLen | ||
352 | from little endian */ | ||
342 | server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); | 353 | server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); |
343 | /* probably no need to store and check maxvcs */ | 354 | /* probably no need to store and check maxvcs */ |
344 | server->maxBuf = | 355 | server->maxBuf = |
@@ -374,7 +385,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
374 | pSMBr->u.extended_response. | 385 | pSMBr->u.extended_response. |
375 | GUID, 16) != 0) { | 386 | GUID, 16) != 0) { |
376 | cFYI(1, | 387 | cFYI(1, |
377 | ("UID of server does not match previous connection to same ip address")); | 388 | ("UID of server does not match previous connection to same ip address")); |
378 | memcpy(server-> | 389 | memcpy(server-> |
379 | server_GUID, | 390 | server_GUID, |
380 | pSMBr->u. | 391 | pSMBr->u. |
@@ -454,17 +465,18 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) | |||
454 | up(&tcon->tconSem); | 465 | up(&tcon->tconSem); |
455 | return -EIO; | 466 | return -EIO; |
456 | } | 467 | } |
457 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, (void **)&smb_buffer); | 468 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, |
469 | (void **)&smb_buffer); | ||
458 | if (rc) { | 470 | if (rc) { |
459 | up(&tcon->tconSem); | 471 | up(&tcon->tconSem); |
460 | return rc; | 472 | return rc; |
461 | } else { | 473 | } else { |
462 | smb_buffer_response = smb_buffer; /* BB removeme BB */ | 474 | smb_buffer_response = smb_buffer; /* BB removeme BB */ |
463 | } | 475 | } |
464 | rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response, | 476 | rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response, |
465 | &length, 0); | 477 | &length, 0); |
466 | if (rc) | 478 | if (rc) |
467 | cFYI(1, (" Tree disconnect failed %d", rc)); | 479 | cFYI(1, ("Tree disconnect failed %d", rc)); |
468 | 480 | ||
469 | if (smb_buffer) | 481 | if (smb_buffer) |
470 | cifs_small_buf_release(smb_buffer); | 482 | cifs_small_buf_release(smb_buffer); |
@@ -538,8 +550,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) | |||
538 | } | 550 | } |
539 | 551 | ||
540 | int | 552 | int |
541 | CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, | 553 | CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, |
542 | const char *fileName, const struct nls_table *nls_codepage) | 554 | const struct nls_table *nls_codepage, int remap) |
543 | { | 555 | { |
544 | DELETE_FILE_REQ *pSMB = NULL; | 556 | DELETE_FILE_REQ *pSMB = NULL; |
545 | DELETE_FILE_RSP *pSMBr = NULL; | 557 | DELETE_FILE_RSP *pSMBr = NULL; |
@@ -555,12 +567,11 @@ DelFileRetry: | |||
555 | 567 | ||
556 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 568 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
557 | name_len = | 569 | name_len = |
558 | cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, PATH_MAX | 570 | cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, |
559 | /* find define for this maxpathcomponent */ | 571 | PATH_MAX, nls_codepage, remap); |
560 | , nls_codepage); | ||
561 | name_len++; /* trailing null */ | 572 | name_len++; /* trailing null */ |
562 | name_len *= 2; | 573 | name_len *= 2; |
563 | } else { /* BB improve the check for buffer overruns BB */ | 574 | } else { /* BB improve check for buffer overruns BB */ |
564 | name_len = strnlen(fileName, PATH_MAX); | 575 | name_len = strnlen(fileName, PATH_MAX); |
565 | name_len++; /* trailing null */ | 576 | name_len++; /* trailing null */ |
566 | strncpy(pSMB->fileName, fileName, name_len); | 577 | strncpy(pSMB->fileName, fileName, name_len); |
@@ -589,8 +600,8 @@ DelFileRetry: | |||
589 | } | 600 | } |
590 | 601 | ||
591 | int | 602 | int |
592 | CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, | 603 | CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, |
593 | const char *dirName, const struct nls_table *nls_codepage) | 604 | const struct nls_table *nls_codepage, int remap) |
594 | { | 605 | { |
595 | DELETE_DIRECTORY_REQ *pSMB = NULL; | 606 | DELETE_DIRECTORY_REQ *pSMB = NULL; |
596 | DELETE_DIRECTORY_RSP *pSMBr = NULL; | 607 | DELETE_DIRECTORY_RSP *pSMBr = NULL; |
@@ -606,12 +617,11 @@ RmDirRetry: | |||
606 | return rc; | 617 | return rc; |
607 | 618 | ||
608 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 619 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
609 | name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, dirName, PATH_MAX | 620 | name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, dirName, |
610 | /* find define for this maxpathcomponent */ | 621 | PATH_MAX, nls_codepage, remap); |
611 | , nls_codepage); | ||
612 | name_len++; /* trailing null */ | 622 | name_len++; /* trailing null */ |
613 | name_len *= 2; | 623 | name_len *= 2; |
614 | } else { /* BB improve the check for buffer overruns BB */ | 624 | } else { /* BB improve check for buffer overruns BB */ |
615 | name_len = strnlen(dirName, PATH_MAX); | 625 | name_len = strnlen(dirName, PATH_MAX); |
616 | name_len++; /* trailing null */ | 626 | name_len++; /* trailing null */ |
617 | strncpy(pSMB->DirName, dirName, name_len); | 627 | strncpy(pSMB->DirName, dirName, name_len); |
@@ -639,7 +649,7 @@ RmDirRetry: | |||
639 | 649 | ||
640 | int | 650 | int |
641 | CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, | 651 | CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, |
642 | const char *name, const struct nls_table *nls_codepage) | 652 | const char *name, const struct nls_table *nls_codepage, int remap) |
643 | { | 653 | { |
644 | int rc = 0; | 654 | int rc = 0; |
645 | CREATE_DIRECTORY_REQ *pSMB = NULL; | 655 | CREATE_DIRECTORY_REQ *pSMB = NULL; |
@@ -655,12 +665,11 @@ MkDirRetry: | |||
655 | return rc; | 665 | return rc; |
656 | 666 | ||
657 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 667 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
658 | name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, name, PATH_MAX | 668 | name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, |
659 | /* find define for this maxpathcomponent */ | 669 | PATH_MAX, nls_codepage, remap); |
660 | , nls_codepage); | ||
661 | name_len++; /* trailing null */ | 670 | name_len++; /* trailing null */ |
662 | name_len *= 2; | 671 | name_len *= 2; |
663 | } else { /* BB improve the check for buffer overruns BB */ | 672 | } else { /* BB improve check for buffer overruns BB */ |
664 | name_len = strnlen(name, PATH_MAX); | 673 | name_len = strnlen(name, PATH_MAX); |
665 | name_len++; /* trailing null */ | 674 | name_len++; /* trailing null */ |
666 | strncpy(pSMB->DirName, name, name_len); | 675 | strncpy(pSMB->DirName, name, name_len); |
@@ -690,7 +699,7 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, | |||
690 | const char *fileName, const int openDisposition, | 699 | const char *fileName, const int openDisposition, |
691 | const int access_flags, const int create_options, __u16 * netfid, | 700 | const int access_flags, const int create_options, __u16 * netfid, |
692 | int *pOplock, FILE_ALL_INFO * pfile_info, | 701 | int *pOplock, FILE_ALL_INFO * pfile_info, |
693 | const struct nls_table *nls_codepage) | 702 | const struct nls_table *nls_codepage, int remap) |
694 | { | 703 | { |
695 | int rc = -EACCES; | 704 | int rc = -EACCES; |
696 | OPEN_REQ *pSMB = NULL; | 705 | OPEN_REQ *pSMB = NULL; |
@@ -710,14 +719,12 @@ openRetry: | |||
710 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 719 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
711 | count = 1; /* account for one byte pad to word boundary */ | 720 | count = 1; /* account for one byte pad to word boundary */ |
712 | name_len = | 721 | name_len = |
713 | cifs_strtoUCS((wchar_t *) (pSMB->fileName + 1), | 722 | cifsConvertToUCS((__u16 *) (pSMB->fileName + 1), |
714 | fileName, PATH_MAX | 723 | fileName, PATH_MAX, nls_codepage, remap); |
715 | /* find define for this maxpathcomponent */ | ||
716 | , nls_codepage); | ||
717 | name_len++; /* trailing null */ | 724 | name_len++; /* trailing null */ |
718 | name_len *= 2; | 725 | name_len *= 2; |
719 | pSMB->NameLength = cpu_to_le16(name_len); | 726 | pSMB->NameLength = cpu_to_le16(name_len); |
720 | } else { /* BB improve the check for buffer overruns BB */ | 727 | } else { /* BB improve check for buffer overruns BB */ |
721 | count = 0; /* no pad */ | 728 | count = 0; /* no pad */ |
722 | name_len = strnlen(fileName, PATH_MAX); | 729 | name_len = strnlen(fileName, PATH_MAX); |
723 | name_len++; /* trailing null */ | 730 | name_len++; /* trailing null */ |
@@ -746,7 +753,8 @@ openRetry: | |||
746 | pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); | 753 | pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); |
747 | pSMB->CreateDisposition = cpu_to_le32(openDisposition); | 754 | pSMB->CreateDisposition = cpu_to_le32(openDisposition); |
748 | pSMB->CreateOptions = cpu_to_le32(create_options); | 755 | pSMB->CreateOptions = cpu_to_le32(create_options); |
749 | pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); /* BB ??*/ | 756 | /* BB Expirement with various impersonation levels and verify */ |
757 | pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); | ||
750 | pSMB->SecurityFlags = | 758 | pSMB->SecurityFlags = |
751 | SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY; | 759 | SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY; |
752 | 760 | ||
@@ -760,7 +768,7 @@ openRetry: | |||
760 | if (rc) { | 768 | if (rc) { |
761 | cFYI(1, ("Error in Open = %d", rc)); | 769 | cFYI(1, ("Error in Open = %d", rc)); |
762 | } else { | 770 | } else { |
763 | *pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */ | 771 | *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */ |
764 | *netfid = pSMBr->Fid; /* cifs fid stays in le */ | 772 | *netfid = pSMBr->Fid; /* cifs fid stays in le */ |
765 | /* Let caller know file was created so we can set the mode. */ | 773 | /* Let caller know file was created so we can set the mode. */ |
766 | /* Do we care about the CreateAction in any other cases? */ | 774 | /* Do we care about the CreateAction in any other cases? */ |
@@ -1017,11 +1025,13 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
1017 | __u16 count; | 1025 | __u16 count; |
1018 | 1026 | ||
1019 | cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock)); | 1027 | cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock)); |
1020 | rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB, | 1028 | rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); |
1021 | (void **) &pSMBr); | 1029 | |
1022 | if (rc) | 1030 | if (rc) |
1023 | return rc; | 1031 | return rc; |
1024 | 1032 | ||
1033 | pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ | ||
1034 | |||
1025 | if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) { | 1035 | if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) { |
1026 | timeout = -1; /* no response expected */ | 1036 | timeout = -1; /* no response expected */ |
1027 | pSMB->Timeout = 0; | 1037 | pSMB->Timeout = 0; |
@@ -1059,7 +1069,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
1059 | if (rc) { | 1069 | if (rc) { |
1060 | cFYI(1, ("Send error in Lock = %d", rc)); | 1070 | cFYI(1, ("Send error in Lock = %d", rc)); |
1061 | } | 1071 | } |
1062 | cifs_buf_release(pSMB); | 1072 | cifs_small_buf_release(pSMB); |
1063 | 1073 | ||
1064 | /* Note: On -EAGAIN error only caller can retry on handle based calls | 1074 | /* Note: On -EAGAIN error only caller can retry on handle based calls |
1065 | since file handle passed in no longer valid */ | 1075 | since file handle passed in no longer valid */ |
@@ -1108,7 +1118,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) | |||
1108 | int | 1118 | int |
1109 | CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, | 1119 | CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, |
1110 | const char *fromName, const char *toName, | 1120 | const char *fromName, const char *toName, |
1111 | const struct nls_table *nls_codepage) | 1121 | const struct nls_table *nls_codepage, int remap) |
1112 | { | 1122 | { |
1113 | int rc = 0; | 1123 | int rc = 0; |
1114 | RENAME_REQ *pSMB = NULL; | 1124 | RENAME_REQ *pSMB = NULL; |
@@ -1131,18 +1141,16 @@ renameRetry: | |||
1131 | 1141 | ||
1132 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1142 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1133 | name_len = | 1143 | name_len = |
1134 | cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, PATH_MAX | 1144 | cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, |
1135 | /* find define for this maxpathcomponent */ | 1145 | PATH_MAX, nls_codepage, remap); |
1136 | , nls_codepage); | ||
1137 | name_len++; /* trailing null */ | 1146 | name_len++; /* trailing null */ |
1138 | name_len *= 2; | 1147 | name_len *= 2; |
1139 | pSMB->OldFileName[name_len] = 0x04; /* pad */ | 1148 | pSMB->OldFileName[name_len] = 0x04; /* pad */ |
1140 | /* protocol requires ASCII signature byte on Unicode string */ | 1149 | /* protocol requires ASCII signature byte on Unicode string */ |
1141 | pSMB->OldFileName[name_len + 1] = 0x00; | 1150 | pSMB->OldFileName[name_len + 1] = 0x00; |
1142 | name_len2 = | 1151 | name_len2 = |
1143 | cifs_strtoUCS((wchar_t *) & pSMB-> | 1152 | cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2], |
1144 | OldFileName[name_len + 2], toName, PATH_MAX, | 1153 | toName, PATH_MAX, nls_codepage, remap); |
1145 | nls_codepage); | ||
1146 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1154 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
1147 | name_len2 *= 2; /* convert to bytes */ | 1155 | name_len2 *= 2; /* convert to bytes */ |
1148 | } else { /* BB improve the check for buffer overruns BB */ | 1156 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -1182,7 +1190,8 @@ renameRetry: | |||
1182 | } | 1190 | } |
1183 | 1191 | ||
1184 | int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, | 1192 | int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, |
1185 | int netfid, char * target_name, const struct nls_table * nls_codepage) | 1193 | int netfid, char * target_name, |
1194 | const struct nls_table * nls_codepage, int remap) | ||
1186 | { | 1195 | { |
1187 | struct smb_com_transaction2_sfi_req *pSMB = NULL; | 1196 | struct smb_com_transaction2_sfi_req *pSMB = NULL; |
1188 | struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; | 1197 | struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; |
@@ -1227,9 +1236,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, | |||
1227 | /* unicode only call */ | 1236 | /* unicode only call */ |
1228 | if(target_name == NULL) { | 1237 | if(target_name == NULL) { |
1229 | sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); | 1238 | sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); |
1230 | len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, dummy_string, 24, nls_codepage); | 1239 | len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, |
1240 | dummy_string, 24, nls_codepage, remap); | ||
1231 | } else { | 1241 | } else { |
1232 | len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, target_name, PATH_MAX, nls_codepage); | 1242 | len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, |
1243 | target_name, PATH_MAX, nls_codepage, remap); | ||
1233 | } | 1244 | } |
1234 | rename_info->target_name_len = cpu_to_le32(2 * len_of_str); | 1245 | rename_info->target_name_len = cpu_to_le32(2 * len_of_str); |
1235 | count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2; | 1246 | count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2; |
@@ -1263,7 +1274,7 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, | |||
1263 | int | 1274 | int |
1264 | CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, | 1275 | CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, |
1265 | const __u16 target_tid, const char *toName, const int flags, | 1276 | const __u16 target_tid, const char *toName, const int flags, |
1266 | const struct nls_table *nls_codepage) | 1277 | const struct nls_table *nls_codepage, int remap) |
1267 | { | 1278 | { |
1268 | int rc = 0; | 1279 | int rc = 0; |
1269 | COPY_REQ *pSMB = NULL; | 1280 | COPY_REQ *pSMB = NULL; |
@@ -1285,18 +1296,16 @@ copyRetry: | |||
1285 | pSMB->Flags = cpu_to_le16(flags & COPY_TREE); | 1296 | pSMB->Flags = cpu_to_le16(flags & COPY_TREE); |
1286 | 1297 | ||
1287 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1298 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1288 | name_len = cifs_strtoUCS((wchar_t *) pSMB->OldFileName, | 1299 | name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, |
1289 | fromName, | 1300 | fromName, PATH_MAX, nls_codepage, |
1290 | PATH_MAX /* find define for this maxpathcomponent */, | 1301 | remap); |
1291 | nls_codepage); | ||
1292 | name_len++; /* trailing null */ | 1302 | name_len++; /* trailing null */ |
1293 | name_len *= 2; | 1303 | name_len *= 2; |
1294 | pSMB->OldFileName[name_len] = 0x04; /* pad */ | 1304 | pSMB->OldFileName[name_len] = 0x04; /* pad */ |
1295 | /* protocol requires ASCII signature byte on Unicode string */ | 1305 | /* protocol requires ASCII signature byte on Unicode string */ |
1296 | pSMB->OldFileName[name_len + 1] = 0x00; | 1306 | pSMB->OldFileName[name_len + 1] = 0x00; |
1297 | name_len2 = cifs_strtoUCS((wchar_t *) & pSMB-> | 1307 | name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], |
1298 | OldFileName[name_len + 2], toName, PATH_MAX, | 1308 | toName, PATH_MAX, nls_codepage, remap); |
1299 | nls_codepage); | ||
1300 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1309 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
1301 | name_len2 *= 2; /* convert to bytes */ | 1310 | name_len2 *= 2; /* convert to bytes */ |
1302 | } else { /* BB improve the check for buffer overruns BB */ | 1311 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -1425,7 +1434,7 @@ createSymLinkRetry: | |||
1425 | int | 1434 | int |
1426 | CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, | 1435 | CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, |
1427 | const char *fromName, const char *toName, | 1436 | const char *fromName, const char *toName, |
1428 | const struct nls_table *nls_codepage) | 1437 | const struct nls_table *nls_codepage, int remap) |
1429 | { | 1438 | { |
1430 | TRANSACTION2_SPI_REQ *pSMB = NULL; | 1439 | TRANSACTION2_SPI_REQ *pSMB = NULL; |
1431 | TRANSACTION2_SPI_RSP *pSMBr = NULL; | 1440 | TRANSACTION2_SPI_RSP *pSMBr = NULL; |
@@ -1444,9 +1453,8 @@ createHardLinkRetry: | |||
1444 | return rc; | 1453 | return rc; |
1445 | 1454 | ||
1446 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1455 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1447 | name_len = cifs_strtoUCS((wchar_t *) pSMB->FileName, toName, PATH_MAX | 1456 | name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName, |
1448 | /* find define for this maxpathcomponent */ | 1457 | PATH_MAX, nls_codepage, remap); |
1449 | , nls_codepage); | ||
1450 | name_len++; /* trailing null */ | 1458 | name_len++; /* trailing null */ |
1451 | name_len *= 2; | 1459 | name_len *= 2; |
1452 | 1460 | ||
@@ -1468,9 +1476,8 @@ createHardLinkRetry: | |||
1468 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | 1476 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; |
1469 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1477 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1470 | name_len_target = | 1478 | name_len_target = |
1471 | cifs_strtoUCS((wchar_t *) data_offset, fromName, PATH_MAX | 1479 | cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX, |
1472 | /* find define for this maxpathcomponent */ | 1480 | nls_codepage, remap); |
1473 | , nls_codepage); | ||
1474 | name_len_target++; /* trailing null */ | 1481 | name_len_target++; /* trailing null */ |
1475 | name_len_target *= 2; | 1482 | name_len_target *= 2; |
1476 | } else { /* BB improve the check for buffer overruns BB */ | 1483 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -1512,7 +1519,7 @@ createHardLinkRetry: | |||
1512 | int | 1519 | int |
1513 | CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, | 1520 | CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, |
1514 | const char *fromName, const char *toName, | 1521 | const char *fromName, const char *toName, |
1515 | const struct nls_table *nls_codepage) | 1522 | const struct nls_table *nls_codepage, int remap) |
1516 | { | 1523 | { |
1517 | int rc = 0; | 1524 | int rc = 0; |
1518 | NT_RENAME_REQ *pSMB = NULL; | 1525 | NT_RENAME_REQ *pSMB = NULL; |
@@ -1539,17 +1546,15 @@ winCreateHardLinkRetry: | |||
1539 | 1546 | ||
1540 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1547 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1541 | name_len = | 1548 | name_len = |
1542 | cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, PATH_MAX | 1549 | cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, |
1543 | /* find define for this maxpathcomponent */ | 1550 | PATH_MAX, nls_codepage, remap); |
1544 | , nls_codepage); | ||
1545 | name_len++; /* trailing null */ | 1551 | name_len++; /* trailing null */ |
1546 | name_len *= 2; | 1552 | name_len *= 2; |
1547 | pSMB->OldFileName[name_len] = 0; /* pad */ | 1553 | pSMB->OldFileName[name_len] = 0; /* pad */ |
1548 | pSMB->OldFileName[name_len + 1] = 0x04; | 1554 | pSMB->OldFileName[name_len + 1] = 0x04; |
1549 | name_len2 = | 1555 | name_len2 = |
1550 | cifs_strtoUCS((wchar_t *) & pSMB-> | 1556 | cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], |
1551 | OldFileName[name_len + 2], toName, PATH_MAX, | 1557 | toName, PATH_MAX, nls_codepage, remap); |
1552 | nls_codepage); | ||
1553 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1558 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
1554 | name_len2 *= 2; /* convert to bytes */ | 1559 | name_len2 *= 2; /* convert to bytes */ |
1555 | } else { /* BB improve the check for buffer overruns BB */ | 1560 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -1659,6 +1664,7 @@ querySymLinkRetry: | |||
1659 | name_len = UniStrnlen((wchar_t *) ((char *) | 1664 | name_len = UniStrnlen((wchar_t *) ((char *) |
1660 | &pSMBr->hdr.Protocol +data_offset), | 1665 | &pSMBr->hdr.Protocol +data_offset), |
1661 | min_t(const int, buflen,count) / 2); | 1666 | min_t(const int, buflen,count) / 2); |
1667 | /* BB FIXME investigate remapping reserved chars here */ | ||
1662 | cifs_strfromUCS_le(symlinkinfo, | 1668 | cifs_strfromUCS_le(symlinkinfo, |
1663 | (wchar_t *) ((char *)&pSMBr->hdr.Protocol + | 1669 | (wchar_t *) ((char *)&pSMBr->hdr.Protocol + |
1664 | data_offset), | 1670 | data_offset), |
@@ -1793,7 +1799,8 @@ static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace | |||
1793 | } | 1799 | } |
1794 | 1800 | ||
1795 | /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */ | 1801 | /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */ |
1796 | static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,const int acl_type,const int size_of_data_area) | 1802 | static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen, |
1803 | const int acl_type,const int size_of_data_area) | ||
1797 | { | 1804 | { |
1798 | int size = 0; | 1805 | int size = 0; |
1799 | int i; | 1806 | int i; |
@@ -1912,7 +1919,7 @@ int | |||
1912 | CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, | 1919 | CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, |
1913 | const unsigned char *searchName, | 1920 | const unsigned char *searchName, |
1914 | char *acl_inf, const int buflen, const int acl_type, | 1921 | char *acl_inf, const int buflen, const int acl_type, |
1915 | const struct nls_table *nls_codepage) | 1922 | const struct nls_table *nls_codepage, int remap) |
1916 | { | 1923 | { |
1917 | /* SMB_QUERY_POSIX_ACL */ | 1924 | /* SMB_QUERY_POSIX_ACL */ |
1918 | TRANSACTION2_QPI_REQ *pSMB = NULL; | 1925 | TRANSACTION2_QPI_REQ *pSMB = NULL; |
@@ -1932,8 +1939,8 @@ queryAclRetry: | |||
1932 | 1939 | ||
1933 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1940 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1934 | name_len = | 1941 | name_len = |
1935 | cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 1942 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, |
1936 | , nls_codepage); | 1943 | PATH_MAX, nls_codepage, remap); |
1937 | name_len++; /* trailing null */ | 1944 | name_len++; /* trailing null */ |
1938 | name_len *= 2; | 1945 | name_len *= 2; |
1939 | pSMB->FileName[name_len] = 0; | 1946 | pSMB->FileName[name_len] = 0; |
@@ -1997,8 +2004,9 @@ queryAclRetry: | |||
1997 | int | 2004 | int |
1998 | CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, | 2005 | CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, |
1999 | const unsigned char *fileName, | 2006 | const unsigned char *fileName, |
2000 | const char *local_acl, const int buflen, const int acl_type, | 2007 | const char *local_acl, const int buflen, |
2001 | const struct nls_table *nls_codepage) | 2008 | const int acl_type, |
2009 | const struct nls_table *nls_codepage, int remap) | ||
2002 | { | 2010 | { |
2003 | struct smb_com_transaction2_spi_req *pSMB = NULL; | 2011 | struct smb_com_transaction2_spi_req *pSMB = NULL; |
2004 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; | 2012 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; |
@@ -2016,8 +2024,8 @@ setAclRetry: | |||
2016 | return rc; | 2024 | return rc; |
2017 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2025 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2018 | name_len = | 2026 | name_len = |
2019 | cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX | 2027 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, |
2020 | , nls_codepage); | 2028 | PATH_MAX, nls_codepage, remap); |
2021 | name_len++; /* trailing null */ | 2029 | name_len++; /* trailing null */ |
2022 | name_len *= 2; | 2030 | name_len *= 2; |
2023 | } else { /* BB improve the check for buffer overruns BB */ | 2031 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -2072,13 +2080,96 @@ setACLerrorExit: | |||
2072 | return rc; | 2080 | return rc; |
2073 | } | 2081 | } |
2074 | 2082 | ||
2075 | #endif | 2083 | /* BB fix tabs in this function FIXME BB */ |
2084 | int | ||
2085 | CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, | ||
2086 | const int netfid, __u64 * pExtAttrBits, __u64 *pMask) | ||
2087 | { | ||
2088 | int rc = 0; | ||
2089 | struct smb_t2_qfi_req *pSMB = NULL; | ||
2090 | struct smb_t2_qfi_rsp *pSMBr = NULL; | ||
2091 | int bytes_returned; | ||
2092 | __u16 params, byte_count; | ||
2093 | |||
2094 | cFYI(1,("In GetExtAttr")); | ||
2095 | if(tcon == NULL) | ||
2096 | return -ENODEV; | ||
2097 | |||
2098 | GetExtAttrRetry: | ||
2099 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | ||
2100 | (void **) &pSMBr); | ||
2101 | if (rc) | ||
2102 | return rc; | ||
2103 | |||
2104 | params = 2 /* level */ +2 /* fid */; | ||
2105 | pSMB->t2.TotalDataCount = 0; | ||
2106 | pSMB->t2.MaxParameterCount = cpu_to_le16(4); | ||
2107 | /* BB find exact max data count below from sess structure BB */ | ||
2108 | pSMB->t2.MaxDataCount = cpu_to_le16(4000); | ||
2109 | pSMB->t2.MaxSetupCount = 0; | ||
2110 | pSMB->t2.Reserved = 0; | ||
2111 | pSMB->t2.Flags = 0; | ||
2112 | pSMB->t2.Timeout = 0; | ||
2113 | pSMB->t2.Reserved2 = 0; | ||
2114 | pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, | ||
2115 | Fid) - 4); | ||
2116 | pSMB->t2.DataCount = 0; | ||
2117 | pSMB->t2.DataOffset = 0; | ||
2118 | pSMB->t2.SetupCount = 1; | ||
2119 | pSMB->t2.Reserved3 = 0; | ||
2120 | pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); | ||
2121 | byte_count = params + 1 /* pad */ ; | ||
2122 | pSMB->t2.TotalParameterCount = cpu_to_le16(params); | ||
2123 | pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; | ||
2124 | pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); | ||
2125 | pSMB->Pad = 0; | ||
2126 | pSMB->Fid = netfid; | ||
2127 | pSMB->hdr.smb_buf_length += byte_count; | ||
2128 | pSMB->t2.ByteCount = cpu_to_le16(byte_count); | ||
2129 | |||
2130 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | ||
2131 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | ||
2132 | if (rc) { | ||
2133 | cFYI(1, ("error %d in GetExtAttr", rc)); | ||
2134 | } else { | ||
2135 | /* decode response */ | ||
2136 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | ||
2137 | if (rc || (pSMBr->ByteCount < 2)) | ||
2138 | /* BB also check enough total bytes returned */ | ||
2139 | /* If rc should we check for EOPNOSUPP and | ||
2140 | disable the srvino flag? or in caller? */ | ||
2141 | rc = -EIO; /* bad smb */ | ||
2142 | else { | ||
2143 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | ||
2144 | __u16 count = le16_to_cpu(pSMBr->t2.DataCount); | ||
2145 | struct file_chattr_info * pfinfo; | ||
2146 | /* BB Do we need a cast or hash here ? */ | ||
2147 | if(count != 16) { | ||
2148 | cFYI(1, ("Illegal size ret in GetExtAttr")); | ||
2149 | rc = -EIO; | ||
2150 | goto GetExtAttrOut; | ||
2151 | } | ||
2152 | pfinfo = (struct file_chattr_info *) | ||
2153 | (data_offset + (char *) &pSMBr->hdr.Protocol); | ||
2154 | *pExtAttrBits = le64_to_cpu(pfinfo->mode); | ||
2155 | *pMask = le64_to_cpu(pfinfo->mask); | ||
2156 | } | ||
2157 | } | ||
2158 | GetExtAttrOut: | ||
2159 | cifs_buf_release(pSMB); | ||
2160 | if (rc == -EAGAIN) | ||
2161 | goto GetExtAttrRetry; | ||
2162 | return rc; | ||
2163 | } | ||
2164 | |||
2165 | |||
2166 | #endif /* CONFIG_POSIX */ | ||
2076 | 2167 | ||
2077 | int | 2168 | int |
2078 | CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, | 2169 | CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, |
2079 | const unsigned char *searchName, | 2170 | const unsigned char *searchName, |
2080 | FILE_ALL_INFO * pFindData, | 2171 | FILE_ALL_INFO * pFindData, |
2081 | const struct nls_table *nls_codepage) | 2172 | const struct nls_table *nls_codepage, int remap) |
2082 | { | 2173 | { |
2083 | /* level 263 SMB_QUERY_FILE_ALL_INFO */ | 2174 | /* level 263 SMB_QUERY_FILE_ALL_INFO */ |
2084 | TRANSACTION2_QPI_REQ *pSMB = NULL; | 2175 | TRANSACTION2_QPI_REQ *pSMB = NULL; |
@@ -2097,9 +2188,8 @@ QPathInfoRetry: | |||
2097 | 2188 | ||
2098 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2189 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2099 | name_len = | 2190 | name_len = |
2100 | cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 2191 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, |
2101 | /* find define for this maxpathcomponent */ | 2192 | PATH_MAX, nls_codepage, remap); |
2102 | , nls_codepage); | ||
2103 | name_len++; /* trailing null */ | 2193 | name_len++; /* trailing null */ |
2104 | name_len *= 2; | 2194 | name_len *= 2; |
2105 | } else { /* BB improve the check for buffer overruns BB */ | 2195 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -2160,7 +2250,7 @@ int | |||
2160 | CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, | 2250 | CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, |
2161 | const unsigned char *searchName, | 2251 | const unsigned char *searchName, |
2162 | FILE_UNIX_BASIC_INFO * pFindData, | 2252 | FILE_UNIX_BASIC_INFO * pFindData, |
2163 | const struct nls_table *nls_codepage) | 2253 | const struct nls_table *nls_codepage, int remap) |
2164 | { | 2254 | { |
2165 | /* SMB_QUERY_FILE_UNIX_BASIC */ | 2255 | /* SMB_QUERY_FILE_UNIX_BASIC */ |
2166 | TRANSACTION2_QPI_REQ *pSMB = NULL; | 2256 | TRANSACTION2_QPI_REQ *pSMB = NULL; |
@@ -2179,9 +2269,8 @@ UnixQPathInfoRetry: | |||
2179 | 2269 | ||
2180 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2270 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2181 | name_len = | 2271 | name_len = |
2182 | cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 2272 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, |
2183 | /* find define for this maxpathcomponent */ | 2273 | PATH_MAX, nls_codepage, remap); |
2184 | , nls_codepage); | ||
2185 | name_len++; /* trailing null */ | 2274 | name_len++; /* trailing null */ |
2186 | name_len *= 2; | 2275 | name_len *= 2; |
2187 | } else { /* BB improve the check for buffer overruns BB */ | 2276 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -2261,7 +2350,7 @@ findUniqueRetry: | |||
2261 | 2350 | ||
2262 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2351 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2263 | name_len = | 2352 | name_len = |
2264 | cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 2353 | cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX |
2265 | /* find define for this maxpathcomponent */ | 2354 | /* find define for this maxpathcomponent */ |
2266 | , nls_codepage); | 2355 | , nls_codepage); |
2267 | name_len++; /* trailing null */ | 2356 | name_len++; /* trailing null */ |
@@ -2325,7 +2414,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, | |||
2325 | const char *searchName, | 2414 | const char *searchName, |
2326 | const struct nls_table *nls_codepage, | 2415 | const struct nls_table *nls_codepage, |
2327 | __u16 * pnetfid, | 2416 | __u16 * pnetfid, |
2328 | struct cifs_search_info * psrch_inf) | 2417 | struct cifs_search_info * psrch_inf, int remap) |
2329 | { | 2418 | { |
2330 | /* level 257 SMB_ */ | 2419 | /* level 257 SMB_ */ |
2331 | TRANSACTION2_FFIRST_REQ *pSMB = NULL; | 2420 | TRANSACTION2_FFIRST_REQ *pSMB = NULL; |
@@ -2336,7 +2425,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, | |||
2336 | int name_len; | 2425 | int name_len; |
2337 | __u16 params, byte_count; | 2426 | __u16 params, byte_count; |
2338 | 2427 | ||
2339 | cFYI(1, ("In FindFirst")); | 2428 | cFYI(1, ("In FindFirst for %s",searchName)); |
2340 | 2429 | ||
2341 | findFirstRetry: | 2430 | findFirstRetry: |
2342 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | 2431 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, |
@@ -2346,20 +2435,30 @@ findFirstRetry: | |||
2346 | 2435 | ||
2347 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2436 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2348 | name_len = | 2437 | name_len = |
2349 | cifs_strtoUCS((wchar_t *) pSMB->FileName,searchName, | 2438 | cifsConvertToUCS((__u16 *) pSMB->FileName,searchName, |
2350 | PATH_MAX, nls_codepage); | 2439 | PATH_MAX, nls_codepage, remap); |
2351 | name_len++; /* trailing null */ | 2440 | /* We can not add the asterik earlier in case |
2441 | it got remapped to 0xF03A as if it were part of the | ||
2442 | directory name instead of a wildcard */ | ||
2352 | name_len *= 2; | 2443 | name_len *= 2; |
2444 | pSMB->FileName[name_len] = '\\'; | ||
2445 | pSMB->FileName[name_len+1] = 0; | ||
2446 | pSMB->FileName[name_len+2] = '*'; | ||
2447 | pSMB->FileName[name_len+3] = 0; | ||
2448 | name_len += 4; /* now the trailing null */ | ||
2353 | pSMB->FileName[name_len] = 0; /* null terminate just in case */ | 2449 | pSMB->FileName[name_len] = 0; /* null terminate just in case */ |
2354 | pSMB->FileName[name_len+1] = 0; | 2450 | pSMB->FileName[name_len+1] = 0; |
2451 | name_len += 2; | ||
2355 | } else { /* BB add check for overrun of SMB buf BB */ | 2452 | } else { /* BB add check for overrun of SMB buf BB */ |
2356 | name_len = strnlen(searchName, PATH_MAX); | 2453 | name_len = strnlen(searchName, PATH_MAX); |
2357 | name_len++; /* trailing null */ | ||
2358 | /* BB fix here and in unicode clause above ie | 2454 | /* BB fix here and in unicode clause above ie |
2359 | if(name_len > buffersize-header) | 2455 | if(name_len > buffersize-header) |
2360 | free buffer exit; BB */ | 2456 | free buffer exit; BB */ |
2361 | strncpy(pSMB->FileName, searchName, name_len); | 2457 | strncpy(pSMB->FileName, searchName, name_len); |
2362 | pSMB->FileName[name_len] = 0; /* just in case */ | 2458 | pSMB->FileName[name_len] = '\\'; |
2459 | pSMB->FileName[name_len+1] = '*'; | ||
2460 | pSMB->FileName[name_len+2] = 0; | ||
2461 | name_len += 3; | ||
2363 | } | 2462 | } |
2364 | 2463 | ||
2365 | params = 12 + name_len /* includes null */ ; | 2464 | params = 12 + name_len /* includes null */ ; |
@@ -2422,7 +2521,6 @@ findFirstRetry: | |||
2422 | psrch_inf->srch_entries_start = | 2521 | psrch_inf->srch_entries_start = |
2423 | (char *) &pSMBr->hdr.Protocol + | 2522 | (char *) &pSMBr->hdr.Protocol + |
2424 | le16_to_cpu(pSMBr->t2.DataOffset); | 2523 | le16_to_cpu(pSMBr->t2.DataOffset); |
2425 | |||
2426 | parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol + | 2524 | parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol + |
2427 | le16_to_cpu(pSMBr->t2.ParameterOffset)); | 2525 | le16_to_cpu(pSMBr->t2.ParameterOffset)); |
2428 | 2526 | ||
@@ -2434,7 +2532,6 @@ findFirstRetry: | |||
2434 | psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); | 2532 | psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); |
2435 | psrch_inf->index_of_last_entry = | 2533 | psrch_inf->index_of_last_entry = |
2436 | psrch_inf->entries_in_buffer; | 2534 | psrch_inf->entries_in_buffer; |
2437 | /*cFYI(1,("entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */ | ||
2438 | *pnetfid = parms->SearchHandle; | 2535 | *pnetfid = parms->SearchHandle; |
2439 | } else { | 2536 | } else { |
2440 | cifs_buf_release(pSMB); | 2537 | cifs_buf_release(pSMB); |
@@ -2608,7 +2705,7 @@ int | |||
2608 | CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, | 2705 | CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, |
2609 | const unsigned char *searchName, | 2706 | const unsigned char *searchName, |
2610 | __u64 * inode_number, | 2707 | __u64 * inode_number, |
2611 | const struct nls_table *nls_codepage) | 2708 | const struct nls_table *nls_codepage, int remap) |
2612 | { | 2709 | { |
2613 | int rc = 0; | 2710 | int rc = 0; |
2614 | TRANSACTION2_QPI_REQ *pSMB = NULL; | 2711 | TRANSACTION2_QPI_REQ *pSMB = NULL; |
@@ -2629,8 +2726,8 @@ GetInodeNumberRetry: | |||
2629 | 2726 | ||
2630 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2727 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2631 | name_len = | 2728 | name_len = |
2632 | cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, | 2729 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, |
2633 | PATH_MAX,nls_codepage); | 2730 | PATH_MAX,nls_codepage, remap); |
2634 | name_len++; /* trailing null */ | 2731 | name_len++; /* trailing null */ |
2635 | name_len *= 2; | 2732 | name_len *= 2; |
2636 | } else { /* BB improve the check for buffer overruns BB */ | 2733 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -2704,7 +2801,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, | |||
2704 | const unsigned char *searchName, | 2801 | const unsigned char *searchName, |
2705 | unsigned char **targetUNCs, | 2802 | unsigned char **targetUNCs, |
2706 | unsigned int *number_of_UNC_in_array, | 2803 | unsigned int *number_of_UNC_in_array, |
2707 | const struct nls_table *nls_codepage) | 2804 | const struct nls_table *nls_codepage, int remap) |
2708 | { | 2805 | { |
2709 | /* TRANS2_GET_DFS_REFERRAL */ | 2806 | /* TRANS2_GET_DFS_REFERRAL */ |
2710 | TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; | 2807 | TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; |
@@ -2740,10 +2837,8 @@ getDFSRetry: | |||
2740 | if (ses->capabilities & CAP_UNICODE) { | 2837 | if (ses->capabilities & CAP_UNICODE) { |
2741 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 2838 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; |
2742 | name_len = | 2839 | name_len = |
2743 | cifs_strtoUCS((wchar_t *) pSMB->RequestFileName, | 2840 | cifsConvertToUCS((__u16 *) pSMB->RequestFileName, |
2744 | searchName, PATH_MAX | 2841 | searchName, PATH_MAX, nls_codepage, remap); |
2745 | /* find define for this maxpathcomponent */ | ||
2746 | , nls_codepage); | ||
2747 | name_len++; /* trailing null */ | 2842 | name_len++; /* trailing null */ |
2748 | name_len *= 2; | 2843 | name_len *= 2; |
2749 | } else { /* BB improve the check for buffer overruns BB */ | 2844 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -2871,8 +2966,7 @@ GetDFSRefExit: | |||
2871 | } | 2966 | } |
2872 | 2967 | ||
2873 | int | 2968 | int |
2874 | CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, | 2969 | CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) |
2875 | struct kstatfs *FSData, const struct nls_table *nls_codepage) | ||
2876 | { | 2970 | { |
2877 | /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ | 2971 | /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ |
2878 | TRANSACTION2_QFSI_REQ *pSMB = NULL; | 2972 | TRANSACTION2_QFSI_REQ *pSMB = NULL; |
@@ -2955,8 +3049,7 @@ QFSInfoRetry: | |||
2955 | } | 3049 | } |
2956 | 3050 | ||
2957 | int | 3051 | int |
2958 | CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon, | 3052 | CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon) |
2959 | const struct nls_table *nls_codepage) | ||
2960 | { | 3053 | { |
2961 | /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ | 3054 | /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ |
2962 | TRANSACTION2_QFSI_REQ *pSMB = NULL; | 3055 | TRANSACTION2_QFSI_REQ *pSMB = NULL; |
@@ -3024,8 +3117,7 @@ QFSAttributeRetry: | |||
3024 | } | 3117 | } |
3025 | 3118 | ||
3026 | int | 3119 | int |
3027 | CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon, | 3120 | CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon) |
3028 | const struct nls_table *nls_codepage) | ||
3029 | { | 3121 | { |
3030 | /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ | 3122 | /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ |
3031 | TRANSACTION2_QFSI_REQ *pSMB = NULL; | 3123 | TRANSACTION2_QFSI_REQ *pSMB = NULL; |
@@ -3078,8 +3170,8 @@ QFSDeviceRetry: | |||
3078 | else { | 3170 | else { |
3079 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 3171 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); |
3080 | response_data = | 3172 | response_data = |
3081 | (FILE_SYSTEM_DEVICE_INFO | 3173 | (FILE_SYSTEM_DEVICE_INFO *) |
3082 | *) (((char *) &pSMBr->hdr.Protocol) + | 3174 | (((char *) &pSMBr->hdr.Protocol) + |
3083 | data_offset); | 3175 | data_offset); |
3084 | memcpy(&tcon->fsDevInfo, response_data, | 3176 | memcpy(&tcon->fsDevInfo, response_data, |
3085 | sizeof (FILE_SYSTEM_DEVICE_INFO)); | 3177 | sizeof (FILE_SYSTEM_DEVICE_INFO)); |
@@ -3094,8 +3186,7 @@ QFSDeviceRetry: | |||
3094 | } | 3186 | } |
3095 | 3187 | ||
3096 | int | 3188 | int |
3097 | CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon, | 3189 | CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) |
3098 | const struct nls_table *nls_codepage) | ||
3099 | { | 3190 | { |
3100 | /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ | 3191 | /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ |
3101 | TRANSACTION2_QFSI_REQ *pSMB = NULL; | 3192 | TRANSACTION2_QFSI_REQ *pSMB = NULL; |
@@ -3166,7 +3257,7 @@ QFSUnixRetry: | |||
3166 | 3257 | ||
3167 | int | 3258 | int |
3168 | CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, | 3259 | CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, |
3169 | struct kstatfs *FSData, const struct nls_table *nls_codepage) | 3260 | struct kstatfs *FSData) |
3170 | { | 3261 | { |
3171 | /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ | 3262 | /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ |
3172 | TRANSACTION2_QFSI_REQ *pSMB = NULL; | 3263 | TRANSACTION2_QFSI_REQ *pSMB = NULL; |
@@ -3258,7 +3349,8 @@ QFSPosixRetry: | |||
3258 | 3349 | ||
3259 | int | 3350 | int |
3260 | CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, | 3351 | CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, |
3261 | __u64 size, int SetAllocation, const struct nls_table *nls_codepage) | 3352 | __u64 size, int SetAllocation, |
3353 | const struct nls_table *nls_codepage, int remap) | ||
3262 | { | 3354 | { |
3263 | struct smb_com_transaction2_spi_req *pSMB = NULL; | 3355 | struct smb_com_transaction2_spi_req *pSMB = NULL; |
3264 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; | 3356 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; |
@@ -3277,9 +3369,8 @@ SetEOFRetry: | |||
3277 | 3369 | ||
3278 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3370 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3279 | name_len = | 3371 | name_len = |
3280 | cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX | 3372 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, |
3281 | /* find define for this maxpathcomponent */ | 3373 | PATH_MAX, nls_codepage, remap); |
3282 | , nls_codepage); | ||
3283 | name_len++; /* trailing null */ | 3374 | name_len++; /* trailing null */ |
3284 | name_len *= 2; | 3375 | name_len *= 2; |
3285 | } else { /* BB improve the check for buffer overruns BB */ | 3376 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -3360,11 +3451,13 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, | |||
3360 | 3451 | ||
3361 | cFYI(1, ("SetFileSize (via SetFileInfo) %lld", | 3452 | cFYI(1, ("SetFileSize (via SetFileInfo) %lld", |
3362 | (long long)size)); | 3453 | (long long)size)); |
3363 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | 3454 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); |
3364 | (void **) &pSMBr); | 3455 | |
3365 | if (rc) | 3456 | if (rc) |
3366 | return rc; | 3457 | return rc; |
3367 | 3458 | ||
3459 | pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; | ||
3460 | |||
3368 | pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); | 3461 | pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); |
3369 | pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); | 3462 | pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); |
3370 | 3463 | ||
@@ -3424,7 +3517,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, | |||
3424 | } | 3517 | } |
3425 | 3518 | ||
3426 | if (pSMB) | 3519 | if (pSMB) |
3427 | cifs_buf_release(pSMB); | 3520 | cifs_small_buf_release(pSMB); |
3428 | 3521 | ||
3429 | /* Note: On -EAGAIN error only caller can retry on handle based calls | 3522 | /* Note: On -EAGAIN error only caller can retry on handle based calls |
3430 | since file handle passed in no longer valid */ | 3523 | since file handle passed in no longer valid */ |
@@ -3450,11 +3543,13 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I | |||
3450 | __u16 params, param_offset, offset, byte_count, count; | 3543 | __u16 params, param_offset, offset, byte_count, count; |
3451 | 3544 | ||
3452 | cFYI(1, ("Set Times (via SetFileInfo)")); | 3545 | cFYI(1, ("Set Times (via SetFileInfo)")); |
3453 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | 3546 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); |
3454 | (void **) &pSMBr); | 3547 | |
3455 | if (rc) | 3548 | if (rc) |
3456 | return rc; | 3549 | return rc; |
3457 | 3550 | ||
3551 | pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; | ||
3552 | |||
3458 | /* At this point there is no need to override the current pid | 3553 | /* At this point there is no need to override the current pid |
3459 | with the pid of the opener, but that could change if we someday | 3554 | with the pid of the opener, but that could change if we someday |
3460 | use an existing handle (rather than opening one on the fly) */ | 3555 | use an existing handle (rather than opening one on the fly) */ |
@@ -3500,7 +3595,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I | |||
3500 | cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc)); | 3595 | cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc)); |
3501 | } | 3596 | } |
3502 | 3597 | ||
3503 | cifs_buf_release(pSMB); | 3598 | cifs_small_buf_release(pSMB); |
3504 | 3599 | ||
3505 | /* Note: On -EAGAIN error only caller can retry on handle based calls | 3600 | /* Note: On -EAGAIN error only caller can retry on handle based calls |
3506 | since file handle passed in no longer valid */ | 3601 | since file handle passed in no longer valid */ |
@@ -3512,7 +3607,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I | |||
3512 | int | 3607 | int |
3513 | CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, | 3608 | CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, |
3514 | const FILE_BASIC_INFO * data, | 3609 | const FILE_BASIC_INFO * data, |
3515 | const struct nls_table *nls_codepage) | 3610 | const struct nls_table *nls_codepage, int remap) |
3516 | { | 3611 | { |
3517 | TRANSACTION2_SPI_REQ *pSMB = NULL; | 3612 | TRANSACTION2_SPI_REQ *pSMB = NULL; |
3518 | TRANSACTION2_SPI_RSP *pSMBr = NULL; | 3613 | TRANSACTION2_SPI_RSP *pSMBr = NULL; |
@@ -3532,9 +3627,8 @@ SetTimesRetry: | |||
3532 | 3627 | ||
3533 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3628 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3534 | name_len = | 3629 | name_len = |
3535 | cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX | 3630 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, |
3536 | /* find define for this maxpathcomponent */ | 3631 | PATH_MAX, nls_codepage, remap); |
3537 | , nls_codepage); | ||
3538 | name_len++; /* trailing null */ | 3632 | name_len++; /* trailing null */ |
3539 | name_len *= 2; | 3633 | name_len *= 2; |
3540 | } else { /* BB improve the check for buffer overruns BB */ | 3634 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -3614,7 +3708,7 @@ SetAttrLgcyRetry: | |||
3614 | 3708 | ||
3615 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3709 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3616 | name_len = | 3710 | name_len = |
3617 | cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, | 3711 | ConvertToUCS((wchar_t *) pSMB->fileName, fileName, |
3618 | PATH_MAX, nls_codepage); | 3712 | PATH_MAX, nls_codepage); |
3619 | name_len++; /* trailing null */ | 3713 | name_len++; /* trailing null */ |
3620 | name_len *= 2; | 3714 | name_len *= 2; |
@@ -3644,8 +3738,9 @@ SetAttrLgcyRetry: | |||
3644 | 3738 | ||
3645 | int | 3739 | int |
3646 | CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, | 3740 | CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, |
3647 | char *fileName, __u64 mode, __u64 uid, __u64 gid, | 3741 | char *fileName, __u64 mode, __u64 uid, __u64 gid, |
3648 | dev_t device, const struct nls_table *nls_codepage) | 3742 | dev_t device, const struct nls_table *nls_codepage, |
3743 | int remap) | ||
3649 | { | 3744 | { |
3650 | TRANSACTION2_SPI_REQ *pSMB = NULL; | 3745 | TRANSACTION2_SPI_REQ *pSMB = NULL; |
3651 | TRANSACTION2_SPI_RSP *pSMBr = NULL; | 3746 | TRANSACTION2_SPI_RSP *pSMBr = NULL; |
@@ -3664,9 +3759,8 @@ setPermsRetry: | |||
3664 | 3759 | ||
3665 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3760 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3666 | name_len = | 3761 | name_len = |
3667 | cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX | 3762 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, |
3668 | /* find define for this maxpathcomponent */ | 3763 | PATH_MAX, nls_codepage, remap); |
3669 | , nls_codepage); | ||
3670 | name_len++; /* trailing null */ | 3764 | name_len++; /* trailing null */ |
3671 | name_len *= 2; | 3765 | name_len *= 2; |
3672 | } else { /* BB improve the check for buffer overruns BB */ | 3766 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -3789,7 +3883,7 @@ ssize_t | |||
3789 | CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, | 3883 | CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, |
3790 | const unsigned char *searchName, | 3884 | const unsigned char *searchName, |
3791 | char * EAData, size_t buf_size, | 3885 | char * EAData, size_t buf_size, |
3792 | const struct nls_table *nls_codepage) | 3886 | const struct nls_table *nls_codepage, int remap) |
3793 | { | 3887 | { |
3794 | /* BB assumes one setup word */ | 3888 | /* BB assumes one setup word */ |
3795 | TRANSACTION2_QPI_REQ *pSMB = NULL; | 3889 | TRANSACTION2_QPI_REQ *pSMB = NULL; |
@@ -3810,9 +3904,8 @@ QAllEAsRetry: | |||
3810 | 3904 | ||
3811 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3905 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3812 | name_len = | 3906 | name_len = |
3813 | cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 3907 | cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, |
3814 | /* find define for this maxpathcomponent */ | 3908 | PATH_MAX, nls_codepage, remap); |
3815 | , nls_codepage); | ||
3816 | name_len++; /* trailing null */ | 3909 | name_len++; /* trailing null */ |
3817 | name_len *= 2; | 3910 | name_len *= 2; |
3818 | } else { /* BB improve the check for buffer overruns BB */ | 3911 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -3934,7 +4027,7 @@ QAllEAsRetry: | |||
3934 | ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, | 4027 | ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, |
3935 | const unsigned char * searchName,const unsigned char * ea_name, | 4028 | const unsigned char * searchName,const unsigned char * ea_name, |
3936 | unsigned char * ea_value, size_t buf_size, | 4029 | unsigned char * ea_value, size_t buf_size, |
3937 | const struct nls_table *nls_codepage) | 4030 | const struct nls_table *nls_codepage, int remap) |
3938 | { | 4031 | { |
3939 | TRANSACTION2_QPI_REQ *pSMB = NULL; | 4032 | TRANSACTION2_QPI_REQ *pSMB = NULL; |
3940 | TRANSACTION2_QPI_RSP *pSMBr = NULL; | 4033 | TRANSACTION2_QPI_RSP *pSMBr = NULL; |
@@ -3954,9 +4047,8 @@ QEARetry: | |||
3954 | 4047 | ||
3955 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 4048 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3956 | name_len = | 4049 | name_len = |
3957 | cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 4050 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, |
3958 | /* find define for this maxpathcomponent */ | 4051 | PATH_MAX, nls_codepage, remap); |
3959 | , nls_codepage); | ||
3960 | name_len++; /* trailing null */ | 4052 | name_len++; /* trailing null */ |
3961 | name_len *= 2; | 4053 | name_len *= 2; |
3962 | } else { /* BB improve the check for buffer overruns BB */ | 4054 | } else { /* BB improve the check for buffer overruns BB */ |
@@ -4082,7 +4174,8 @@ QEARetry: | |||
4082 | int | 4174 | int |
4083 | CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, | 4175 | CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, |
4084 | const char * ea_name, const void * ea_value, | 4176 | const char * ea_name, const void * ea_value, |
4085 | const __u16 ea_value_len, const struct nls_table *nls_codepage) | 4177 | const __u16 ea_value_len, const struct nls_table *nls_codepage, |
4178 | int remap) | ||
4086 | { | 4179 | { |
4087 | struct smb_com_transaction2_spi_req *pSMB = NULL; | 4180 | struct smb_com_transaction2_spi_req *pSMB = NULL; |
4088 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; | 4181 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; |
@@ -4101,9 +4194,8 @@ SetEARetry: | |||
4101 | 4194 | ||
4102 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 4195 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
4103 | name_len = | 4196 | name_len = |
4104 | cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX | 4197 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, |
4105 | /* find define for this maxpathcomponent */ | 4198 | PATH_MAX, nls_codepage, remap); |
4106 | , nls_codepage); | ||
4107 | name_len++; /* trailing null */ | 4199 | name_len++; /* trailing null */ |
4108 | name_len *= 2; | 4200 | name_len *= 2; |
4109 | } else { /* BB improve the check for buffer overruns BB */ | 4201 | } else { /* BB improve the check for buffer overruns BB */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 40470b9d5477..e568cc47a7f9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/connect.c | 2 | * fs/cifs/connect.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2004 | 4 | * Copyright (C) International Business Machines Corp., 2002,2005 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
30 | #include <linux/mempool.h> | 30 | #include <linux/mempool.h> |
31 | #include <linux/delay.h> | ||
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
33 | #include "cifspdu.h" | 34 | #include "cifspdu.h" |
@@ -72,6 +73,7 @@ struct smb_vol { | |||
72 | unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ | 73 | unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ |
73 | unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ | 74 | unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ |
74 | unsigned direct_io:1; | 75 | unsigned direct_io:1; |
76 | unsigned remap:1; /* set to remap seven reserved chars in filenames */ | ||
75 | unsigned int rsize; | 77 | unsigned int rsize; |
76 | unsigned int wsize; | 78 | unsigned int wsize; |
77 | unsigned int sockopt; | 79 | unsigned int sockopt; |
@@ -114,7 +116,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
114 | spin_unlock(&GlobalMid_Lock); | 116 | spin_unlock(&GlobalMid_Lock); |
115 | server->maxBuf = 0; | 117 | server->maxBuf = 0; |
116 | 118 | ||
117 | cFYI(1, ("Reconnecting tcp session ")); | 119 | cFYI(1, ("Reconnecting tcp session")); |
118 | 120 | ||
119 | /* before reconnecting the tcp session, mark the smb session (uid) | 121 | /* before reconnecting the tcp session, mark the smb session (uid) |
120 | and the tid bad so they are not used until reconnected */ | 122 | and the tid bad so they are not used until reconnected */ |
@@ -155,9 +157,10 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
155 | qhead); | 157 | qhead); |
156 | if(mid_entry) { | 158 | if(mid_entry) { |
157 | if(mid_entry->midState == MID_REQUEST_SUBMITTED) { | 159 | if(mid_entry->midState == MID_REQUEST_SUBMITTED) { |
158 | /* Mark other intransit requests as needing retry so | 160 | /* Mark other intransit requests as needing |
159 | we do not immediately mark the session bad again | 161 | retry so we do not immediately mark the |
160 | (ie after we reconnect below) as they timeout too */ | 162 | session bad again (ie after we reconnect |
163 | below) as they timeout too */ | ||
161 | mid_entry->midState = MID_RETRY_NEEDED; | 164 | mid_entry->midState = MID_RETRY_NEEDED; |
162 | } | 165 | } |
163 | } | 166 | } |
@@ -175,14 +178,14 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
175 | server->workstation_RFC1001_name); | 178 | server->workstation_RFC1001_name); |
176 | } | 179 | } |
177 | if(rc) { | 180 | if(rc) { |
178 | set_current_state(TASK_INTERRUPTIBLE); | 181 | msleep(3000); |
179 | schedule_timeout(3 * HZ); | ||
180 | } else { | 182 | } else { |
181 | atomic_inc(&tcpSesReconnectCount); | 183 | atomic_inc(&tcpSesReconnectCount); |
182 | spin_lock(&GlobalMid_Lock); | 184 | spin_lock(&GlobalMid_Lock); |
183 | if(server->tcpStatus != CifsExiting) | 185 | if(server->tcpStatus != CifsExiting) |
184 | server->tcpStatus = CifsGood; | 186 | server->tcpStatus = CifsGood; |
185 | spin_unlock(&GlobalMid_Lock); | 187 | server->sequence_number = 0; |
188 | spin_unlock(&GlobalMid_Lock); | ||
186 | /* atomic_set(&server->inFlight,0);*/ | 189 | /* atomic_set(&server->inFlight,0);*/ |
187 | wake_up(&server->response_q); | 190 | wake_up(&server->response_q); |
188 | } | 191 | } |
@@ -190,12 +193,129 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
190 | return rc; | 193 | return rc; |
191 | } | 194 | } |
192 | 195 | ||
196 | /* | ||
197 | return codes: | ||
198 | 0 not a transact2, or all data present | ||
199 | >0 transact2 with that much data missing | ||
200 | -EINVAL = invalid transact2 | ||
201 | |||
202 | */ | ||
203 | static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize) | ||
204 | { | ||
205 | struct smb_t2_rsp * pSMBt; | ||
206 | int total_data_size; | ||
207 | int data_in_this_rsp; | ||
208 | int remaining; | ||
209 | |||
210 | if(pSMB->Command != SMB_COM_TRANSACTION2) | ||
211 | return 0; | ||
212 | |||
213 | /* check for plausible wct, bcc and t2 data and parm sizes */ | ||
214 | /* check for parm and data offset going beyond end of smb */ | ||
215 | if(pSMB->WordCount != 10) { /* coalesce_t2 depends on this */ | ||
216 | cFYI(1,("invalid transact2 word count")); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | pSMBt = (struct smb_t2_rsp *)pSMB; | ||
221 | |||
222 | total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount); | ||
223 | data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount); | ||
224 | |||
225 | remaining = total_data_size - data_in_this_rsp; | ||
226 | |||
227 | if(remaining == 0) | ||
228 | return 0; | ||
229 | else if(remaining < 0) { | ||
230 | cFYI(1,("total data %d smaller than data in frame %d", | ||
231 | total_data_size, data_in_this_rsp)); | ||
232 | return -EINVAL; | ||
233 | } else { | ||
234 | cFYI(1,("missing %d bytes from transact2, check next response", | ||
235 | remaining)); | ||
236 | if(total_data_size > maxBufSize) { | ||
237 | cERROR(1,("TotalDataSize %d is over maximum buffer %d", | ||
238 | total_data_size,maxBufSize)); | ||
239 | return -EINVAL; | ||
240 | } | ||
241 | return remaining; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB) | ||
246 | { | ||
247 | struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond; | ||
248 | struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB; | ||
249 | int total_data_size; | ||
250 | int total_in_buf; | ||
251 | int remaining; | ||
252 | int total_in_buf2; | ||
253 | char * data_area_of_target; | ||
254 | char * data_area_of_buf2; | ||
255 | __u16 byte_count; | ||
256 | |||
257 | total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount); | ||
258 | |||
259 | if(total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) { | ||
260 | cFYI(1,("total data sizes of primary and secondary t2 differ")); | ||
261 | } | ||
262 | |||
263 | total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount); | ||
264 | |||
265 | remaining = total_data_size - total_in_buf; | ||
266 | |||
267 | if(remaining < 0) | ||
268 | return -EINVAL; | ||
269 | |||
270 | if(remaining == 0) /* nothing to do, ignore */ | ||
271 | return 0; | ||
272 | |||
273 | total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount); | ||
274 | if(remaining < total_in_buf2) { | ||
275 | cFYI(1,("transact2 2nd response contains too much data")); | ||
276 | } | ||
277 | |||
278 | /* find end of first SMB data area */ | ||
279 | data_area_of_target = (char *)&pSMBt->hdr.Protocol + | ||
280 | le16_to_cpu(pSMBt->t2_rsp.DataOffset); | ||
281 | /* validate target area */ | ||
282 | |||
283 | data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol + | ||
284 | le16_to_cpu(pSMB2->t2_rsp.DataOffset); | ||
285 | |||
286 | data_area_of_target += total_in_buf; | ||
287 | |||
288 | /* copy second buffer into end of first buffer */ | ||
289 | memcpy(data_area_of_target,data_area_of_buf2,total_in_buf2); | ||
290 | total_in_buf += total_in_buf2; | ||
291 | pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf); | ||
292 | byte_count = le16_to_cpu(BCC_LE(pTargetSMB)); | ||
293 | byte_count += total_in_buf2; | ||
294 | BCC_LE(pTargetSMB) = cpu_to_le16(byte_count); | ||
295 | |||
296 | byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); | ||
297 | byte_count += total_in_buf2; | ||
298 | |||
299 | /* BB also add check that we are not beyond maximum buffer size */ | ||
300 | |||
301 | pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); | ||
302 | |||
303 | if(remaining == total_in_buf2) { | ||
304 | cFYI(1,("found the last secondary response")); | ||
305 | return 0; /* we are done */ | ||
306 | } else /* more responses to go */ | ||
307 | return 1; | ||
308 | |||
309 | } | ||
310 | |||
193 | static int | 311 | static int |
194 | cifs_demultiplex_thread(struct TCP_Server_Info *server) | 312 | cifs_demultiplex_thread(struct TCP_Server_Info *server) |
195 | { | 313 | { |
196 | int length; | 314 | int length; |
197 | unsigned int pdu_length, total_read; | 315 | unsigned int pdu_length, total_read; |
198 | struct smb_hdr *smb_buffer = NULL; | 316 | struct smb_hdr *smb_buffer = NULL; |
317 | struct smb_hdr *bigbuf = NULL; | ||
318 | struct smb_hdr *smallbuf = NULL; | ||
199 | struct msghdr smb_msg; | 319 | struct msghdr smb_msg; |
200 | struct kvec iov; | 320 | struct kvec iov; |
201 | struct socket *csocket = server->ssocket; | 321 | struct socket *csocket = server->ssocket; |
@@ -204,6 +324,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
204 | struct task_struct *task_to_wake = NULL; | 324 | struct task_struct *task_to_wake = NULL; |
205 | struct mid_q_entry *mid_entry; | 325 | struct mid_q_entry *mid_entry; |
206 | char *temp; | 326 | char *temp; |
327 | int isLargeBuf = FALSE; | ||
328 | int isMultiRsp; | ||
329 | int reconnect; | ||
207 | 330 | ||
208 | daemonize("cifsd"); | 331 | daemonize("cifsd"); |
209 | allow_signal(SIGKILL); | 332 | allow_signal(SIGKILL); |
@@ -221,17 +344,34 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
221 | } | 344 | } |
222 | 345 | ||
223 | while (server->tcpStatus != CifsExiting) { | 346 | while (server->tcpStatus != CifsExiting) { |
224 | if (smb_buffer == NULL) | 347 | if (bigbuf == NULL) { |
225 | smb_buffer = cifs_buf_get(); | 348 | bigbuf = cifs_buf_get(); |
226 | else | 349 | if(bigbuf == NULL) { |
227 | memset(smb_buffer, 0, sizeof (struct smb_hdr)); | 350 | cERROR(1,("No memory for large SMB response")); |
228 | 351 | msleep(3000); | |
229 | if (smb_buffer == NULL) { | 352 | /* retry will check if exiting */ |
230 | cERROR(1,("Can not get memory for SMB response")); | 353 | continue; |
231 | set_current_state(TASK_INTERRUPTIBLE); | 354 | } |
232 | schedule_timeout(HZ * 3); /* give system time to free memory */ | 355 | } else if(isLargeBuf) { |
233 | continue; | 356 | /* we are reusing a dirtry large buf, clear its start */ |
357 | memset(bigbuf, 0, sizeof (struct smb_hdr)); | ||
234 | } | 358 | } |
359 | |||
360 | if (smallbuf == NULL) { | ||
361 | smallbuf = cifs_small_buf_get(); | ||
362 | if(smallbuf == NULL) { | ||
363 | cERROR(1,("No memory for SMB response")); | ||
364 | msleep(1000); | ||
365 | /* retry will check if exiting */ | ||
366 | continue; | ||
367 | } | ||
368 | /* beginning of smb buffer is cleared in our buf_get */ | ||
369 | } else /* if existing small buf clear beginning */ | ||
370 | memset(smallbuf, 0, sizeof (struct smb_hdr)); | ||
371 | |||
372 | isLargeBuf = FALSE; | ||
373 | isMultiRsp = FALSE; | ||
374 | smb_buffer = smallbuf; | ||
235 | iov.iov_base = smb_buffer; | 375 | iov.iov_base = smb_buffer; |
236 | iov.iov_len = 4; | 376 | iov.iov_len = 4; |
237 | smb_msg.msg_control = NULL; | 377 | smb_msg.msg_control = NULL; |
@@ -243,176 +383,257 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
243 | if(server->tcpStatus == CifsExiting) { | 383 | if(server->tcpStatus == CifsExiting) { |
244 | break; | 384 | break; |
245 | } else if (server->tcpStatus == CifsNeedReconnect) { | 385 | } else if (server->tcpStatus == CifsNeedReconnect) { |
246 | cFYI(1,("Reconnecting after server stopped responding")); | 386 | cFYI(1,("Reconnect after server stopped responding")); |
247 | cifs_reconnect(server); | 387 | cifs_reconnect(server); |
248 | cFYI(1,("call to reconnect done")); | 388 | cFYI(1,("call to reconnect done")); |
249 | csocket = server->ssocket; | 389 | csocket = server->ssocket; |
250 | continue; | 390 | continue; |
251 | } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { | 391 | } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { |
252 | set_current_state(TASK_INTERRUPTIBLE); | 392 | msleep(1); /* minimum sleep to prevent looping |
253 | schedule_timeout(1); /* minimum sleep to prevent looping | ||
254 | allowing socket to clear and app threads to set | 393 | allowing socket to clear and app threads to set |
255 | tcpStatus CifsNeedReconnect if server hung */ | 394 | tcpStatus CifsNeedReconnect if server hung */ |
256 | continue; | 395 | continue; |
257 | } else if (length <= 0) { | 396 | } else if (length <= 0) { |
258 | if(server->tcpStatus == CifsNew) { | 397 | if(server->tcpStatus == CifsNew) { |
259 | cFYI(1,("tcp session abended prematurely (after SMBnegprot)")); | 398 | cFYI(1,("tcp session abend after SMBnegprot")); |
260 | /* some servers kill tcp session rather than returning | 399 | /* some servers kill the TCP session rather than |
261 | smb negprot error in which case reconnecting here is | 400 | returning an SMB negprot error, in which |
262 | not going to help - return error to mount */ | 401 | case reconnecting here is not going to help, |
402 | and so simply return error to mount */ | ||
263 | break; | 403 | break; |
264 | } | 404 | } |
265 | if(length == -EINTR) { | 405 | if(length == -EINTR) { |
266 | cFYI(1,("cifsd thread killed")); | 406 | cFYI(1,("cifsd thread killed")); |
267 | break; | 407 | break; |
268 | } | 408 | } |
269 | cFYI(1,("Reconnecting after unexpected peek error %d",length)); | 409 | cFYI(1,("Reconnect after unexpected peek error %d", |
410 | length)); | ||
270 | cifs_reconnect(server); | 411 | cifs_reconnect(server); |
271 | csocket = server->ssocket; | 412 | csocket = server->ssocket; |
272 | wake_up(&server->response_q); | 413 | wake_up(&server->response_q); |
273 | continue; | 414 | continue; |
274 | } else if (length > 3) { | 415 | } else if (length < 4) { |
275 | pdu_length = ntohl(smb_buffer->smb_buf_length); | 416 | cFYI(1, |
276 | /* Only read pdu_length after below checks for too short (due | 417 | ("Frame under four bytes received (%d bytes long)", |
277 | to e.g. int overflow) and too long ie beyond end of buf */ | 418 | length)); |
278 | cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4)); | 419 | cifs_reconnect(server); |
279 | 420 | csocket = server->ssocket; | |
280 | temp = (char *) smb_buffer; | 421 | wake_up(&server->response_q); |
281 | if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) { | 422 | continue; |
282 | cFYI(0,("Received 4 byte keep alive packet")); | 423 | } |
283 | } else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) { | ||
284 | cFYI(1,("Good RFC 1002 session rsp")); | ||
285 | } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { | ||
286 | /* we get this from Windows 98 instead of error on SMB negprot response */ | ||
287 | cFYI(1,("Negative RFC 1002 Session Response Error 0x%x)",temp[4])); | ||
288 | if(server->tcpStatus == CifsNew) { | ||
289 | /* if nack on negprot (rather than | ||
290 | ret of smb negprot error) reconnecting | ||
291 | not going to help, ret error to mount */ | ||
292 | break; | ||
293 | } else { | ||
294 | /* give server a second to | ||
295 | clean up before reconnect attempt */ | ||
296 | set_current_state(TASK_INTERRUPTIBLE); | ||
297 | schedule_timeout(HZ); | ||
298 | /* always try 445 first on reconnect | ||
299 | since we get NACK on some if we ever | ||
300 | connected to port 139 (the NACK is | ||
301 | since we do not begin with RFC1001 | ||
302 | session initialize frame) */ | ||
303 | server->addr.sockAddr.sin_port = htons(CIFS_PORT); | ||
304 | cifs_reconnect(server); | ||
305 | csocket = server->ssocket; | ||
306 | wake_up(&server->response_q); | ||
307 | continue; | ||
308 | } | ||
309 | } else if (temp[0] != (char) 0) { | ||
310 | cERROR(1,("Unknown RFC 1002 frame")); | ||
311 | cifs_dump_mem(" Received Data: ", temp, length); | ||
312 | cifs_reconnect(server); | ||
313 | csocket = server->ssocket; | ||
314 | continue; | ||
315 | } else { | ||
316 | if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) | ||
317 | || (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { | ||
318 | cERROR(1, | ||
319 | ("Invalid size SMB length %d and pdu_length %d", | ||
320 | length, pdu_length+4)); | ||
321 | cifs_reconnect(server); | ||
322 | csocket = server->ssocket; | ||
323 | wake_up(&server->response_q); | ||
324 | continue; | ||
325 | } else { /* length ok */ | ||
326 | length = 0; | ||
327 | iov.iov_base = 4 + (char *)smb_buffer; | ||
328 | iov.iov_len = pdu_length; | ||
329 | for (total_read = 0; | ||
330 | total_read < pdu_length; | ||
331 | total_read += length) { | ||
332 | length = kernel_recvmsg(csocket, &smb_msg, | ||
333 | &iov, 1, | ||
334 | pdu_length - total_read, 0); | ||
335 | if (length == 0) { | ||
336 | cERROR(1, | ||
337 | ("Zero length receive when expecting %d ", | ||
338 | pdu_length - total_read)); | ||
339 | cifs_reconnect(server); | ||
340 | csocket = server->ssocket; | ||
341 | wake_up(&server->response_q); | ||
342 | continue; | ||
343 | } | ||
344 | } | ||
345 | length += 4; /* account for rfc1002 hdr */ | ||
346 | } | ||
347 | 424 | ||
348 | dump_smb(smb_buffer, length); | 425 | /* the right amount was read from socket - 4 bytes */ |
349 | if (checkSMB | ||
350 | (smb_buffer, smb_buffer->Mid, total_read+4)) { | ||
351 | cERROR(1, ("Bad SMB Received ")); | ||
352 | continue; | ||
353 | } | ||
354 | 426 | ||
355 | task_to_wake = NULL; | 427 | pdu_length = ntohl(smb_buffer->smb_buf_length); |
356 | spin_lock(&GlobalMid_Lock); | 428 | cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4)); |
357 | list_for_each(tmp, &server->pending_mid_q) { | ||
358 | mid_entry = list_entry(tmp, struct | ||
359 | mid_q_entry, | ||
360 | qhead); | ||
361 | 429 | ||
362 | if ((mid_entry->mid == smb_buffer->Mid) && (mid_entry->midState == MID_REQUEST_SUBMITTED)) { | 430 | temp = (char *) smb_buffer; |
363 | cFYI(1, | 431 | if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) { |
364 | (" Mid 0x%x matched - waking up ",mid_entry->mid)); | 432 | continue; |
365 | task_to_wake = mid_entry->tsk; | 433 | } else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { |
366 | mid_entry->resp_buf = | 434 | cFYI(1,("Good RFC 1002 session rsp")); |
367 | smb_buffer; | 435 | continue; |
368 | mid_entry->midState = | 436 | } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { |
369 | MID_RESPONSE_RECEIVED; | 437 | /* we get this from Windows 98 instead of |
370 | } | 438 | an error on SMB negprot response */ |
371 | } | 439 | cFYI(1,("Negative RFC1002 Session Response Error 0x%x)", |
372 | spin_unlock(&GlobalMid_Lock); | 440 | temp[4])); |
373 | if (task_to_wake) { | 441 | if(server->tcpStatus == CifsNew) { |
374 | smb_buffer = NULL; /* will be freed by users thread after he is done */ | 442 | /* if nack on negprot (rather than |
375 | wake_up_process(task_to_wake); | 443 | ret of smb negprot error) reconnecting |
376 | } else if (is_valid_oplock_break(smb_buffer) == FALSE) { | 444 | not going to help, ret error to mount */ |
377 | cERROR(1, ("No task to wake, unknown frame rcvd!")); | 445 | break; |
378 | cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)); | 446 | } else { |
379 | } | 447 | /* give server a second to |
448 | clean up before reconnect attempt */ | ||
449 | msleep(1000); | ||
450 | /* always try 445 first on reconnect | ||
451 | since we get NACK on some if we ever | ||
452 | connected to port 139 (the NACK is | ||
453 | since we do not begin with RFC1001 | ||
454 | session initialize frame) */ | ||
455 | server->addr.sockAddr.sin_port = | ||
456 | htons(CIFS_PORT); | ||
457 | cifs_reconnect(server); | ||
458 | csocket = server->ssocket; | ||
459 | wake_up(&server->response_q); | ||
460 | continue; | ||
380 | } | 461 | } |
381 | } else { | 462 | } else if (temp[0] != (char) 0) { |
382 | cFYI(1, | 463 | cERROR(1,("Unknown RFC 1002 frame")); |
383 | ("Frame less than four bytes received %d bytes long.", | 464 | cifs_dump_mem(" Received Data: ", temp, length); |
384 | length)); | 465 | cifs_reconnect(server); |
466 | csocket = server->ssocket; | ||
467 | continue; | ||
468 | } | ||
469 | |||
470 | /* else we have an SMB response */ | ||
471 | if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || | ||
472 | (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { | ||
473 | cERROR(1, ("Invalid size SMB length %d pdu_length %d", | ||
474 | length, pdu_length+4)); | ||
385 | cifs_reconnect(server); | 475 | cifs_reconnect(server); |
386 | csocket = server->ssocket; | 476 | csocket = server->ssocket; |
387 | wake_up(&server->response_q); | 477 | wake_up(&server->response_q); |
388 | continue; | 478 | continue; |
479 | } | ||
480 | |||
481 | /* else length ok */ | ||
482 | reconnect = 0; | ||
483 | |||
484 | if(pdu_length > MAX_CIFS_HDR_SIZE - 4) { | ||
485 | isLargeBuf = TRUE; | ||
486 | memcpy(bigbuf, smallbuf, 4); | ||
487 | smb_buffer = bigbuf; | ||
389 | } | 488 | } |
390 | } | 489 | length = 0; |
490 | iov.iov_base = 4 + (char *)smb_buffer; | ||
491 | iov.iov_len = pdu_length; | ||
492 | for (total_read = 0; total_read < pdu_length; | ||
493 | total_read += length) { | ||
494 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, | ||
495 | pdu_length - total_read, 0); | ||
496 | if((server->tcpStatus == CifsExiting) || | ||
497 | (length == -EINTR)) { | ||
498 | /* then will exit */ | ||
499 | reconnect = 2; | ||
500 | break; | ||
501 | } else if (server->tcpStatus == CifsNeedReconnect) { | ||
502 | cifs_reconnect(server); | ||
503 | csocket = server->ssocket; | ||
504 | /* Reconnect wakes up rspns q */ | ||
505 | /* Now we will reread sock */ | ||
506 | reconnect = 1; | ||
507 | break; | ||
508 | } else if ((length == -ERESTARTSYS) || | ||
509 | (length == -EAGAIN)) { | ||
510 | msleep(1); /* minimum sleep to prevent looping, | ||
511 | allowing socket to clear and app | ||
512 | threads to set tcpStatus | ||
513 | CifsNeedReconnect if server hung*/ | ||
514 | continue; | ||
515 | } else if (length <= 0) { | ||
516 | cERROR(1,("Received no data, expecting %d", | ||
517 | pdu_length - total_read)); | ||
518 | cifs_reconnect(server); | ||
519 | csocket = server->ssocket; | ||
520 | reconnect = 1; | ||
521 | break; | ||
522 | } | ||
523 | } | ||
524 | if(reconnect == 2) | ||
525 | break; | ||
526 | else if(reconnect == 1) | ||
527 | continue; | ||
528 | |||
529 | length += 4; /* account for rfc1002 hdr */ | ||
530 | |||
531 | |||
532 | dump_smb(smb_buffer, length); | ||
533 | if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { | ||
534 | cERROR(1, ("Bad SMB Received ")); | ||
535 | continue; | ||
536 | } | ||
537 | |||
538 | |||
539 | task_to_wake = NULL; | ||
540 | spin_lock(&GlobalMid_Lock); | ||
541 | list_for_each(tmp, &server->pending_mid_q) { | ||
542 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | ||
543 | |||
544 | if ((mid_entry->mid == smb_buffer->Mid) && | ||
545 | (mid_entry->midState == MID_REQUEST_SUBMITTED) && | ||
546 | (mid_entry->command == smb_buffer->Command)) { | ||
547 | if(check2ndT2(smb_buffer,server->maxBuf) > 0) { | ||
548 | /* We have a multipart transact2 resp */ | ||
549 | isMultiRsp = TRUE; | ||
550 | if(mid_entry->resp_buf) { | ||
551 | /* merge response - fix up 1st*/ | ||
552 | if(coalesce_t2(smb_buffer, | ||
553 | mid_entry->resp_buf)) { | ||
554 | break; | ||
555 | } else { | ||
556 | /* all parts received */ | ||
557 | goto multi_t2_fnd; | ||
558 | } | ||
559 | } else { | ||
560 | if(!isLargeBuf) { | ||
561 | cERROR(1,("1st trans2 resp needs bigbuf")); | ||
562 | /* BB maybe we can fix this up, switch | ||
563 | to already allocated large buffer? */ | ||
564 | } else { | ||
565 | /* Have first buffer */ | ||
566 | mid_entry->resp_buf = | ||
567 | smb_buffer; | ||
568 | mid_entry->largeBuf = 1; | ||
569 | bigbuf = NULL; | ||
570 | } | ||
571 | } | ||
572 | break; | ||
573 | } | ||
574 | mid_entry->resp_buf = smb_buffer; | ||
575 | if(isLargeBuf) | ||
576 | mid_entry->largeBuf = 1; | ||
577 | else | ||
578 | mid_entry->largeBuf = 0; | ||
579 | multi_t2_fnd: | ||
580 | task_to_wake = mid_entry->tsk; | ||
581 | mid_entry->midState = MID_RESPONSE_RECEIVED; | ||
582 | break; | ||
583 | } | ||
584 | } | ||
585 | spin_unlock(&GlobalMid_Lock); | ||
586 | if (task_to_wake) { | ||
587 | /* Was previous buf put in mpx struct for multi-rsp? */ | ||
588 | if(!isMultiRsp) { | ||
589 | /* smb buffer will be freed by user thread */ | ||
590 | if(isLargeBuf) { | ||
591 | bigbuf = NULL; | ||
592 | } else | ||
593 | smallbuf = NULL; | ||
594 | } | ||
595 | wake_up_process(task_to_wake); | ||
596 | } else if ((is_valid_oplock_break(smb_buffer) == FALSE) | ||
597 | && (isMultiRsp == FALSE)) { | ||
598 | cERROR(1, ("No task to wake, unknown frame rcvd!")); | ||
599 | cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)); | ||
600 | } | ||
601 | } /* end while !EXITING */ | ||
602 | |||
391 | spin_lock(&GlobalMid_Lock); | 603 | spin_lock(&GlobalMid_Lock); |
392 | server->tcpStatus = CifsExiting; | 604 | server->tcpStatus = CifsExiting; |
393 | server->tsk = NULL; | 605 | server->tsk = NULL; |
394 | atomic_set(&server->inFlight, 0); | 606 | /* check if we have blocked requests that need to free */ |
607 | /* Note that cifs_max_pending is normally 50, but | ||
608 | can be set at module install time to as little as two */ | ||
609 | if(atomic_read(&server->inFlight) >= cifs_max_pending) | ||
610 | atomic_set(&server->inFlight, cifs_max_pending - 1); | ||
611 | /* We do not want to set the max_pending too low or we | ||
612 | could end up with the counter going negative */ | ||
395 | spin_unlock(&GlobalMid_Lock); | 613 | spin_unlock(&GlobalMid_Lock); |
396 | /* Although there should not be any requests blocked on | 614 | /* Although there should not be any requests blocked on |
397 | this queue it can not hurt to be paranoid and try to wake up requests | 615 | this queue it can not hurt to be paranoid and try to wake up requests |
398 | that may haven been blocked when more than 50 at time were on the wire | 616 | that may haven been blocked when more than 50 at time were on the wire |
399 | to the same server - they now will see the session is in exit state | 617 | to the same server - they now will see the session is in exit state |
400 | and get out of SendReceive. */ | 618 | and get out of SendReceive. */ |
401 | wake_up_all(&server->request_q); | 619 | wake_up_all(&server->request_q); |
402 | /* give those requests time to exit */ | 620 | /* give those requests time to exit */ |
403 | set_current_state(TASK_INTERRUPTIBLE); | 621 | msleep(125); |
404 | schedule_timeout(HZ/8); | 622 | |
405 | |||
406 | if(server->ssocket) { | 623 | if(server->ssocket) { |
407 | sock_release(csocket); | 624 | sock_release(csocket); |
408 | server->ssocket = NULL; | 625 | server->ssocket = NULL; |
409 | } | 626 | } |
410 | if (smb_buffer) /* buffer usually freed in free_mid - need to free it on error or exit */ | 627 | /* buffer usuallly freed in free_mid - need to free it here on exit */ |
411 | cifs_buf_release(smb_buffer); | 628 | if (bigbuf != NULL) |
629 | cifs_buf_release(bigbuf); | ||
630 | if (smallbuf != NULL) | ||
631 | cifs_small_buf_release(smallbuf); | ||
412 | 632 | ||
413 | read_lock(&GlobalSMBSeslock); | 633 | read_lock(&GlobalSMBSeslock); |
414 | if (list_empty(&server->pending_mid_q)) { | 634 | if (list_empty(&server->pending_mid_q)) { |
415 | /* loop through server session structures attached to this and mark them dead */ | 635 | /* loop through server session structures attached to this and |
636 | mark them dead */ | ||
416 | list_for_each(tmp, &GlobalSMBSessionList) { | 637 | list_for_each(tmp, &GlobalSMBSessionList) { |
417 | ses = | 638 | ses = |
418 | list_entry(tmp, struct cifsSesInfo, | 639 | list_entry(tmp, struct cifsSesInfo, |
@@ -424,12 +645,23 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
424 | } | 645 | } |
425 | read_unlock(&GlobalSMBSeslock); | 646 | read_unlock(&GlobalSMBSeslock); |
426 | } else { | 647 | } else { |
648 | /* although we can not zero the server struct pointer yet, | ||
649 | since there are active requests which may depnd on them, | ||
650 | mark the corresponding SMB sessions as exiting too */ | ||
651 | list_for_each(tmp, &GlobalSMBSessionList) { | ||
652 | ses = list_entry(tmp, struct cifsSesInfo, | ||
653 | cifsSessionList); | ||
654 | if (ses->server == server) { | ||
655 | ses->status = CifsExiting; | ||
656 | } | ||
657 | } | ||
658 | |||
427 | spin_lock(&GlobalMid_Lock); | 659 | spin_lock(&GlobalMid_Lock); |
428 | list_for_each(tmp, &server->pending_mid_q) { | 660 | list_for_each(tmp, &server->pending_mid_q) { |
429 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 661 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
430 | if (mid_entry->midState == MID_REQUEST_SUBMITTED) { | 662 | if (mid_entry->midState == MID_REQUEST_SUBMITTED) { |
431 | cFYI(1, | 663 | cFYI(1, |
432 | (" Clearing Mid 0x%x - waking up ",mid_entry->mid)); | 664 | ("Clearing Mid 0x%x - waking up ",mid_entry->mid)); |
433 | task_to_wake = mid_entry->tsk; | 665 | task_to_wake = mid_entry->tsk; |
434 | if(task_to_wake) { | 666 | if(task_to_wake) { |
435 | wake_up_process(task_to_wake); | 667 | wake_up_process(task_to_wake); |
@@ -438,47 +670,51 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
438 | } | 670 | } |
439 | spin_unlock(&GlobalMid_Lock); | 671 | spin_unlock(&GlobalMid_Lock); |
440 | read_unlock(&GlobalSMBSeslock); | 672 | read_unlock(&GlobalSMBSeslock); |
441 | set_current_state(TASK_INTERRUPTIBLE); | ||
442 | /* 1/8th of sec is more than enough time for them to exit */ | 673 | /* 1/8th of sec is more than enough time for them to exit */ |
443 | schedule_timeout(HZ/8); | 674 | msleep(125); |
444 | } | 675 | } |
445 | 676 | ||
446 | if (list_empty(&server->pending_mid_q)) { | 677 | if (list_empty(&server->pending_mid_q)) { |
447 | /* mpx threads have not exited yet give them | 678 | /* mpx threads have not exited yet give them |
448 | at least the smb send timeout time for long ops */ | 679 | at least the smb send timeout time for long ops */ |
680 | /* due to delays on oplock break requests, we need | ||
681 | to wait at least 45 seconds before giving up | ||
682 | on a request getting a response and going ahead | ||
683 | and killing cifsd */ | ||
449 | cFYI(1, ("Wait for exit from demultiplex thread")); | 684 | cFYI(1, ("Wait for exit from demultiplex thread")); |
450 | set_current_state(TASK_INTERRUPTIBLE); | 685 | msleep(46000); |
451 | schedule_timeout(46 * HZ); | ||
452 | /* if threads still have not exited they are probably never | 686 | /* if threads still have not exited they are probably never |
453 | coming home not much else we can do but free the memory */ | 687 | coming home not much else we can do but free the memory */ |
454 | } | 688 | } |
455 | kfree(server); | ||
456 | 689 | ||
457 | write_lock(&GlobalSMBSeslock); | 690 | write_lock(&GlobalSMBSeslock); |
458 | atomic_dec(&tcpSesAllocCount); | 691 | atomic_dec(&tcpSesAllocCount); |
459 | length = tcpSesAllocCount.counter; | 692 | length = tcpSesAllocCount.counter; |
693 | |||
694 | /* last chance to mark ses pointers invalid | ||
695 | if there are any pointing to this (e.g | ||
696 | if a crazy root user tried to kill cifsd | ||
697 | kernel thread explicitly this might happen) */ | ||
698 | list_for_each(tmp, &GlobalSMBSessionList) { | ||
699 | ses = list_entry(tmp, struct cifsSesInfo, | ||
700 | cifsSessionList); | ||
701 | if (ses->server == server) { | ||
702 | ses->server = NULL; | ||
703 | } | ||
704 | } | ||
460 | write_unlock(&GlobalSMBSeslock); | 705 | write_unlock(&GlobalSMBSeslock); |
706 | |||
707 | kfree(server); | ||
461 | if(length > 0) { | 708 | if(length > 0) { |
462 | mempool_resize(cifs_req_poolp, | 709 | mempool_resize(cifs_req_poolp, |
463 | length + cifs_min_rcv, | 710 | length + cifs_min_rcv, |
464 | GFP_KERNEL); | 711 | GFP_KERNEL); |
465 | } | 712 | } |
466 | 713 | ||
467 | set_current_state(TASK_INTERRUPTIBLE); | 714 | msleep(250); |
468 | schedule_timeout(HZ/4); | ||
469 | return 0; | 715 | return 0; |
470 | } | 716 | } |
471 | 717 | ||
472 | static void * | ||
473 | cifs_kcalloc(size_t size, unsigned int __nocast type) | ||
474 | { | ||
475 | void *addr; | ||
476 | addr = kmalloc(size, type); | ||
477 | if (addr) | ||
478 | memset(addr, 0, size); | ||
479 | return addr; | ||
480 | } | ||
481 | |||
482 | static int | 718 | static int |
483 | cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | 719 | cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) |
484 | { | 720 | { |
@@ -495,7 +731,8 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
495 | /* does not have to be a perfect mapping since the field is | 731 | /* does not have to be a perfect mapping since the field is |
496 | informational, only used for servers that do not support | 732 | informational, only used for servers that do not support |
497 | port 445 and it can be overridden at mount time */ | 733 | port 445 and it can be overridden at mount time */ |
498 | vol->source_rfc1001_name[i] = toupper(system_utsname.nodename[i]); | 734 | vol->source_rfc1001_name[i] = |
735 | toupper(system_utsname.nodename[i]); | ||
499 | } | 736 | } |
500 | vol->source_rfc1001_name[15] = 0; | 737 | vol->source_rfc1001_name[15] = 0; |
501 | 738 | ||
@@ -570,14 +807,17 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
570 | /* NB: password legally can have multiple commas and | 807 | /* NB: password legally can have multiple commas and |
571 | the only illegal character in a password is null */ | 808 | the only illegal character in a password is null */ |
572 | 809 | ||
573 | if ((value[temp_len] == 0) && (value[temp_len+1] == separator[0])) { | 810 | if ((value[temp_len] == 0) && |
811 | (value[temp_len+1] == separator[0])) { | ||
574 | /* reinsert comma */ | 812 | /* reinsert comma */ |
575 | value[temp_len] = separator[0]; | 813 | value[temp_len] = separator[0]; |
576 | temp_len+=2; /* move after the second comma */ | 814 | temp_len+=2; /* move after the second comma */ |
577 | while(value[temp_len] != 0) { | 815 | while(value[temp_len] != 0) { |
578 | if (value[temp_len] == separator[0]) { | 816 | if (value[temp_len] == separator[0]) { |
579 | if (value[temp_len+1] == separator[0]) { | 817 | if (value[temp_len+1] == |
580 | temp_len++; /* skip second comma */ | 818 | separator[0]) { |
819 | /* skip second comma */ | ||
820 | temp_len++; | ||
581 | } else { | 821 | } else { |
582 | /* single comma indicating start | 822 | /* single comma indicating start |
583 | of next parm */ | 823 | of next parm */ |
@@ -596,17 +836,26 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
596 | /* go from value to value + temp_len condensing | 836 | /* go from value to value + temp_len condensing |
597 | double commas to singles. Note that this ends up | 837 | double commas to singles. Note that this ends up |
598 | allocating a few bytes too many, which is ok */ | 838 | allocating a few bytes too many, which is ok */ |
599 | vol->password = cifs_kcalloc(temp_len, GFP_KERNEL); | 839 | vol->password = kcalloc(1, temp_len, GFP_KERNEL); |
840 | if(vol->password == NULL) { | ||
841 | printk("CIFS: no memory for pass\n"); | ||
842 | return 1; | ||
843 | } | ||
600 | for(i=0,j=0;i<temp_len;i++,j++) { | 844 | for(i=0,j=0;i<temp_len;i++,j++) { |
601 | vol->password[j] = value[i]; | 845 | vol->password[j] = value[i]; |
602 | if(value[i] == separator[0] && value[i+1] == separator[0]) { | 846 | if(value[i] == separator[0] |
847 | && value[i+1] == separator[0]) { | ||
603 | /* skip second comma */ | 848 | /* skip second comma */ |
604 | i++; | 849 | i++; |
605 | } | 850 | } |
606 | } | 851 | } |
607 | vol->password[j] = 0; | 852 | vol->password[j] = 0; |
608 | } else { | 853 | } else { |
609 | vol->password = cifs_kcalloc(temp_len + 1, GFP_KERNEL); | 854 | vol->password = kcalloc(1, temp_len+1, GFP_KERNEL); |
855 | if(vol->password == NULL) { | ||
856 | printk("CIFS: no memory for pass\n"); | ||
857 | return 1; | ||
858 | } | ||
610 | strcpy(vol->password, value); | 859 | strcpy(vol->password, value); |
611 | } | 860 | } |
612 | } else if (strnicmp(data, "ip", 2) == 0) { | 861 | } else if (strnicmp(data, "ip", 2) == 0) { |
@@ -770,6 +1019,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
770 | vol->noperm = 0; | 1019 | vol->noperm = 0; |
771 | } else if (strnicmp(data, "noperm", 6) == 0) { | 1020 | } else if (strnicmp(data, "noperm", 6) == 0) { |
772 | vol->noperm = 1; | 1021 | vol->noperm = 1; |
1022 | } else if (strnicmp(data, "mapchars", 8) == 0) { | ||
1023 | vol->remap = 1; | ||
1024 | } else if (strnicmp(data, "nomapchars", 10) == 0) { | ||
1025 | vol->remap = 0; | ||
773 | } else if (strnicmp(data, "setuids", 7) == 0) { | 1026 | } else if (strnicmp(data, "setuids", 7) == 0) { |
774 | vol->setuids = 1; | 1027 | vol->setuids = 1; |
775 | } else if (strnicmp(data, "nosetuids", 9) == 0) { | 1028 | } else if (strnicmp(data, "nosetuids", 9) == 0) { |
@@ -918,14 +1171,15 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName) | |||
918 | 1171 | ||
919 | int | 1172 | int |
920 | connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | 1173 | connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, |
921 | const char *old_path, const struct nls_table *nls_codepage) | 1174 | const char *old_path, const struct nls_table *nls_codepage, |
1175 | int remap) | ||
922 | { | 1176 | { |
923 | unsigned char *referrals = NULL; | 1177 | unsigned char *referrals = NULL; |
924 | unsigned int num_referrals; | 1178 | unsigned int num_referrals; |
925 | int rc = 0; | 1179 | int rc = 0; |
926 | 1180 | ||
927 | rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, | 1181 | rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, |
928 | &num_referrals, &referrals); | 1182 | &num_referrals, &referrals, remap); |
929 | 1183 | ||
930 | /* BB Add in code to: if valid refrl, if not ip address contact | 1184 | /* BB Add in code to: if valid refrl, if not ip address contact |
931 | the helper that resolves tcp names, mount to it, try to | 1185 | the helper that resolves tcp names, mount to it, try to |
@@ -940,7 +1194,8 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | |||
940 | int | 1194 | int |
941 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | 1195 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, |
942 | const char *old_path, const struct nls_table *nls_codepage, | 1196 | const char *old_path, const struct nls_table *nls_codepage, |
943 | unsigned int *pnum_referrals, unsigned char ** preferrals) | 1197 | unsigned int *pnum_referrals, |
1198 | unsigned char ** preferrals, int remap) | ||
944 | { | 1199 | { |
945 | char *temp_unc; | 1200 | char *temp_unc; |
946 | int rc = 0; | 1201 | int rc = 0; |
@@ -965,7 +1220,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | |||
965 | } | 1220 | } |
966 | if (rc == 0) | 1221 | if (rc == 0) |
967 | rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, | 1222 | rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, |
968 | pnum_referrals, nls_codepage); | 1223 | pnum_referrals, nls_codepage, remap); |
969 | 1224 | ||
970 | return rc; | 1225 | return rc; |
971 | } | 1226 | } |
@@ -1062,7 +1317,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1062 | sessinit is sent but no second negprot */ | 1317 | sessinit is sent but no second negprot */ |
1063 | struct rfc1002_session_packet * ses_init_buf; | 1318 | struct rfc1002_session_packet * ses_init_buf; |
1064 | struct smb_hdr * smb_buf; | 1319 | struct smb_hdr * smb_buf; |
1065 | ses_init_buf = cifs_kcalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL); | 1320 | ses_init_buf = kcalloc(1, sizeof(struct rfc1002_session_packet), GFP_KERNEL); |
1066 | if(ses_init_buf) { | 1321 | if(ses_init_buf) { |
1067 | ses_init_buf->trailer.session_req.called_len = 32; | 1322 | ses_init_buf->trailer.session_req.called_len = 32; |
1068 | rfc1002mangle(ses_init_buf->trailer.session_req.called_name, | 1323 | rfc1002mangle(ses_init_buf->trailer.session_req.called_name, |
@@ -1352,6 +1607,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1352 | } else | 1607 | } else |
1353 | rc = 0; | 1608 | rc = 0; |
1354 | memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); | 1609 | memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); |
1610 | srvTcp->sequence_number = 0; | ||
1355 | } | 1611 | } |
1356 | } | 1612 | } |
1357 | 1613 | ||
@@ -1419,6 +1675,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1419 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; | 1675 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; |
1420 | if(volume_info.server_ino) | 1676 | if(volume_info.server_ino) |
1421 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; | 1677 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; |
1678 | if(volume_info.remap) | ||
1679 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; | ||
1422 | if(volume_info.no_xattr) | 1680 | if(volume_info.no_xattr) |
1423 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; | 1681 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; |
1424 | if(volume_info.direct_io) { | 1682 | if(volume_info.direct_io) { |
@@ -1447,11 +1705,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1447 | if ((strchr(volume_info.UNC + 3, '\\') == NULL) | 1705 | if ((strchr(volume_info.UNC + 3, '\\') == NULL) |
1448 | && (strchr(volume_info.UNC + 3, '/') == | 1706 | && (strchr(volume_info.UNC + 3, '/') == |
1449 | NULL)) { | 1707 | NULL)) { |
1450 | rc = connect_to_dfs_path(xid, | 1708 | rc = connect_to_dfs_path(xid, pSesInfo, |
1451 | pSesInfo, | 1709 | "", cifs_sb->local_nls, |
1452 | "", | 1710 | cifs_sb->mnt_cifs_flags & |
1453 | cifs_sb-> | 1711 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1454 | local_nls); | ||
1455 | if(volume_info.UNC) | 1712 | if(volume_info.UNC) |
1456 | kfree(volume_info.UNC); | 1713 | kfree(volume_info.UNC); |
1457 | FreeXid(xid); | 1714 | FreeXid(xid); |
@@ -1514,10 +1771,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1514 | tcon->ses = pSesInfo; | 1771 | tcon->ses = pSesInfo; |
1515 | 1772 | ||
1516 | /* do not care if following two calls succeed - informational only */ | 1773 | /* do not care if following two calls succeed - informational only */ |
1517 | CIFSSMBQFSDeviceInfo(xid, tcon, cifs_sb->local_nls); | 1774 | CIFSSMBQFSDeviceInfo(xid, tcon); |
1518 | CIFSSMBQFSAttributeInfo(xid, tcon, cifs_sb->local_nls); | 1775 | CIFSSMBQFSAttributeInfo(xid, tcon); |
1519 | if (tcon->ses->capabilities & CAP_UNIX) { | 1776 | if (tcon->ses->capabilities & CAP_UNIX) { |
1520 | if(!CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls)) { | 1777 | if(!CIFSSMBQFSUnixInfo(xid, tcon)) { |
1521 | if(!volume_info.no_psx_acl) { | 1778 | if(!volume_info.no_psx_acl) { |
1522 | if(CIFS_UNIX_POSIX_ACL_CAP & | 1779 | if(CIFS_UNIX_POSIX_ACL_CAP & |
1523 | le64_to_cpu(tcon->fsUnixInfo.Capability)) | 1780 | le64_to_cpu(tcon->fsUnixInfo.Capability)) |
@@ -1707,7 +1964,9 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1707 | /* We look for obvious messed up bcc or strings in response so we do not go off | 1964 | /* We look for obvious messed up bcc or strings in response so we do not go off |
1708 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 1965 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
1709 | terminating last Unicode string in response */ | 1966 | terminating last Unicode string in response */ |
1710 | ses->serverOS = cifs_kcalloc(2 * (len + 1), GFP_KERNEL); | 1967 | ses->serverOS = kcalloc(1, 2 * (len + 1), GFP_KERNEL); |
1968 | if(ses->serverOS == NULL) | ||
1969 | goto sesssetup_nomem; | ||
1711 | cifs_strfromUCS_le(ses->serverOS, | 1970 | cifs_strfromUCS_le(ses->serverOS, |
1712 | (wchar_t *)bcc_ptr, len,nls_codepage); | 1971 | (wchar_t *)bcc_ptr, len,nls_codepage); |
1713 | bcc_ptr += 2 * (len + 1); | 1972 | bcc_ptr += 2 * (len + 1); |
@@ -1717,7 +1976,9 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1717 | if (remaining_words > 0) { | 1976 | if (remaining_words > 0) { |
1718 | len = UniStrnlen((wchar_t *)bcc_ptr, | 1977 | len = UniStrnlen((wchar_t *)bcc_ptr, |
1719 | remaining_words-1); | 1978 | remaining_words-1); |
1720 | ses->serverNOS =cifs_kcalloc(2 * (len + 1),GFP_KERNEL); | 1979 | ses->serverNOS = kcalloc(1, 2 * (len + 1),GFP_KERNEL); |
1980 | if(ses->serverNOS == NULL) | ||
1981 | goto sesssetup_nomem; | ||
1721 | cifs_strfromUCS_le(ses->serverNOS, | 1982 | cifs_strfromUCS_le(ses->serverNOS, |
1722 | (wchar_t *)bcc_ptr,len,nls_codepage); | 1983 | (wchar_t *)bcc_ptr,len,nls_codepage); |
1723 | bcc_ptr += 2 * (len + 1); | 1984 | bcc_ptr += 2 * (len + 1); |
@@ -1730,10 +1991,12 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1730 | } | 1991 | } |
1731 | remaining_words -= len + 1; | 1992 | remaining_words -= len + 1; |
1732 | if (remaining_words > 0) { | 1993 | if (remaining_words > 0) { |
1733 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 1994 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
1734 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ | 1995 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ |
1735 | ses->serverDomain = | 1996 | ses->serverDomain = |
1736 | cifs_kcalloc(2*(len+1),GFP_KERNEL); | 1997 | kcalloc(1, 2*(len+1),GFP_KERNEL); |
1998 | if(ses->serverDomain == NULL) | ||
1999 | goto sesssetup_nomem; | ||
1737 | cifs_strfromUCS_le(ses->serverDomain, | 2000 | cifs_strfromUCS_le(ses->serverDomain, |
1738 | (wchar_t *)bcc_ptr,len,nls_codepage); | 2001 | (wchar_t *)bcc_ptr,len,nls_codepage); |
1739 | bcc_ptr += 2 * (len + 1); | 2002 | bcc_ptr += 2 * (len + 1); |
@@ -1741,21 +2004,25 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1741 | ses->serverDomain[1+(2*len)] = 0; | 2004 | ses->serverDomain[1+(2*len)] = 0; |
1742 | } /* else no more room so create dummy domain string */ | 2005 | } /* else no more room so create dummy domain string */ |
1743 | else | 2006 | else |
1744 | ses->serverDomain = | 2007 | ses->serverDomain = |
1745 | cifs_kcalloc(2, | 2008 | kcalloc(1, 2, GFP_KERNEL); |
1746 | GFP_KERNEL); | ||
1747 | } else { /* no room so create dummy domain and NOS string */ | 2009 | } else { /* no room so create dummy domain and NOS string */ |
2010 | /* if these kcallocs fail not much we | ||
2011 | can do, but better to not fail the | ||
2012 | sesssetup itself */ | ||
1748 | ses->serverDomain = | 2013 | ses->serverDomain = |
1749 | cifs_kcalloc(2, GFP_KERNEL); | 2014 | kcalloc(1, 2, GFP_KERNEL); |
1750 | ses->serverNOS = | 2015 | ses->serverNOS = |
1751 | cifs_kcalloc(2, GFP_KERNEL); | 2016 | kcalloc(1, 2, GFP_KERNEL); |
1752 | } | 2017 | } |
1753 | } else { /* ASCII */ | 2018 | } else { /* ASCII */ |
1754 | len = strnlen(bcc_ptr, 1024); | 2019 | len = strnlen(bcc_ptr, 1024); |
1755 | if (((long) bcc_ptr + len) - (long) | 2020 | if (((long) bcc_ptr + len) - (long) |
1756 | pByteArea(smb_buffer_response) | 2021 | pByteArea(smb_buffer_response) |
1757 | <= BCC(smb_buffer_response)) { | 2022 | <= BCC(smb_buffer_response)) { |
1758 | ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL); | 2023 | ses->serverOS = kcalloc(1, len + 1,GFP_KERNEL); |
2024 | if(ses->serverOS == NULL) | ||
2025 | goto sesssetup_nomem; | ||
1759 | strncpy(ses->serverOS,bcc_ptr, len); | 2026 | strncpy(ses->serverOS,bcc_ptr, len); |
1760 | 2027 | ||
1761 | bcc_ptr += len; | 2028 | bcc_ptr += len; |
@@ -1763,14 +2030,18 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1763 | bcc_ptr++; | 2030 | bcc_ptr++; |
1764 | 2031 | ||
1765 | len = strnlen(bcc_ptr, 1024); | 2032 | len = strnlen(bcc_ptr, 1024); |
1766 | ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL); | 2033 | ses->serverNOS = kcalloc(1, len + 1,GFP_KERNEL); |
2034 | if(ses->serverNOS == NULL) | ||
2035 | goto sesssetup_nomem; | ||
1767 | strncpy(ses->serverNOS, bcc_ptr, len); | 2036 | strncpy(ses->serverNOS, bcc_ptr, len); |
1768 | bcc_ptr += len; | 2037 | bcc_ptr += len; |
1769 | bcc_ptr[0] = 0; | 2038 | bcc_ptr[0] = 0; |
1770 | bcc_ptr++; | 2039 | bcc_ptr++; |
1771 | 2040 | ||
1772 | len = strnlen(bcc_ptr, 1024); | 2041 | len = strnlen(bcc_ptr, 1024); |
1773 | ses->serverDomain = cifs_kcalloc(len + 1,GFP_KERNEL); | 2042 | ses->serverDomain = kcalloc(1, len + 1,GFP_KERNEL); |
2043 | if(ses->serverDomain == NULL) | ||
2044 | goto sesssetup_nomem; | ||
1774 | strncpy(ses->serverDomain, bcc_ptr, len); | 2045 | strncpy(ses->serverDomain, bcc_ptr, len); |
1775 | bcc_ptr += len; | 2046 | bcc_ptr += len; |
1776 | bcc_ptr[0] = 0; | 2047 | bcc_ptr[0] = 0; |
@@ -1790,7 +2061,9 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1790 | smb_buffer_response->WordCount)); | 2061 | smb_buffer_response->WordCount)); |
1791 | rc = -EIO; | 2062 | rc = -EIO; |
1792 | } | 2063 | } |
1793 | 2064 | sesssetup_nomem: /* do not return an error on nomem for the info strings, | |
2065 | since that could make reconnection harder, and | ||
2066 | reconnection might be needed to free memory */ | ||
1794 | if (smb_buffer) | 2067 | if (smb_buffer) |
1795 | cifs_buf_release(smb_buffer); | 2068 | cifs_buf_release(smb_buffer); |
1796 | 2069 | ||
@@ -1967,7 +2240,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1967 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 2240 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
1968 | terminating last Unicode string in response */ | 2241 | terminating last Unicode string in response */ |
1969 | ses->serverOS = | 2242 | ses->serverOS = |
1970 | cifs_kcalloc(2 * (len + 1), GFP_KERNEL); | 2243 | kcalloc(1, 2 * (len + 1), GFP_KERNEL); |
1971 | cifs_strfromUCS_le(ses->serverOS, | 2244 | cifs_strfromUCS_le(ses->serverOS, |
1972 | (wchar_t *) | 2245 | (wchar_t *) |
1973 | bcc_ptr, len, | 2246 | bcc_ptr, len, |
@@ -1981,7 +2254,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1981 | remaining_words | 2254 | remaining_words |
1982 | - 1); | 2255 | - 1); |
1983 | ses->serverNOS = | 2256 | ses->serverNOS = |
1984 | cifs_kcalloc(2 * (len + 1), | 2257 | kcalloc(1, 2 * (len + 1), |
1985 | GFP_KERNEL); | 2258 | GFP_KERNEL); |
1986 | cifs_strfromUCS_le(ses->serverNOS, | 2259 | cifs_strfromUCS_le(ses->serverNOS, |
1987 | (wchar_t *)bcc_ptr, | 2260 | (wchar_t *)bcc_ptr, |
@@ -1994,7 +2267,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1994 | if (remaining_words > 0) { | 2267 | if (remaining_words > 0) { |
1995 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 2268 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
1996 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ | 2269 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ |
1997 | ses->serverDomain = cifs_kcalloc(2*(len+1),GFP_KERNEL); | 2270 | ses->serverDomain = kcalloc(1, 2*(len+1),GFP_KERNEL); |
1998 | cifs_strfromUCS_le(ses->serverDomain, | 2271 | cifs_strfromUCS_le(ses->serverDomain, |
1999 | (wchar_t *)bcc_ptr, | 2272 | (wchar_t *)bcc_ptr, |
2000 | len, | 2273 | len, |
@@ -2005,10 +2278,10 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2005 | } /* else no more room so create dummy domain string */ | 2278 | } /* else no more room so create dummy domain string */ |
2006 | else | 2279 | else |
2007 | ses->serverDomain = | 2280 | ses->serverDomain = |
2008 | cifs_kcalloc(2,GFP_KERNEL); | 2281 | kcalloc(1, 2,GFP_KERNEL); |
2009 | } else { /* no room so create dummy domain and NOS string */ | 2282 | } else { /* no room so create dummy domain and NOS string */ |
2010 | ses->serverDomain = cifs_kcalloc(2, GFP_KERNEL); | 2283 | ses->serverDomain = kcalloc(1, 2, GFP_KERNEL); |
2011 | ses->serverNOS = cifs_kcalloc(2, GFP_KERNEL); | 2284 | ses->serverNOS = kcalloc(1, 2, GFP_KERNEL); |
2012 | } | 2285 | } |
2013 | } else { /* ASCII */ | 2286 | } else { /* ASCII */ |
2014 | 2287 | ||
@@ -2016,7 +2289,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2016 | if (((long) bcc_ptr + len) - (long) | 2289 | if (((long) bcc_ptr + len) - (long) |
2017 | pByteArea(smb_buffer_response) | 2290 | pByteArea(smb_buffer_response) |
2018 | <= BCC(smb_buffer_response)) { | 2291 | <= BCC(smb_buffer_response)) { |
2019 | ses->serverOS = cifs_kcalloc(len + 1, GFP_KERNEL); | 2292 | ses->serverOS = kcalloc(1, len + 1, GFP_KERNEL); |
2020 | strncpy(ses->serverOS, bcc_ptr, len); | 2293 | strncpy(ses->serverOS, bcc_ptr, len); |
2021 | 2294 | ||
2022 | bcc_ptr += len; | 2295 | bcc_ptr += len; |
@@ -2024,14 +2297,14 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2024 | bcc_ptr++; | 2297 | bcc_ptr++; |
2025 | 2298 | ||
2026 | len = strnlen(bcc_ptr, 1024); | 2299 | len = strnlen(bcc_ptr, 1024); |
2027 | ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL); | 2300 | ses->serverNOS = kcalloc(1, len + 1,GFP_KERNEL); |
2028 | strncpy(ses->serverNOS, bcc_ptr, len); | 2301 | strncpy(ses->serverNOS, bcc_ptr, len); |
2029 | bcc_ptr += len; | 2302 | bcc_ptr += len; |
2030 | bcc_ptr[0] = 0; | 2303 | bcc_ptr[0] = 0; |
2031 | bcc_ptr++; | 2304 | bcc_ptr++; |
2032 | 2305 | ||
2033 | len = strnlen(bcc_ptr, 1024); | 2306 | len = strnlen(bcc_ptr, 1024); |
2034 | ses->serverDomain = cifs_kcalloc(len + 1, GFP_KERNEL); | 2307 | ses->serverDomain = kcalloc(1, len + 1, GFP_KERNEL); |
2035 | strncpy(ses->serverDomain, bcc_ptr, len); | 2308 | strncpy(ses->serverDomain, bcc_ptr, len); |
2036 | bcc_ptr += len; | 2309 | bcc_ptr += len; |
2037 | bcc_ptr[0] = 0; | 2310 | bcc_ptr[0] = 0; |
@@ -2281,7 +2554,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2281 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 2554 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
2282 | terminating last Unicode string in response */ | 2555 | terminating last Unicode string in response */ |
2283 | ses->serverOS = | 2556 | ses->serverOS = |
2284 | cifs_kcalloc(2 * (len + 1), GFP_KERNEL); | 2557 | kcalloc(1, 2 * (len + 1), GFP_KERNEL); |
2285 | cifs_strfromUCS_le(ses->serverOS, | 2558 | cifs_strfromUCS_le(ses->serverOS, |
2286 | (wchar_t *) | 2559 | (wchar_t *) |
2287 | bcc_ptr, len, | 2560 | bcc_ptr, len, |
@@ -2296,7 +2569,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2296 | remaining_words | 2569 | remaining_words |
2297 | - 1); | 2570 | - 1); |
2298 | ses->serverNOS = | 2571 | ses->serverNOS = |
2299 | cifs_kcalloc(2 * (len + 1), | 2572 | kcalloc(1, 2 * (len + 1), |
2300 | GFP_KERNEL); | 2573 | GFP_KERNEL); |
2301 | cifs_strfromUCS_le(ses-> | 2574 | cifs_strfromUCS_le(ses-> |
2302 | serverNOS, | 2575 | serverNOS, |
@@ -2313,7 +2586,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2313 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 2586 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
2314 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ | 2587 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ |
2315 | ses->serverDomain = | 2588 | ses->serverDomain = |
2316 | cifs_kcalloc(2 * | 2589 | kcalloc(1, 2 * |
2317 | (len + | 2590 | (len + |
2318 | 1), | 2591 | 1), |
2319 | GFP_KERNEL); | 2592 | GFP_KERNEL); |
@@ -2339,13 +2612,13 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2339 | } /* else no more room so create dummy domain string */ | 2612 | } /* else no more room so create dummy domain string */ |
2340 | else | 2613 | else |
2341 | ses->serverDomain = | 2614 | ses->serverDomain = |
2342 | cifs_kcalloc(2, | 2615 | kcalloc(1, 2, |
2343 | GFP_KERNEL); | 2616 | GFP_KERNEL); |
2344 | } else { /* no room so create dummy domain and NOS string */ | 2617 | } else { /* no room so create dummy domain and NOS string */ |
2345 | ses->serverDomain = | 2618 | ses->serverDomain = |
2346 | cifs_kcalloc(2, GFP_KERNEL); | 2619 | kcalloc(1, 2, GFP_KERNEL); |
2347 | ses->serverNOS = | 2620 | ses->serverNOS = |
2348 | cifs_kcalloc(2, GFP_KERNEL); | 2621 | kcalloc(1, 2, GFP_KERNEL); |
2349 | } | 2622 | } |
2350 | } else { /* ASCII */ | 2623 | } else { /* ASCII */ |
2351 | len = strnlen(bcc_ptr, 1024); | 2624 | len = strnlen(bcc_ptr, 1024); |
@@ -2353,7 +2626,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2353 | pByteArea(smb_buffer_response) | 2626 | pByteArea(smb_buffer_response) |
2354 | <= BCC(smb_buffer_response)) { | 2627 | <= BCC(smb_buffer_response)) { |
2355 | ses->serverOS = | 2628 | ses->serverOS = |
2356 | cifs_kcalloc(len + 1, | 2629 | kcalloc(1, len + 1, |
2357 | GFP_KERNEL); | 2630 | GFP_KERNEL); |
2358 | strncpy(ses->serverOS, | 2631 | strncpy(ses->serverOS, |
2359 | bcc_ptr, len); | 2632 | bcc_ptr, len); |
@@ -2364,7 +2637,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2364 | 2637 | ||
2365 | len = strnlen(bcc_ptr, 1024); | 2638 | len = strnlen(bcc_ptr, 1024); |
2366 | ses->serverNOS = | 2639 | ses->serverNOS = |
2367 | cifs_kcalloc(len + 1, | 2640 | kcalloc(1, len + 1, |
2368 | GFP_KERNEL); | 2641 | GFP_KERNEL); |
2369 | strncpy(ses->serverNOS, bcc_ptr, len); | 2642 | strncpy(ses->serverNOS, bcc_ptr, len); |
2370 | bcc_ptr += len; | 2643 | bcc_ptr += len; |
@@ -2373,7 +2646,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2373 | 2646 | ||
2374 | len = strnlen(bcc_ptr, 1024); | 2647 | len = strnlen(bcc_ptr, 1024); |
2375 | ses->serverDomain = | 2648 | ses->serverDomain = |
2376 | cifs_kcalloc(len + 1, | 2649 | kcalloc(1, len + 1, |
2377 | GFP_KERNEL); | 2650 | GFP_KERNEL); |
2378 | strncpy(ses->serverDomain, bcc_ptr, len); | 2651 | strncpy(ses->serverDomain, bcc_ptr, len); |
2379 | bcc_ptr += len; | 2652 | bcc_ptr += len; |
@@ -2675,7 +2948,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2675 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 2948 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
2676 | terminating last Unicode string in response */ | 2949 | terminating last Unicode string in response */ |
2677 | ses->serverOS = | 2950 | ses->serverOS = |
2678 | cifs_kcalloc(2 * (len + 1), GFP_KERNEL); | 2951 | kcalloc(1, 2 * (len + 1), GFP_KERNEL); |
2679 | cifs_strfromUCS_le(ses->serverOS, | 2952 | cifs_strfromUCS_le(ses->serverOS, |
2680 | (wchar_t *) | 2953 | (wchar_t *) |
2681 | bcc_ptr, len, | 2954 | bcc_ptr, len, |
@@ -2690,7 +2963,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2690 | remaining_words | 2963 | remaining_words |
2691 | - 1); | 2964 | - 1); |
2692 | ses->serverNOS = | 2965 | ses->serverNOS = |
2693 | cifs_kcalloc(2 * (len + 1), | 2966 | kcalloc(1, 2 * (len + 1), |
2694 | GFP_KERNEL); | 2967 | GFP_KERNEL); |
2695 | cifs_strfromUCS_le(ses-> | 2968 | cifs_strfromUCS_le(ses-> |
2696 | serverNOS, | 2969 | serverNOS, |
@@ -2706,7 +2979,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2706 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 2979 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
2707 | /* last string not always null terminated (e.g. for Windows XP & 2000) */ | 2980 | /* last string not always null terminated (e.g. for Windows XP & 2000) */ |
2708 | ses->serverDomain = | 2981 | ses->serverDomain = |
2709 | cifs_kcalloc(2 * | 2982 | kcalloc(1, 2 * |
2710 | (len + | 2983 | (len + |
2711 | 1), | 2984 | 1), |
2712 | GFP_KERNEL); | 2985 | GFP_KERNEL); |
@@ -2731,17 +3004,17 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2731 | = 0; | 3004 | = 0; |
2732 | } /* else no more room so create dummy domain string */ | 3005 | } /* else no more room so create dummy domain string */ |
2733 | else | 3006 | else |
2734 | ses->serverDomain = cifs_kcalloc(2,GFP_KERNEL); | 3007 | ses->serverDomain = kcalloc(1, 2,GFP_KERNEL); |
2735 | } else { /* no room so create dummy domain and NOS string */ | 3008 | } else { /* no room so create dummy domain and NOS string */ |
2736 | ses->serverDomain = cifs_kcalloc(2, GFP_KERNEL); | 3009 | ses->serverDomain = kcalloc(1, 2, GFP_KERNEL); |
2737 | ses->serverNOS = cifs_kcalloc(2, GFP_KERNEL); | 3010 | ses->serverNOS = kcalloc(1, 2, GFP_KERNEL); |
2738 | } | 3011 | } |
2739 | } else { /* ASCII */ | 3012 | } else { /* ASCII */ |
2740 | len = strnlen(bcc_ptr, 1024); | 3013 | len = strnlen(bcc_ptr, 1024); |
2741 | if (((long) bcc_ptr + len) - | 3014 | if (((long) bcc_ptr + len) - |
2742 | (long) pByteArea(smb_buffer_response) | 3015 | (long) pByteArea(smb_buffer_response) |
2743 | <= BCC(smb_buffer_response)) { | 3016 | <= BCC(smb_buffer_response)) { |
2744 | ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL); | 3017 | ses->serverOS = kcalloc(1, len + 1,GFP_KERNEL); |
2745 | strncpy(ses->serverOS,bcc_ptr, len); | 3018 | strncpy(ses->serverOS,bcc_ptr, len); |
2746 | 3019 | ||
2747 | bcc_ptr += len; | 3020 | bcc_ptr += len; |
@@ -2749,14 +3022,14 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2749 | bcc_ptr++; | 3022 | bcc_ptr++; |
2750 | 3023 | ||
2751 | len = strnlen(bcc_ptr, 1024); | 3024 | len = strnlen(bcc_ptr, 1024); |
2752 | ses->serverNOS = cifs_kcalloc(len+1,GFP_KERNEL); | 3025 | ses->serverNOS = kcalloc(1, len+1,GFP_KERNEL); |
2753 | strncpy(ses->serverNOS, bcc_ptr, len); | 3026 | strncpy(ses->serverNOS, bcc_ptr, len); |
2754 | bcc_ptr += len; | 3027 | bcc_ptr += len; |
2755 | bcc_ptr[0] = 0; | 3028 | bcc_ptr[0] = 0; |
2756 | bcc_ptr++; | 3029 | bcc_ptr++; |
2757 | 3030 | ||
2758 | len = strnlen(bcc_ptr, 1024); | 3031 | len = strnlen(bcc_ptr, 1024); |
2759 | ses->serverDomain = cifs_kcalloc(len+1,GFP_KERNEL); | 3032 | ses->serverDomain = kcalloc(1, len+1,GFP_KERNEL); |
2760 | strncpy(ses->serverDomain, bcc_ptr, len); | 3033 | strncpy(ses->serverDomain, bcc_ptr, len); |
2761 | bcc_ptr += len; | 3034 | bcc_ptr += len; |
2762 | bcc_ptr[0] = 0; | 3035 | bcc_ptr[0] = 0; |
@@ -2868,7 +3141,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
2868 | if(tcon->nativeFileSystem) | 3141 | if(tcon->nativeFileSystem) |
2869 | kfree(tcon->nativeFileSystem); | 3142 | kfree(tcon->nativeFileSystem); |
2870 | tcon->nativeFileSystem = | 3143 | tcon->nativeFileSystem = |
2871 | cifs_kcalloc(length + 2, GFP_KERNEL); | 3144 | kcalloc(1, length + 2, GFP_KERNEL); |
2872 | cifs_strfromUCS_le(tcon->nativeFileSystem, | 3145 | cifs_strfromUCS_le(tcon->nativeFileSystem, |
2873 | (wchar_t *) bcc_ptr, | 3146 | (wchar_t *) bcc_ptr, |
2874 | length, nls_codepage); | 3147 | length, nls_codepage); |
@@ -2886,7 +3159,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
2886 | if(tcon->nativeFileSystem) | 3159 | if(tcon->nativeFileSystem) |
2887 | kfree(tcon->nativeFileSystem); | 3160 | kfree(tcon->nativeFileSystem); |
2888 | tcon->nativeFileSystem = | 3161 | tcon->nativeFileSystem = |
2889 | cifs_kcalloc(length + 1, GFP_KERNEL); | 3162 | kcalloc(1, length + 1, GFP_KERNEL); |
2890 | strncpy(tcon->nativeFileSystem, bcc_ptr, | 3163 | strncpy(tcon->nativeFileSystem, bcc_ptr, |
2891 | length); | 3164 | length); |
2892 | } | 3165 | } |
@@ -2959,6 +3232,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
2959 | int rc = 0; | 3232 | int rc = 0; |
2960 | char ntlm_session_key[CIFS_SESSION_KEY_SIZE]; | 3233 | char ntlm_session_key[CIFS_SESSION_KEY_SIZE]; |
2961 | int ntlmv2_flag = FALSE; | 3234 | int ntlmv2_flag = FALSE; |
3235 | int first_time = 0; | ||
2962 | 3236 | ||
2963 | /* what if server changes its buffer size after dropping the session? */ | 3237 | /* what if server changes its buffer size after dropping the session? */ |
2964 | if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ { | 3238 | if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ { |
@@ -2977,12 +3251,13 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
2977 | spin_unlock(&GlobalMid_Lock); | 3251 | spin_unlock(&GlobalMid_Lock); |
2978 | 3252 | ||
2979 | } | 3253 | } |
3254 | first_time = 1; | ||
2980 | } | 3255 | } |
2981 | if (!rc) { | 3256 | if (!rc) { |
2982 | pSesInfo->capabilities = pSesInfo->server->capabilities; | 3257 | pSesInfo->capabilities = pSesInfo->server->capabilities; |
2983 | if(linuxExtEnabled == 0) | 3258 | if(linuxExtEnabled == 0) |
2984 | pSesInfo->capabilities &= (~CAP_UNIX); | 3259 | pSesInfo->capabilities &= (~CAP_UNIX); |
2985 | pSesInfo->sequence_number = 0; | 3260 | /* pSesInfo->sequence_number = 0;*/ |
2986 | cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d", | 3261 | cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d", |
2987 | pSesInfo->server->secMode, | 3262 | pSesInfo->server->secMode, |
2988 | pSesInfo->server->capabilities, | 3263 | pSesInfo->server->capabilities, |
@@ -3015,7 +3290,10 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3015 | v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); | 3290 | v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); |
3016 | if(v2_response) { | 3291 | if(v2_response) { |
3017 | CalcNTLMv2_response(pSesInfo,v2_response); | 3292 | CalcNTLMv2_response(pSesInfo,v2_response); |
3018 | /* cifs_calculate_ntlmv2_mac_key(pSesInfo->mac_signing_key, response, ntlm_session_key, */ | 3293 | /* if(first_time) |
3294 | cifs_calculate_ntlmv2_mac_key( | ||
3295 | pSesInfo->server->mac_signing_key, | ||
3296 | response, ntlm_session_key, */ | ||
3019 | kfree(v2_response); | 3297 | kfree(v2_response); |
3020 | /* BB Put dummy sig in SessSetup PDU? */ | 3298 | /* BB Put dummy sig in SessSetup PDU? */ |
3021 | } else { | 3299 | } else { |
@@ -3028,9 +3306,11 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3028 | pSesInfo->server->cryptKey, | 3306 | pSesInfo->server->cryptKey, |
3029 | ntlm_session_key); | 3307 | ntlm_session_key); |
3030 | 3308 | ||
3031 | cifs_calculate_mac_key(pSesInfo->mac_signing_key, | 3309 | if(first_time) |
3032 | ntlm_session_key, | 3310 | cifs_calculate_mac_key( |
3033 | pSesInfo->password); | 3311 | pSesInfo->server->mac_signing_key, |
3312 | ntlm_session_key, | ||
3313 | pSesInfo->password); | ||
3034 | } | 3314 | } |
3035 | /* for better security the weaker lanman hash not sent | 3315 | /* for better security the weaker lanman hash not sent |
3036 | in AuthSessSetup so we no longer calculate it */ | 3316 | in AuthSessSetup so we no longer calculate it */ |
@@ -3046,8 +3326,11 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3046 | pSesInfo->server->cryptKey, | 3326 | pSesInfo->server->cryptKey, |
3047 | ntlm_session_key); | 3327 | ntlm_session_key); |
3048 | 3328 | ||
3049 | cifs_calculate_mac_key(pSesInfo->mac_signing_key, | 3329 | if(first_time) |
3050 | ntlm_session_key, pSesInfo->password); | 3330 | cifs_calculate_mac_key( |
3331 | pSesInfo->server->mac_signing_key, | ||
3332 | ntlm_session_key, pSesInfo->password); | ||
3333 | |||
3051 | rc = CIFSSessSetup(xid, pSesInfo, | 3334 | rc = CIFSSessSetup(xid, pSesInfo, |
3052 | ntlm_session_key, nls_info); | 3335 | ntlm_session_key, nls_info); |
3053 | } | 3336 | } |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index f54e1866f0f4..e3137aa48cdd 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -101,68 +101,15 @@ cifs_bp_rename_retry: | |||
101 | return full_path; | 101 | return full_path; |
102 | } | 102 | } |
103 | 103 | ||
104 | /* Note: caller must free return buffer */ | 104 | /* char * build_wildcard_path_from_dentry(struct dentry *direntry) |
105 | char * | ||
106 | build_wildcard_path_from_dentry(struct dentry *direntry) | ||
107 | { | 105 | { |
108 | struct dentry *temp; | ||
109 | int namelen = 0; | ||
110 | char *full_path; | ||
111 | |||
112 | if(direntry == NULL) | ||
113 | return NULL; /* not much we can do if dentry is freed and | ||
114 | we need to reopen the file after it was closed implicitly | ||
115 | when the server crashed */ | ||
116 | |||
117 | cifs_bwp_rename_retry: | ||
118 | for (temp = direntry; !IS_ROOT(temp);) { | ||
119 | namelen += (1 + temp->d_name.len); | ||
120 | temp = temp->d_parent; | ||
121 | if(temp == NULL) { | ||
122 | cERROR(1,("corrupt dentry")); | ||
123 | return NULL; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | full_path = kmalloc(namelen+3, GFP_KERNEL); | ||
128 | if(full_path == NULL) | 106 | if(full_path == NULL) |
129 | return full_path; | 107 | return full_path; |
130 | 108 | ||
131 | full_path[namelen] = '\\'; | 109 | full_path[namelen] = '\\'; |
132 | full_path[namelen+1] = '*'; | 110 | full_path[namelen+1] = '*'; |
133 | full_path[namelen+2] = 0; /* trailing null */ | 111 | full_path[namelen+2] = 0; |
134 | 112 | BB remove above eight lines BB */ | |
135 | for (temp = direntry; !IS_ROOT(temp);) { | ||
136 | namelen -= 1 + temp->d_name.len; | ||
137 | if (namelen < 0) { | ||
138 | break; | ||
139 | } else { | ||
140 | full_path[namelen] = '\\'; | ||
141 | strncpy(full_path + namelen + 1, temp->d_name.name, | ||
142 | temp->d_name.len); | ||
143 | cFYI(0, (" name: %s ", full_path + namelen)); | ||
144 | } | ||
145 | temp = temp->d_parent; | ||
146 | if(temp == NULL) { | ||
147 | cERROR(1,("corrupt dentry")); | ||
148 | kfree(full_path); | ||
149 | return NULL; | ||
150 | } | ||
151 | } | ||
152 | if (namelen != 0) { | ||
153 | cERROR(1, | ||
154 | ("We did not end path lookup where we expected namelen is %d", | ||
155 | namelen)); | ||
156 | /* presumably this is only possible if we were racing with a rename | ||
157 | of one of the parent directories (we can not lock the dentries | ||
158 | above us to prevent this, but retrying should be harmless) */ | ||
159 | kfree(full_path); | ||
160 | namelen = 0; | ||
161 | goto cifs_bwp_rename_retry; | ||
162 | } | ||
163 | |||
164 | return full_path; | ||
165 | } | ||
166 | 113 | ||
167 | /* Inode operations in similar order to how they appear in the Linux file fs.h */ | 114 | /* Inode operations in similar order to how they appear in the Linux file fs.h */ |
168 | 115 | ||
@@ -235,7 +182,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
235 | 182 | ||
236 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | 183 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, |
237 | desiredAccess, CREATE_NOT_DIR, | 184 | desiredAccess, CREATE_NOT_DIR, |
238 | &fileHandle, &oplock, buf, cifs_sb->local_nls); | 185 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
186 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
239 | if (rc) { | 187 | if (rc) { |
240 | cFYI(1, ("cifs_create returned 0x%x ", rc)); | 188 | cFYI(1, ("cifs_create returned 0x%x ", rc)); |
241 | } else { | 189 | } else { |
@@ -248,13 +196,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
248 | (__u64)current->euid, | 196 | (__u64)current->euid, |
249 | (__u64)current->egid, | 197 | (__u64)current->egid, |
250 | 0 /* dev */, | 198 | 0 /* dev */, |
251 | cifs_sb->local_nls); | 199 | cifs_sb->local_nls, |
200 | cifs_sb->mnt_cifs_flags & | ||
201 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
252 | } else { | 202 | } else { |
253 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 203 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, |
254 | (__u64)-1, | 204 | (__u64)-1, |
255 | (__u64)-1, | 205 | (__u64)-1, |
256 | 0 /* dev */, | 206 | 0 /* dev */, |
257 | cifs_sb->local_nls); | 207 | cifs_sb->local_nls, |
208 | cifs_sb->mnt_cifs_flags & | ||
209 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
258 | } | 210 | } |
259 | else { | 211 | else { |
260 | /* BB implement via Windows security descriptors */ | 212 | /* BB implement via Windows security descriptors */ |
@@ -284,51 +236,48 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
284 | /* mknod case - do not leave file open */ | 236 | /* mknod case - do not leave file open */ |
285 | CIFSSMBClose(xid, pTcon, fileHandle); | 237 | CIFSSMBClose(xid, pTcon, fileHandle); |
286 | } else if(newinode) { | 238 | } else if(newinode) { |
287 | pCifsFile = (struct cifsFileInfo *) | 239 | pCifsFile = |
288 | kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); | 240 | kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); |
289 | 241 | ||
290 | if (pCifsFile) { | 242 | if(pCifsFile == NULL) |
291 | memset((char *)pCifsFile, 0, | 243 | goto cifs_create_out; |
292 | sizeof (struct cifsFileInfo)); | 244 | memset((char *)pCifsFile, 0, |
293 | pCifsFile->netfid = fileHandle; | 245 | sizeof (struct cifsFileInfo)); |
294 | pCifsFile->pid = current->tgid; | 246 | pCifsFile->netfid = fileHandle; |
295 | pCifsFile->pInode = newinode; | 247 | pCifsFile->pid = current->tgid; |
296 | pCifsFile->invalidHandle = FALSE; | 248 | pCifsFile->pInode = newinode; |
297 | pCifsFile->closePend = FALSE; | 249 | pCifsFile->invalidHandle = FALSE; |
298 | init_MUTEX(&pCifsFile->fh_sem); | 250 | pCifsFile->closePend = FALSE; |
299 | /* put the following in at open now */ | 251 | init_MUTEX(&pCifsFile->fh_sem); |
300 | /* pCifsFile->pfile = file; */ | 252 | /* set the following in open now |
301 | write_lock(&GlobalSMBSeslock); | 253 | pCifsFile->pfile = file; */ |
302 | list_add(&pCifsFile->tlist,&pTcon->openFileList); | 254 | write_lock(&GlobalSMBSeslock); |
303 | pCifsInode = CIFS_I(newinode); | 255 | list_add(&pCifsFile->tlist,&pTcon->openFileList); |
304 | if(pCifsInode) { | 256 | pCifsInode = CIFS_I(newinode); |
257 | if(pCifsInode) { | ||
305 | /* if readable file instance put first in list*/ | 258 | /* if readable file instance put first in list*/ |
306 | if (write_only == TRUE) { | 259 | if (write_only == TRUE) { |
307 | list_add_tail(&pCifsFile->flist, | 260 | list_add_tail(&pCifsFile->flist, |
308 | &pCifsInode->openFileList); | 261 | &pCifsInode->openFileList); |
309 | } else { | 262 | } else { |
310 | list_add(&pCifsFile->flist, | 263 | list_add(&pCifsFile->flist, |
311 | &pCifsInode->openFileList); | 264 | &pCifsInode->openFileList); |
312 | } | ||
313 | if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | ||
314 | pCifsInode->clientCanCacheAll = TRUE; | ||
315 | pCifsInode->clientCanCacheRead = TRUE; | ||
316 | cFYI(1,("Exclusive Oplock granted on inode %p", | ||
317 | newinode)); | ||
318 | } else if((oplock & 0xF) == OPLOCK_READ) | ||
319 | pCifsInode->clientCanCacheRead = TRUE; | ||
320 | } | 265 | } |
321 | write_unlock(&GlobalSMBSeslock); | 266 | if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
267 | pCifsInode->clientCanCacheAll = TRUE; | ||
268 | pCifsInode->clientCanCacheRead = TRUE; | ||
269 | cFYI(1,("Exclusive Oplock for inode %p", | ||
270 | newinode)); | ||
271 | } else if((oplock & 0xF) == OPLOCK_READ) | ||
272 | pCifsInode->clientCanCacheRead = TRUE; | ||
322 | } | 273 | } |
274 | write_unlock(&GlobalSMBSeslock); | ||
323 | } | 275 | } |
324 | } | 276 | } |
325 | 277 | cifs_create_out: | |
326 | if (buf) | 278 | kfree(buf); |
327 | kfree(buf); | 279 | kfree(full_path); |
328 | if (full_path) | ||
329 | kfree(full_path); | ||
330 | FreeXid(xid); | 280 | FreeXid(xid); |
331 | |||
332 | return rc; | 281 | return rc; |
333 | } | 282 | } |
334 | 283 | ||
@@ -359,11 +308,15 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev | |||
359 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 308 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
360 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 309 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
361 | mode,(__u64)current->euid,(__u64)current->egid, | 310 | mode,(__u64)current->euid,(__u64)current->egid, |
362 | device_number, cifs_sb->local_nls); | 311 | device_number, cifs_sb->local_nls, |
312 | cifs_sb->mnt_cifs_flags & | ||
313 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
363 | } else { | 314 | } else { |
364 | rc = CIFSSMBUnixSetPerms(xid, pTcon, | 315 | rc = CIFSSMBUnixSetPerms(xid, pTcon, |
365 | full_path, mode, (__u64)-1, (__u64)-1, | 316 | full_path, mode, (__u64)-1, (__u64)-1, |
366 | device_number, cifs_sb->local_nls); | 317 | device_number, cifs_sb->local_nls, |
318 | cifs_sb->mnt_cifs_flags & | ||
319 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
367 | } | 320 | } |
368 | 321 | ||
369 | if(!rc) { | 322 | if(!rc) { |
@@ -375,10 +328,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev | |||
375 | } | 328 | } |
376 | } | 329 | } |
377 | 330 | ||
378 | if (full_path) | 331 | kfree(full_path); |
379 | kfree(full_path); | ||
380 | FreeXid(xid); | 332 | FreeXid(xid); |
381 | |||
382 | return rc; | 333 | return rc; |
383 | } | 334 | } |
384 | 335 | ||
@@ -447,43 +398,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
447 | if file exists or not but no access BB */ | 398 | if file exists or not but no access BB */ |
448 | } | 399 | } |
449 | 400 | ||
450 | if (full_path) | 401 | kfree(full_path); |
451 | kfree(full_path); | ||
452 | FreeXid(xid); | 402 | FreeXid(xid); |
453 | return ERR_PTR(rc); | 403 | return ERR_PTR(rc); |
454 | } | 404 | } |
455 | 405 | ||
456 | int | ||
457 | cifs_dir_open(struct inode *inode, struct file *file) | ||
458 | { /* NB: currently unused since searches are opened in readdir */ | ||
459 | int rc = 0; | ||
460 | int xid; | ||
461 | struct cifs_sb_info *cifs_sb; | ||
462 | struct cifsTconInfo *pTcon; | ||
463 | char *full_path = NULL; | ||
464 | |||
465 | xid = GetXid(); | ||
466 | |||
467 | cifs_sb = CIFS_SB(inode->i_sb); | ||
468 | pTcon = cifs_sb->tcon; | ||
469 | |||
470 | if(file->f_dentry) { | ||
471 | down(&file->f_dentry->d_sb->s_vfs_rename_sem); | ||
472 | full_path = build_wildcard_path_from_dentry(file->f_dentry); | ||
473 | up(&file->f_dentry->d_sb->s_vfs_rename_sem); | ||
474 | } else { | ||
475 | FreeXid(xid); | ||
476 | return -EIO; | ||
477 | } | ||
478 | |||
479 | cFYI(1, ("inode = 0x%p and full path is %s", inode, full_path)); | ||
480 | |||
481 | if (full_path) | ||
482 | kfree(full_path); | ||
483 | FreeXid(xid); | ||
484 | return rc; | ||
485 | } | ||
486 | |||
487 | static int | 406 | static int |
488 | cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | 407 | cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) |
489 | { | 408 | { |
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index 9d24c40f1967..7d2a9202c39a 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c | |||
@@ -92,7 +92,8 @@ int cifs_dir_notify(struct file * file, unsigned long arg) | |||
92 | cERROR(1,("cifs dir notify on file %s with arg 0x%lx",full_path,arg)); /* BB removeme BB */ | 92 | cERROR(1,("cifs dir notify on file %s with arg 0x%lx",full_path,arg)); /* BB removeme BB */ |
93 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, | 93 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, |
94 | GENERIC_READ | SYNCHRONIZE, 0 /* create options */, | 94 | GENERIC_READ | SYNCHRONIZE, 0 /* create options */, |
95 | &netfid, &oplock,NULL, cifs_sb->local_nls); | 95 | &netfid, &oplock,NULL, cifs_sb->local_nls, |
96 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
96 | /* BB fixme - add this handle to a notify handle list */ | 97 | /* BB fixme - add this handle to a notify handle list */ |
97 | if(rc) { | 98 | if(rc) { |
98 | cERROR(1,("Could not open directory for notify")); /* BB remove BB */ | 99 | cERROR(1,("Could not open directory for notify")); /* BB remove BB */ |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index dcab7cf1b53b..dde2d251fc3d 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -254,7 +254,8 @@ int cifs_open(struct inode *inode, struct file *file) | |||
254 | } | 254 | } |
255 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, | 255 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, |
256 | CREATE_NOT_DIR, &netfid, &oplock, buf, | 256 | CREATE_NOT_DIR, &netfid, &oplock, buf, |
257 | cifs_sb->local_nls); | 257 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags |
258 | & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
258 | if (rc) { | 259 | if (rc) { |
259 | cFYI(1, ("cifs_open returned 0x%x ", rc)); | 260 | cFYI(1, ("cifs_open returned 0x%x ", rc)); |
260 | goto out; | 261 | goto out; |
@@ -287,7 +288,9 @@ int cifs_open(struct inode *inode, struct file *file) | |||
287 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 288 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
288 | inode->i_mode, | 289 | inode->i_mode, |
289 | (__u64)-1, (__u64)-1, 0 /* dev */, | 290 | (__u64)-1, (__u64)-1, 0 /* dev */, |
290 | cifs_sb->local_nls); | 291 | cifs_sb->local_nls, |
292 | cifs_sb->mnt_cifs_flags & | ||
293 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
291 | } else { | 294 | } else { |
292 | /* BB implement via Windows security descriptors eg | 295 | /* BB implement via Windows security descriptors eg |
293 | CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, | 296 | CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, |
@@ -387,7 +390,8 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
387 | } */ | 390 | } */ |
388 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, | 391 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, |
389 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | 392 | CREATE_NOT_DIR, &netfid, &oplock, NULL, |
390 | cifs_sb->local_nls); | 393 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
394 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
391 | if (rc) { | 395 | if (rc) { |
392 | up(&pCifsFile->fh_sem); | 396 | up(&pCifsFile->fh_sem); |
393 | cFYI(1, ("cifs_open returned 0x%x ", rc)); | 397 | cFYI(1, ("cifs_open returned 0x%x ", rc)); |
@@ -465,8 +469,10 @@ int cifs_close(struct inode *inode, struct file *file) | |||
465 | write_lock(&file->f_owner.lock); | 469 | write_lock(&file->f_owner.lock); |
466 | } | 470 | } |
467 | } | 471 | } |
472 | write_lock(&GlobalSMBSeslock); | ||
468 | list_del(&pSMBFile->flist); | 473 | list_del(&pSMBFile->flist); |
469 | list_del(&pSMBFile->tlist); | 474 | list_del(&pSMBFile->tlist); |
475 | write_unlock(&GlobalSMBSeslock); | ||
470 | write_unlock(&file->f_owner.lock); | 476 | write_unlock(&file->f_owner.lock); |
471 | kfree(pSMBFile->search_resume_name); | 477 | kfree(pSMBFile->search_resume_name); |
472 | kfree(file->private_data); | 478 | kfree(file->private_data); |
@@ -506,7 +512,8 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
506 | pTcon = cifs_sb->tcon; | 512 | pTcon = cifs_sb->tcon; |
507 | 513 | ||
508 | cFYI(1, ("Freeing private data in close dir")); | 514 | cFYI(1, ("Freeing private data in close dir")); |
509 | if (pCFileStruct->srch_inf.endOfSearch == FALSE) { | 515 | if ((pCFileStruct->srch_inf.endOfSearch == FALSE) && |
516 | (pCFileStruct->invalidHandle == FALSE)) { | ||
510 | pCFileStruct->invalidHandle = TRUE; | 517 | pCFileStruct->invalidHandle = TRUE; |
511 | rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); | 518 | rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); |
512 | cFYI(1, ("Closing uncompleted readdir with rc %d", | 519 | cFYI(1, ("Closing uncompleted readdir with rc %d", |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index d73b0aa86775..670947288262 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -44,7 +44,8 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
44 | cFYI(1, (" Getting info on %s ", search_path)); | 44 | cFYI(1, (" Getting info on %s ", search_path)); |
45 | /* could have done a find first instead but this returns more info */ | 45 | /* could have done a find first instead but this returns more info */ |
46 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, | 46 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, |
47 | cifs_sb->local_nls); | 47 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
48 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
48 | /* dump_mem("\nUnixQPathInfo return data", &findData, | 49 | /* dump_mem("\nUnixQPathInfo return data", &findData, |
49 | sizeof(findData)); */ | 50 | sizeof(findData)); */ |
50 | if (rc) { | 51 | if (rc) { |
@@ -63,7 +64,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
63 | strncat(tmp_path, search_path, MAX_PATHCONF); | 64 | strncat(tmp_path, search_path, MAX_PATHCONF); |
64 | rc = connect_to_dfs_path(xid, pTcon->ses, | 65 | rc = connect_to_dfs_path(xid, pTcon->ses, |
65 | /* treename + */ tmp_path, | 66 | /* treename + */ tmp_path, |
66 | cifs_sb->local_nls); | 67 | cifs_sb->local_nls, |
68 | cifs_sb->mnt_cifs_flags & | ||
69 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
67 | kfree(tmp_path); | 70 | kfree(tmp_path); |
68 | 71 | ||
69 | /* BB fix up inode etc. */ | 72 | /* BB fix up inode etc. */ |
@@ -210,7 +213,8 @@ int cifs_get_inode_info(struct inode **pinode, | |||
210 | pfindData = (FILE_ALL_INFO *)buf; | 213 | pfindData = (FILE_ALL_INFO *)buf; |
211 | /* could do find first instead but this returns more info */ | 214 | /* could do find first instead but this returns more info */ |
212 | rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, | 215 | rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, |
213 | cifs_sb->local_nls); | 216 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
217 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
214 | } | 218 | } |
215 | /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ | 219 | /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ |
216 | if (rc) { | 220 | if (rc) { |
@@ -230,7 +234,9 @@ int cifs_get_inode_info(struct inode **pinode, | |||
230 | strncat(tmp_path, search_path, MAX_PATHCONF); | 234 | strncat(tmp_path, search_path, MAX_PATHCONF); |
231 | rc = connect_to_dfs_path(xid, pTcon->ses, | 235 | rc = connect_to_dfs_path(xid, pTcon->ses, |
232 | /* treename + */ tmp_path, | 236 | /* treename + */ tmp_path, |
233 | cifs_sb->local_nls); | 237 | cifs_sb->local_nls, |
238 | cifs_sb->mnt_cifs_flags & | ||
239 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
234 | kfree(tmp_path); | 240 | kfree(tmp_path); |
235 | /* BB fix up inode etc. */ | 241 | /* BB fix up inode etc. */ |
236 | } else if (rc) { | 242 | } else if (rc) { |
@@ -268,7 +274,9 @@ int cifs_get_inode_info(struct inode **pinode, | |||
268 | 274 | ||
269 | rc1 = CIFSGetSrvInodeNumber(xid, pTcon, | 275 | rc1 = CIFSGetSrvInodeNumber(xid, pTcon, |
270 | search_path, &inode_num, | 276 | search_path, &inode_num, |
271 | cifs_sb->local_nls); | 277 | cifs_sb->local_nls, |
278 | cifs_sb->mnt_cifs_flags & | ||
279 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
272 | if(rc1) { | 280 | if(rc1) { |
273 | cFYI(1,("GetSrvInodeNum rc %d", rc1)); | 281 | cFYI(1,("GetSrvInodeNum rc %d", rc1)); |
274 | /* BB EOPNOSUPP disable SERVER_INUM? */ | 282 | /* BB EOPNOSUPP disable SERVER_INUM? */ |
@@ -410,7 +418,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
410 | FreeXid(xid); | 418 | FreeXid(xid); |
411 | return -ENOMEM; | 419 | return -ENOMEM; |
412 | } | 420 | } |
413 | rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls); | 421 | rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls, |
422 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
414 | 423 | ||
415 | if (!rc) { | 424 | if (!rc) { |
416 | direntry->d_inode->i_nlink--; | 425 | direntry->d_inode->i_nlink--; |
@@ -422,10 +431,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
422 | 431 | ||
423 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, | 432 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, |
424 | CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, | 433 | CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, |
425 | &netfid, &oplock, NULL, cifs_sb->local_nls); | 434 | &netfid, &oplock, NULL, cifs_sb->local_nls, |
435 | cifs_sb->mnt_cifs_flags & | ||
436 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
426 | if (rc==0) { | 437 | if (rc==0) { |
427 | CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL, | 438 | CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL, |
428 | cifs_sb->local_nls); | 439 | cifs_sb->local_nls, |
440 | cifs_sb->mnt_cifs_flags & | ||
441 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
429 | CIFSSMBClose(xid, pTcon, netfid); | 442 | CIFSSMBClose(xid, pTcon, netfid); |
430 | direntry->d_inode->i_nlink--; | 443 | direntry->d_inode->i_nlink--; |
431 | } | 444 | } |
@@ -439,7 +452,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
439 | if (!(pTcon->ses->flags & CIFS_SES_NT4)) | 452 | if (!(pTcon->ses->flags & CIFS_SES_NT4)) |
440 | rc = CIFSSMBSetTimes(xid, pTcon, full_path, | 453 | rc = CIFSSMBSetTimes(xid, pTcon, full_path, |
441 | pinfo_buf, | 454 | pinfo_buf, |
442 | cifs_sb->local_nls); | 455 | cifs_sb->local_nls, |
456 | cifs_sb->mnt_cifs_flags & | ||
457 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
443 | else | 458 | else |
444 | rc = -EOPNOTSUPP; | 459 | rc = -EOPNOTSUPP; |
445 | 460 | ||
@@ -461,7 +476,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
461 | FILE_OPEN, SYNCHRONIZE | | 476 | FILE_OPEN, SYNCHRONIZE | |
462 | FILE_WRITE_ATTRIBUTES, 0, | 477 | FILE_WRITE_ATTRIBUTES, 0, |
463 | &netfid, &oplock, NULL, | 478 | &netfid, &oplock, NULL, |
464 | cifs_sb->local_nls); | 479 | cifs_sb->local_nls, |
480 | cifs_sb->mnt_cifs_flags & | ||
481 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
465 | if (rc==0) { | 482 | if (rc==0) { |
466 | rc = CIFSSMBSetFileTimes(xid, pTcon, | 483 | rc = CIFSSMBSetFileTimes(xid, pTcon, |
467 | pinfo_buf, | 484 | pinfo_buf, |
@@ -472,8 +489,10 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
472 | kfree(pinfo_buf); | 489 | kfree(pinfo_buf); |
473 | } | 490 | } |
474 | if (rc==0) { | 491 | if (rc==0) { |
475 | rc = CIFSSMBDelFile(xid, pTcon, full_path, | 492 | rc = CIFSSMBDelFile(xid, pTcon, full_path, |
476 | cifs_sb->local_nls); | 493 | cifs_sb->local_nls, |
494 | cifs_sb->mnt_cifs_flags & | ||
495 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
477 | if (!rc) { | 496 | if (!rc) { |
478 | direntry->d_inode->i_nlink--; | 497 | direntry->d_inode->i_nlink--; |
479 | } else if (rc == -ETXTBSY) { | 498 | } else if (rc == -ETXTBSY) { |
@@ -485,11 +504,15 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
485 | CREATE_NOT_DIR | | 504 | CREATE_NOT_DIR | |
486 | CREATE_DELETE_ON_CLOSE, | 505 | CREATE_DELETE_ON_CLOSE, |
487 | &netfid, &oplock, NULL, | 506 | &netfid, &oplock, NULL, |
488 | cifs_sb->local_nls); | 507 | cifs_sb->local_nls, |
508 | cifs_sb->mnt_cifs_flags & | ||
509 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
489 | if (rc==0) { | 510 | if (rc==0) { |
490 | CIFSSMBRenameOpenFile(xid, pTcon, | 511 | CIFSSMBRenameOpenFile(xid, pTcon, |
491 | netfid, NULL, | 512 | netfid, NULL, |
492 | cifs_sb->local_nls); | 513 | cifs_sb->local_nls, |
514 | cifs_sb->mnt_cifs_flags & | ||
515 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
493 | CIFSSMBClose(xid, pTcon, netfid); | 516 | CIFSSMBClose(xid, pTcon, netfid); |
494 | direntry->d_inode->i_nlink--; | 517 | direntry->d_inode->i_nlink--; |
495 | } | 518 | } |
@@ -534,7 +557,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
534 | return -ENOMEM; | 557 | return -ENOMEM; |
535 | } | 558 | } |
536 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ | 559 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ |
537 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls); | 560 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, |
561 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
538 | if (rc) { | 562 | if (rc) { |
539 | cFYI(1, ("cifs_mkdir returned 0x%x ", rc)); | 563 | cFYI(1, ("cifs_mkdir returned 0x%x ", rc)); |
540 | d_drop(direntry); | 564 | d_drop(direntry); |
@@ -558,12 +582,16 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
558 | (__u64)current->euid, | 582 | (__u64)current->euid, |
559 | (__u64)current->egid, | 583 | (__u64)current->egid, |
560 | 0 /* dev_t */, | 584 | 0 /* dev_t */, |
561 | cifs_sb->local_nls); | 585 | cifs_sb->local_nls, |
586 | cifs_sb->mnt_cifs_flags & | ||
587 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
562 | } else { | 588 | } else { |
563 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 589 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
564 | mode, (__u64)-1, | 590 | mode, (__u64)-1, |
565 | (__u64)-1, 0 /* dev_t */, | 591 | (__u64)-1, 0 /* dev_t */, |
566 | cifs_sb->local_nls); | 592 | cifs_sb->local_nls, |
593 | cifs_sb->mnt_cifs_flags & | ||
594 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
567 | } | 595 | } |
568 | else { | 596 | else { |
569 | /* BB to be implemented via Windows secrty descriptors | 597 | /* BB to be implemented via Windows secrty descriptors |
@@ -600,7 +628,8 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
600 | return -ENOMEM; | 628 | return -ENOMEM; |
601 | } | 629 | } |
602 | 630 | ||
603 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls); | 631 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, |
632 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
604 | 633 | ||
605 | if (!rc) { | 634 | if (!rc) { |
606 | inode->i_nlink--; | 635 | inode->i_nlink--; |
@@ -653,7 +682,9 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, | |||
653 | } | 682 | } |
654 | 683 | ||
655 | rc = CIFSSMBRename(xid, pTcon, fromName, toName, | 684 | rc = CIFSSMBRename(xid, pTcon, fromName, toName, |
656 | cifs_sb_source->local_nls); | 685 | cifs_sb_source->local_nls, |
686 | cifs_sb_source->mnt_cifs_flags & | ||
687 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
657 | if (rc == -EEXIST) { | 688 | if (rc == -EEXIST) { |
658 | /* check if they are the same file because rename of hardlinked | 689 | /* check if they are the same file because rename of hardlinked |
659 | files is a noop */ | 690 | files is a noop */ |
@@ -665,11 +696,16 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, | |||
665 | if (info_buf_source != NULL) { | 696 | if (info_buf_source != NULL) { |
666 | info_buf_target = info_buf_source + 1; | 697 | info_buf_target = info_buf_source + 1; |
667 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, | 698 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, |
668 | info_buf_source, cifs_sb_source->local_nls); | 699 | info_buf_source, cifs_sb_source->local_nls, |
700 | cifs_sb_source->mnt_cifs_flags & | ||
701 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
669 | if (rc == 0) { | 702 | if (rc == 0) { |
670 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName, | 703 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName, |
671 | info_buf_target, | 704 | info_buf_target, |
672 | cifs_sb_target->local_nls); | 705 | cifs_sb_target->local_nls, |
706 | /* remap based on source sb */ | ||
707 | cifs_sb_source->mnt_cifs_flags & | ||
708 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
673 | } | 709 | } |
674 | if ((rc == 0) && | 710 | if ((rc == 0) && |
675 | (info_buf_source->UniqueId == | 711 | (info_buf_source->UniqueId == |
@@ -685,7 +721,9 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, | |||
685 | cifs_unlink(target_inode, target_direntry); | 721 | cifs_unlink(target_inode, target_direntry); |
686 | rc = CIFSSMBRename(xid, pTcon, fromName, | 722 | rc = CIFSSMBRename(xid, pTcon, fromName, |
687 | toName, | 723 | toName, |
688 | cifs_sb_source->local_nls); | 724 | cifs_sb_source->local_nls, |
725 | cifs_sb_source->mnt_cifs_flags | ||
726 | & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
689 | } | 727 | } |
690 | kfree(info_buf_source); | 728 | kfree(info_buf_source); |
691 | } /* if we can not get memory just leave rc as EEXIST */ | 729 | } /* if we can not get memory just leave rc as EEXIST */ |
@@ -705,10 +743,14 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, | |||
705 | might not right be right access to request */ | 743 | might not right be right access to request */ |
706 | rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ, | 744 | rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ, |
707 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | 745 | CREATE_NOT_DIR, &netfid, &oplock, NULL, |
708 | cifs_sb_source->local_nls); | 746 | cifs_sb_source->local_nls, |
747 | cifs_sb_source->mnt_cifs_flags & | ||
748 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
709 | if (rc==0) { | 749 | if (rc==0) { |
710 | CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, | 750 | CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, |
711 | cifs_sb_source->local_nls); | 751 | cifs_sb_source->local_nls, |
752 | cifs_sb_source->mnt_cifs_flags & | ||
753 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
712 | CIFSSMBClose(xid, pTcon, netfid); | 754 | CIFSSMBClose(xid, pTcon, netfid); |
713 | } | 755 | } |
714 | } | 756 | } |
@@ -962,7 +1004,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
962 | it by handle */ | 1004 | it by handle */ |
963 | rc = CIFSSMBSetEOF(xid, pTcon, full_path, | 1005 | rc = CIFSSMBSetEOF(xid, pTcon, full_path, |
964 | attrs->ia_size, FALSE, | 1006 | attrs->ia_size, FALSE, |
965 | cifs_sb->local_nls); | 1007 | cifs_sb->local_nls, |
1008 | cifs_sb->mnt_cifs_flags & | ||
1009 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
966 | cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc)); | 1010 | cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc)); |
967 | } | 1011 | } |
968 | 1012 | ||
@@ -999,7 +1043,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
999 | if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) | 1043 | if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) |
1000 | && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) | 1044 | && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) |
1001 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid, | 1045 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid, |
1002 | 0 /* dev_t */, cifs_sb->local_nls); | 1046 | 0 /* dev_t */, cifs_sb->local_nls, |
1047 | cifs_sb->mnt_cifs_flags & | ||
1048 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1003 | else if (attrs->ia_valid & ATTR_MODE) { | 1049 | else if (attrs->ia_valid & ATTR_MODE) { |
1004 | if ((mode & S_IWUGO) == 0) /* not writeable */ { | 1050 | if ((mode & S_IWUGO) == 0) /* not writeable */ { |
1005 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) | 1051 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) |
@@ -1048,7 +1094,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1048 | via Handle (SetFileInfo) instead of by path */ | 1094 | via Handle (SetFileInfo) instead of by path */ |
1049 | if (!(pTcon->ses->flags & CIFS_SES_NT4)) | 1095 | if (!(pTcon->ses->flags & CIFS_SES_NT4)) |
1050 | rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf, | 1096 | rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf, |
1051 | cifs_sb->local_nls); | 1097 | cifs_sb->local_nls, |
1098 | cifs_sb->mnt_cifs_flags & | ||
1099 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1052 | else | 1100 | else |
1053 | rc = -EOPNOTSUPP; | 1101 | rc = -EOPNOTSUPP; |
1054 | 1102 | ||
@@ -1063,7 +1111,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1063 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, | 1111 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, |
1064 | SYNCHRONIZE | FILE_WRITE_ATTRIBUTES, | 1112 | SYNCHRONIZE | FILE_WRITE_ATTRIBUTES, |
1065 | CREATE_NOT_DIR, &netfid, &oplock, | 1113 | CREATE_NOT_DIR, &netfid, &oplock, |
1066 | NULL, cifs_sb->local_nls); | 1114 | NULL, cifs_sb->local_nls, |
1115 | cifs_sb->mnt_cifs_flags & | ||
1116 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1067 | if (rc==0) { | 1117 | if (rc==0) { |
1068 | rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf, | 1118 | rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf, |
1069 | netfid); | 1119 | netfid); |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index b4b8e201d428..b0ea6687ab55 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -20,30 +20,93 @@ | |||
20 | * along with this library; if not, write to the Free Software | 20 | * along with this library; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | |||
23 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
24 | #include <linux/ext2_fs.h> | 25 | #include <linux/ext2_fs.h> |
25 | #include "cifspdu.h" | 26 | #include "cifspdu.h" |
26 | #include "cifsglob.h" | 27 | #include "cifsglob.h" |
27 | #include "cifsproto.h" | 28 | #include "cifsproto.h" |
28 | #include "cifs_debug.h" | 29 | #include "cifs_debug.h" |
30 | #include "cifsfs.h" | ||
31 | |||
32 | #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) | ||
29 | 33 | ||
30 | int cifs_ioctl (struct inode * inode, struct file * filep, | 34 | int cifs_ioctl (struct inode * inode, struct file * filep, |
31 | unsigned int command, unsigned long arg) | 35 | unsigned int command, unsigned long arg) |
32 | { | 36 | { |
33 | int rc = -ENOTTY; /* strange error - but the precedent */ | 37 | int rc = -ENOTTY; /* strange error - but the precedent */ |
38 | int xid; | ||
39 | struct cifs_sb_info *cifs_sb; | ||
40 | #ifdef CONFIG_CIFS_POSIX | ||
41 | __u64 ExtAttrBits = 0; | ||
42 | __u64 ExtAttrMask = 0; | ||
43 | __u64 caps; | ||
44 | struct cifsTconInfo *tcon; | ||
45 | struct cifsFileInfo *pSMBFile = | ||
46 | (struct cifsFileInfo *)filep->private_data; | ||
47 | #endif /* CONFIG_CIFS_POSIX */ | ||
48 | |||
49 | xid = GetXid(); | ||
50 | |||
51 | cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg)); | ||
52 | |||
53 | cifs_sb = CIFS_SB(inode->i_sb); | ||
54 | |||
34 | #ifdef CONFIG_CIFS_POSIX | 55 | #ifdef CONFIG_CIFS_POSIX |
35 | cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg)); | 56 | tcon = cifs_sb->tcon; |
57 | if(tcon) | ||
58 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | ||
59 | else { | ||
60 | rc = -EIO; | ||
61 | FreeXid(xid); | ||
62 | return -EIO; | ||
63 | } | ||
64 | #endif /* CONFIG_CIFS_POSIX */ | ||
65 | |||
36 | switch(command) { | 66 | switch(command) { |
67 | case CIFS_IOC_CHECKUMOUNT: | ||
68 | cFYI(1,("User unmount attempted")); | ||
69 | if(cifs_sb->mnt_uid == current->uid) | ||
70 | rc = 0; | ||
71 | else { | ||
72 | rc = -EACCES; | ||
73 | cFYI(1,("uids do not match")); | ||
74 | } | ||
75 | break; | ||
76 | #ifdef CONFIG_CIFS_POSIX | ||
37 | case EXT2_IOC_GETFLAGS: | 77 | case EXT2_IOC_GETFLAGS: |
38 | cFYI(1,("get flags not implemented yet")); | 78 | if(CIFS_UNIX_EXTATTR_CAP & caps) { |
39 | return -EOPNOTSUPP; | 79 | if (pSMBFile == NULL) |
80 | break; | ||
81 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, | ||
82 | &ExtAttrBits, &ExtAttrMask); | ||
83 | if(rc == 0) | ||
84 | rc = put_user(ExtAttrBits & | ||
85 | EXT2_FL_USER_VISIBLE, | ||
86 | (int __user *)arg); | ||
87 | } | ||
88 | break; | ||
89 | |||
40 | case EXT2_IOC_SETFLAGS: | 90 | case EXT2_IOC_SETFLAGS: |
91 | if(CIFS_UNIX_EXTATTR_CAP & caps) { | ||
92 | if(get_user(ExtAttrBits,(int __user *)arg)) { | ||
93 | rc = -EFAULT; | ||
94 | break; | ||
95 | } | ||
96 | if (pSMBFile == NULL) | ||
97 | break; | ||
98 | /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, | ||
99 | extAttrBits, &ExtAttrMask);*/ | ||
100 | |||
101 | } | ||
41 | cFYI(1,("set flags not implemented yet")); | 102 | cFYI(1,("set flags not implemented yet")); |
42 | return -EOPNOTSUPP; | 103 | break; |
104 | #endif /* CONFIG_CIFS_POSIX */ | ||
43 | default: | 105 | default: |
44 | cFYI(1,("unsupported ioctl")); | 106 | cFYI(1,("unsupported ioctl")); |
45 | return rc; | 107 | break; |
46 | } | 108 | } |
47 | #endif /* CONFIG_CIFS_POSIX */ | 109 | |
110 | FreeXid(xid); | ||
48 | return rc; | 111 | return rc; |
49 | } | 112 | } |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 1455810ba1cb..bde0fabfece0 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -59,10 +59,14 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, | |||
59 | 59 | ||
60 | if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX) | 60 | if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX) |
61 | rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, | 61 | rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, |
62 | cifs_sb_target->local_nls); | 62 | cifs_sb_target->local_nls, |
63 | cifs_sb_target->mnt_cifs_flags & | ||
64 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
63 | else { | 65 | else { |
64 | rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, | 66 | rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, |
65 | cifs_sb_target->local_nls); | 67 | cifs_sb_target->local_nls, |
68 | cifs_sb_target->mnt_cifs_flags & | ||
69 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
66 | if(rc == -EIO) | 70 | if(rc == -EIO) |
67 | rc = -EOPNOTSUPP; | 71 | rc = -EOPNOTSUPP; |
68 | } | 72 | } |
@@ -260,7 +264,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
260 | cifs_sb->local_nls); | 264 | cifs_sb->local_nls); |
261 | else { | 265 | else { |
262 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, | 266 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, |
263 | OPEN_REPARSE_POINT,&fid, &oplock, NULL, cifs_sb->local_nls); | 267 | OPEN_REPARSE_POINT,&fid, &oplock, NULL, |
268 | cifs_sb->local_nls, | ||
269 | cifs_sb->mnt_cifs_flags & | ||
270 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
264 | if(!rc) { | 271 | if(!rc) { |
265 | rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path, | 272 | rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path, |
266 | tmpbuffer, | 273 | tmpbuffer, |
@@ -279,7 +286,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
279 | strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); | 286 | strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); |
280 | strncat(tmp_path, full_path, MAX_PATHCONF); | 287 | strncat(tmp_path, full_path, MAX_PATHCONF); |
281 | rc = get_dfs_path(xid, pTcon->ses, tmp_path, | 288 | rc = get_dfs_path(xid, pTcon->ses, tmp_path, |
282 | cifs_sb->local_nls, &num_referrals, &referrals); | 289 | cifs_sb->local_nls, |
290 | &num_referrals, &referrals, | ||
291 | cifs_sb->mnt_cifs_flags & | ||
292 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
283 | cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc)); | 293 | cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc)); |
284 | if((num_referrals == 0) && (rc == 0)) | 294 | if((num_referrals == 0) && (rc == 0)) |
285 | rc = -EACCES; | 295 | rc = -EACCES; |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 7b38d3059a83..db14b503d89e 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "cifs_debug.h" | 28 | #include "cifs_debug.h" |
29 | #include "smberr.h" | 29 | #include "smberr.h" |
30 | #include "nterr.h" | 30 | #include "nterr.h" |
31 | #include "cifs_unicode.h" | ||
31 | 32 | ||
32 | extern mempool_t *cifs_sm_req_poolp; | 33 | extern mempool_t *cifs_sm_req_poolp; |
33 | extern mempool_t *cifs_req_poolp; | 34 | extern mempool_t *cifs_req_poolp; |
@@ -451,25 +452,30 @@ is_valid_oplock_break(struct smb_hdr *buf) | |||
451 | atomic_inc(&tcon->num_oplock_brks); | 452 | atomic_inc(&tcon->num_oplock_brks); |
452 | #endif | 453 | #endif |
453 | list_for_each(tmp1,&tcon->openFileList){ | 454 | list_for_each(tmp1,&tcon->openFileList){ |
454 | netfile = list_entry(tmp1,struct cifsFileInfo,tlist); | 455 | netfile = list_entry(tmp1,struct cifsFileInfo, |
456 | tlist); | ||
455 | if(pSMB->Fid == netfile->netfid) { | 457 | if(pSMB->Fid == netfile->netfid) { |
456 | struct cifsInodeInfo *pCifsInode; | 458 | struct cifsInodeInfo *pCifsInode; |
457 | read_unlock(&GlobalSMBSeslock); | 459 | read_unlock(&GlobalSMBSeslock); |
458 | cFYI(1,("Matching file id, processing oplock break")); | 460 | cFYI(1,("file id match, oplock break")); |
459 | pCifsInode = | 461 | pCifsInode = |
460 | CIFS_I(netfile->pInode); | 462 | CIFS_I(netfile->pInode); |
461 | pCifsInode->clientCanCacheAll = FALSE; | 463 | pCifsInode->clientCanCacheAll = FALSE; |
462 | if(pSMB->OplockLevel == 0) | 464 | if(pSMB->OplockLevel == 0) |
463 | pCifsInode->clientCanCacheRead = FALSE; | 465 | pCifsInode->clientCanCacheRead |
466 | = FALSE; | ||
464 | pCifsInode->oplockPending = TRUE; | 467 | pCifsInode->oplockPending = TRUE; |
465 | AllocOplockQEntry(netfile->pInode, netfile->netfid, tcon); | 468 | AllocOplockQEntry(netfile->pInode, |
469 | netfile->netfid, | ||
470 | tcon); | ||
466 | cFYI(1,("about to wake up oplock thd")); | 471 | cFYI(1,("about to wake up oplock thd")); |
467 | wake_up_process(oplockThread); | 472 | if(oplockThread) |
473 | wake_up_process(oplockThread); | ||
468 | return TRUE; | 474 | return TRUE; |
469 | } | 475 | } |
470 | } | 476 | } |
471 | read_unlock(&GlobalSMBSeslock); | 477 | read_unlock(&GlobalSMBSeslock); |
472 | cFYI(1,("No matching file for oplock break on connection")); | 478 | cFYI(1,("No matching file for oplock break")); |
473 | return TRUE; | 479 | return TRUE; |
474 | } | 480 | } |
475 | } | 481 | } |
@@ -490,7 +496,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) | |||
490 | 496 | ||
491 | buffer = (unsigned char *) smb_buf; | 497 | buffer = (unsigned char *) smb_buf; |
492 | for (i = 0, j = 0; i < smb_buf_length; i++, j++) { | 498 | for (i = 0, j = 0; i < smb_buf_length; i++, j++) { |
493 | if (i % 8 == 0) { /* we have reached the beginning of line */ | 499 | if (i % 8 == 0) { /* have reached the beginning of line */ |
494 | printk(KERN_DEBUG "| "); | 500 | printk(KERN_DEBUG "| "); |
495 | j = 0; | 501 | j = 0; |
496 | } | 502 | } |
@@ -501,7 +507,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) | |||
501 | else | 507 | else |
502 | debug_line[1 + (2 * j)] = '_'; | 508 | debug_line[1 + (2 * j)] = '_'; |
503 | 509 | ||
504 | if (i % 8 == 7) { /* we have reached end of line, time to print ascii */ | 510 | if (i % 8 == 7) { /* reached end of line, time to print ascii */ |
505 | debug_line[16] = 0; | 511 | debug_line[16] = 0; |
506 | printk(" | %s\n", debug_line); | 512 | printk(" | %s\n", debug_line); |
507 | } | 513 | } |
@@ -514,3 +520,141 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) | |||
514 | printk( " | %s\n", debug_line); | 520 | printk( " | %s\n", debug_line); |
515 | return; | 521 | return; |
516 | } | 522 | } |
523 | |||
524 | /* Windows maps these to the user defined 16 bit Unicode range since they are | ||
525 | reserved symbols (along with \ and /), otherwise illegal to store | ||
526 | in filenames in NTFS */ | ||
527 | #define UNI_ASTERIK (__u16) ('*' + 0xF000) | ||
528 | #define UNI_QUESTION (__u16) ('?' + 0xF000) | ||
529 | #define UNI_COLON (__u16) (':' + 0xF000) | ||
530 | #define UNI_GRTRTHAN (__u16) ('>' + 0xF000) | ||
531 | #define UNI_LESSTHAN (__u16) ('<' + 0xF000) | ||
532 | #define UNI_PIPE (__u16) ('|' + 0xF000) | ||
533 | #define UNI_SLASH (__u16) ('\\' + 0xF000) | ||
534 | |||
535 | /* Convert 16 bit Unicode pathname from wire format to string in current code | ||
536 | page. Conversion may involve remapping up the seven characters that are | ||
537 | only legal in POSIX-like OS (if they are present in the string). Path | ||
538 | names are little endian 16 bit Unicode on the wire */ | ||
539 | int | ||
540 | cifs_convertUCSpath(char *target, const __le16 * source, int maxlen, | ||
541 | const struct nls_table * cp) | ||
542 | { | ||
543 | int i,j,len; | ||
544 | __u16 src_char; | ||
545 | |||
546 | for(i = 0, j = 0; i < maxlen; i++) { | ||
547 | src_char = le16_to_cpu(source[i]); | ||
548 | switch (src_char) { | ||
549 | case 0: | ||
550 | goto cUCS_out; /* BB check this BB */ | ||
551 | case UNI_COLON: | ||
552 | target[j] = ':'; | ||
553 | break; | ||
554 | case UNI_ASTERIK: | ||
555 | target[j] = '*'; | ||
556 | break; | ||
557 | case UNI_QUESTION: | ||
558 | target[j] = '?'; | ||
559 | break; | ||
560 | /* BB We can not handle remapping slash until | ||
561 | all the calls to build_path_from_dentry | ||
562 | are modified, as they use slash as separator BB */ | ||
563 | /* case UNI_SLASH: | ||
564 | target[j] = '\\'; | ||
565 | break;*/ | ||
566 | case UNI_PIPE: | ||
567 | target[j] = '|'; | ||
568 | break; | ||
569 | case UNI_GRTRTHAN: | ||
570 | target[j] = '>'; | ||
571 | break; | ||
572 | case UNI_LESSTHAN: | ||
573 | target[j] = '<'; | ||
574 | default: | ||
575 | len = cp->uni2char(src_char, &target[j], | ||
576 | NLS_MAX_CHARSET_SIZE); | ||
577 | if(len > 0) { | ||
578 | j += len; | ||
579 | continue; | ||
580 | } else { | ||
581 | target[j] = '?'; | ||
582 | } | ||
583 | } | ||
584 | j++; | ||
585 | /* make sure we do not overrun callers allocated temp buffer */ | ||
586 | if(j >= (2 * NAME_MAX)) | ||
587 | break; | ||
588 | } | ||
589 | cUCS_out: | ||
590 | target[j] = 0; | ||
591 | return j; | ||
592 | } | ||
593 | |||
594 | /* Convert 16 bit Unicode pathname to wire format from string in current code | ||
595 | page. Conversion may involve remapping up the seven characters that are | ||
596 | only legal in POSIX-like OS (if they are present in the string). Path | ||
597 | names are little endian 16 bit Unicode on the wire */ | ||
598 | int | ||
599 | cifsConvertToUCS(__le16 * target, const char *source, int maxlen, | ||
600 | const struct nls_table * cp, int mapChars) | ||
601 | { | ||
602 | int i,j,charlen; | ||
603 | int len_remaining = maxlen; | ||
604 | char src_char; | ||
605 | |||
606 | if(!mapChars) | ||
607 | return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); | ||
608 | |||
609 | for(i = 0, j = 0; i < maxlen; j++) { | ||
610 | src_char = source[i]; | ||
611 | switch (src_char) { | ||
612 | case 0: | ||
613 | goto ctoUCS_out; | ||
614 | case ':': | ||
615 | target[j] = cpu_to_le16(UNI_COLON); | ||
616 | break; | ||
617 | case '*': | ||
618 | target[j] = cpu_to_le16(UNI_ASTERIK); | ||
619 | break; | ||
620 | case '?': | ||
621 | target[j] = cpu_to_le16(UNI_QUESTION); | ||
622 | break; | ||
623 | case '<': | ||
624 | target[j] = cpu_to_le16(UNI_LESSTHAN); | ||
625 | break; | ||
626 | case '>': | ||
627 | target[j] = cpu_to_le16(UNI_GRTRTHAN); | ||
628 | break; | ||
629 | case '|': | ||
630 | target[j] = cpu_to_le16(UNI_PIPE); | ||
631 | break; | ||
632 | /* BB We can not handle remapping slash until | ||
633 | all the calls to build_path_from_dentry | ||
634 | are modified, as they use slash as separator BB */ | ||
635 | /* case '\\': | ||
636 | target[j] = cpu_to_le16(UNI_SLASH); | ||
637 | break;*/ | ||
638 | default: | ||
639 | charlen = cp->char2uni(source+i, | ||
640 | len_remaining, target+j); | ||
641 | /* if no match, use question mark, which | ||
642 | at least in some cases servers as wild card */ | ||
643 | if(charlen < 1) { | ||
644 | target[j] = cpu_to_le16(0x003f); | ||
645 | charlen = 1; | ||
646 | } | ||
647 | len_remaining -= charlen; | ||
648 | /* character may take more than one byte in the | ||
649 | the source string, but will take exactly two | ||
650 | bytes in the target string */ | ||
651 | i+= charlen; | ||
652 | continue; | ||
653 | } | ||
654 | i++; /* move to next char in source string */ | ||
655 | len_remaining--; | ||
656 | } | ||
657 | |||
658 | ctoUCS_out: | ||
659 | return i; | ||
660 | } | ||
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 4e34c89cec5d..a92af41d4411 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -78,6 +78,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = { | |||
78 | {ErrQuota, -EDQUOT}, | 78 | {ErrQuota, -EDQUOT}, |
79 | {ErrNotALink, -ENOLINK}, | 79 | {ErrNotALink, -ENOLINK}, |
80 | {ERRnetlogonNotStarted,-ENOPROTOOPT}, | 80 | {ERRnetlogonNotStarted,-ENOPROTOOPT}, |
81 | {ErrTooManyLinks,-EMLINK}, | ||
81 | {0, 0} | 82 | {0, 0} |
82 | }; | 83 | }; |
83 | 84 | ||
@@ -206,7 +207,7 @@ static const struct { | |||
206 | { | 207 | { |
207 | ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, { | 208 | ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, { |
208 | ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, { | 209 | ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, { |
209 | ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, { | 210 | ERRDOS, ERRinvlevel, NT_STATUS_INVALID_INFO_CLASS}, { |
210 | ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, { | 211 | ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, { |
211 | ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, { | 212 | ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, { |
212 | ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, { | 213 | ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, { |
@@ -742,7 +743,7 @@ static const struct { | |||
742 | ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, { | 743 | ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, { |
743 | ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, { | 744 | ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, { |
744 | ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, { | 745 | ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, { |
745 | ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LINKS}, { | 746 | ERRDOS, ErrTooManyLinks, NT_STATUS_TOO_MANY_LINKS}, { |
746 | ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, { | 747 | ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, { |
747 | ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, { | 748 | ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, { |
748 | ERRDOS, 21, 0xc000026e}, { | 749 | ERRDOS, 21, 0xc000026e}, { |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index f8bea395ec9e..22557716f9af 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Directory search handling | 4 | * Directory search handling |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2004 | 6 | * Copyright (C) International Business Machines Corp., 2004, 2005 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * | 8 | * |
9 | * This library is free software; you can redistribute it and/or modify | 9 | * This library is free software; you can redistribute it and/or modify |
@@ -65,14 +65,14 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
65 | struct cifsTconInfo *pTcon; | 65 | struct cifsTconInfo *pTcon; |
66 | int rc = 0; | 66 | int rc = 0; |
67 | 67 | ||
68 | cFYI(1, ("For %s ", qstring->name)); | 68 | cFYI(1, ("For %s", qstring->name)); |
69 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 69 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); |
70 | pTcon = cifs_sb->tcon; | 70 | pTcon = cifs_sb->tcon; |
71 | 71 | ||
72 | qstring->hash = full_name_hash(qstring->name, qstring->len); | 72 | qstring->hash = full_name_hash(qstring->name, qstring->len); |
73 | tmp_dentry = d_lookup(file->f_dentry, qstring); | 73 | tmp_dentry = d_lookup(file->f_dentry, qstring); |
74 | if (tmp_dentry) { | 74 | if (tmp_dentry) { |
75 | cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode)); | 75 | cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); |
76 | *ptmp_inode = tmp_dentry->d_inode; | 76 | *ptmp_inode = tmp_dentry->d_inode; |
77 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ | 77 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ |
78 | if(*ptmp_inode == NULL) { | 78 | if(*ptmp_inode == NULL) { |
@@ -105,8 +105,11 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
105 | } | 105 | } |
106 | 106 | ||
107 | static void fill_in_inode(struct inode *tmp_inode, | 107 | static void fill_in_inode(struct inode *tmp_inode, |
108 | FILE_DIRECTORY_INFO *pfindData, int *pobject_type) | 108 | FILE_DIRECTORY_INFO *pfindData, int *pobject_type, int isNewInode) |
109 | { | 109 | { |
110 | loff_t local_size; | ||
111 | struct timespec local_mtime; | ||
112 | |||
110 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); | 113 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); |
111 | struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); | 114 | struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); |
112 | __u32 attr = le32_to_cpu(pfindData->ExtFileAttributes); | 115 | __u32 attr = le32_to_cpu(pfindData->ExtFileAttributes); |
@@ -116,6 +119,10 @@ static void fill_in_inode(struct inode *tmp_inode, | |||
116 | cifsInfo->cifsAttrs = attr; | 119 | cifsInfo->cifsAttrs = attr; |
117 | cifsInfo->time = jiffies; | 120 | cifsInfo->time = jiffies; |
118 | 121 | ||
122 | /* save mtime and size */ | ||
123 | local_mtime = tmp_inode->i_mtime; | ||
124 | local_size = tmp_inode->i_size; | ||
125 | |||
119 | /* Linux can not store file creation time unfortunately so ignore it */ | 126 | /* Linux can not store file creation time unfortunately so ignore it */ |
120 | tmp_inode->i_atime = | 127 | tmp_inode->i_atime = |
121 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); | 128 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); |
@@ -134,7 +141,6 @@ static void fill_in_inode(struct inode *tmp_inode, | |||
134 | tmp_inode->i_mode = cifs_sb->mnt_file_mode; | 141 | tmp_inode->i_mode = cifs_sb->mnt_file_mode; |
135 | } | 142 | } |
136 | 143 | ||
137 | cFYI(0,("CIFS FFIRST: Attributes came in as 0x%x",attr)); | ||
138 | if (attr & ATTR_DIRECTORY) { | 144 | if (attr & ATTR_DIRECTORY) { |
139 | *pobject_type = DT_DIR; | 145 | *pobject_type = DT_DIR; |
140 | /* override default perms since we do not lock dirs */ | 146 | /* override default perms since we do not lock dirs */ |
@@ -175,30 +181,46 @@ static void fill_in_inode(struct inode *tmp_inode, | |||
175 | (unsigned long)tmp_inode->i_size, tmp_inode->i_blocks, | 181 | (unsigned long)tmp_inode->i_size, tmp_inode->i_blocks, |
176 | tmp_inode->i_blksize)); | 182 | tmp_inode->i_blksize)); |
177 | if (S_ISREG(tmp_inode->i_mode)) { | 183 | if (S_ISREG(tmp_inode->i_mode)) { |
178 | cFYI(1, (" File inode ")); | 184 | cFYI(1, ("File inode")); |
179 | tmp_inode->i_op = &cifs_file_inode_ops; | 185 | tmp_inode->i_op = &cifs_file_inode_ops; |
180 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | 186 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) |
181 | tmp_inode->i_fop = &cifs_file_direct_ops; | 187 | tmp_inode->i_fop = &cifs_file_direct_ops; |
182 | else | 188 | else |
183 | tmp_inode->i_fop = &cifs_file_ops; | 189 | tmp_inode->i_fop = &cifs_file_ops; |
184 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | 190 | tmp_inode->i_data.a_ops = &cifs_addr_ops; |
191 | |||
192 | if(isNewInode) | ||
193 | return; /* No sense invalidating pages for new inode since we | ||
194 | have not started caching readahead file data yet */ | ||
195 | |||
196 | if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && | ||
197 | (local_size == tmp_inode->i_size)) { | ||
198 | cFYI(1, ("inode exists but unchanged")); | ||
199 | } else { | ||
200 | /* file may have changed on server */ | ||
201 | cFYI(1, ("invalidate inode, readdir detected change")); | ||
202 | invalidate_remote_inode(tmp_inode); | ||
203 | } | ||
185 | } else if (S_ISDIR(tmp_inode->i_mode)) { | 204 | } else if (S_ISDIR(tmp_inode->i_mode)) { |
186 | cFYI(1, (" Directory inode")); | 205 | cFYI(1, ("Directory inode")); |
187 | tmp_inode->i_op = &cifs_dir_inode_ops; | 206 | tmp_inode->i_op = &cifs_dir_inode_ops; |
188 | tmp_inode->i_fop = &cifs_dir_ops; | 207 | tmp_inode->i_fop = &cifs_dir_ops; |
189 | } else if (S_ISLNK(tmp_inode->i_mode)) { | 208 | } else if (S_ISLNK(tmp_inode->i_mode)) { |
190 | cFYI(1, (" Symbolic Link inode ")); | 209 | cFYI(1, ("Symbolic Link inode")); |
191 | tmp_inode->i_op = &cifs_symlink_inode_ops; | 210 | tmp_inode->i_op = &cifs_symlink_inode_ops; |
192 | } else { | 211 | } else { |
193 | cFYI(1, (" Init special inode ")); | 212 | cFYI(1, ("Init special inode")); |
194 | init_special_inode(tmp_inode, tmp_inode->i_mode, | 213 | init_special_inode(tmp_inode, tmp_inode->i_mode, |
195 | tmp_inode->i_rdev); | 214 | tmp_inode->i_rdev); |
196 | } | 215 | } |
197 | } | 216 | } |
198 | 217 | ||
199 | static void unix_fill_in_inode(struct inode *tmp_inode, | 218 | static void unix_fill_in_inode(struct inode *tmp_inode, |
200 | FILE_UNIX_INFO *pfindData, int *pobject_type) | 219 | FILE_UNIX_INFO *pfindData, int *pobject_type, int isNewInode) |
201 | { | 220 | { |
221 | loff_t local_size; | ||
222 | struct timespec local_mtime; | ||
223 | |||
202 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); | 224 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); |
203 | struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); | 225 | struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); |
204 | 226 | ||
@@ -208,6 +230,10 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
208 | cifsInfo->time = jiffies; | 230 | cifsInfo->time = jiffies; |
209 | atomic_inc(&cifsInfo->inUse); | 231 | atomic_inc(&cifsInfo->inUse); |
210 | 232 | ||
233 | /* save mtime and size */ | ||
234 | local_mtime = tmp_inode->i_mtime; | ||
235 | local_size = tmp_inode->i_size; | ||
236 | |||
211 | tmp_inode->i_atime = | 237 | tmp_inode->i_atime = |
212 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); | 238 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); |
213 | tmp_inode->i_mtime = | 239 | tmp_inode->i_mtime = |
@@ -265,6 +291,19 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
265 | else | 291 | else |
266 | tmp_inode->i_fop = &cifs_file_ops; | 292 | tmp_inode->i_fop = &cifs_file_ops; |
267 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | 293 | tmp_inode->i_data.a_ops = &cifs_addr_ops; |
294 | |||
295 | if(isNewInode) | ||
296 | return; /* No sense invalidating pages for new inode since we | ||
297 | have not started caching readahead file data yet */ | ||
298 | |||
299 | if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && | ||
300 | (local_size == tmp_inode->i_size)) { | ||
301 | cFYI(1, ("inode exists but unchanged")); | ||
302 | } else { | ||
303 | /* file may have changed on server */ | ||
304 | cFYI(1, ("invalidate inode, readdir detected change")); | ||
305 | invalidate_remote_inode(tmp_inode); | ||
306 | } | ||
268 | } else if (S_ISDIR(tmp_inode->i_mode)) { | 307 | } else if (S_ISDIR(tmp_inode->i_mode)) { |
269 | cFYI(1, ("Directory inode")); | 308 | cFYI(1, ("Directory inode")); |
270 | tmp_inode->i_op = &cifs_dir_inode_ops; | 309 | tmp_inode->i_op = &cifs_dir_inode_ops; |
@@ -314,15 +353,16 @@ static int initiate_cifs_search(const int xid, struct file *file) | |||
314 | return -EINVAL; | 353 | return -EINVAL; |
315 | 354 | ||
316 | down(&file->f_dentry->d_sb->s_vfs_rename_sem); | 355 | down(&file->f_dentry->d_sb->s_vfs_rename_sem); |
317 | full_path = build_wildcard_path_from_dentry(file->f_dentry); | 356 | full_path = build_path_from_dentry(file->f_dentry); |
318 | up(&file->f_dentry->d_sb->s_vfs_rename_sem); | 357 | up(&file->f_dentry->d_sb->s_vfs_rename_sem); |
319 | 358 | ||
320 | if(full_path == NULL) { | 359 | if(full_path == NULL) { |
321 | return -ENOMEM; | 360 | return -ENOMEM; |
322 | } | 361 | } |
323 | 362 | ||
324 | cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos)); | 363 | cFYI(1, ("Full path: %s start at: %lld", full_path, file->f_pos)); |
325 | 364 | ||
365 | ffirst_retry: | ||
326 | /* test for Unix extensions */ | 366 | /* test for Unix extensions */ |
327 | if (pTcon->ses->capabilities & CAP_UNIX) { | 367 | if (pTcon->ses->capabilities & CAP_UNIX) { |
328 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; | 368 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; |
@@ -332,10 +372,16 @@ static int initiate_cifs_search(const int xid, struct file *file) | |||
332 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; | 372 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; |
333 | } | 373 | } |
334 | 374 | ||
335 | rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, | 375 | rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, |
336 | &cifsFile->netfid, &cifsFile->srch_inf); | 376 | &cifsFile->netfid, &cifsFile->srch_inf, |
377 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
337 | if(rc == 0) | 378 | if(rc == 0) |
338 | cifsFile->invalidHandle = FALSE; | 379 | cifsFile->invalidHandle = FALSE; |
380 | if((rc == -EOPNOTSUPP) && | ||
381 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { | ||
382 | cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; | ||
383 | goto ffirst_retry; | ||
384 | } | ||
339 | kfree(full_path); | 385 | kfree(full_path); |
340 | return rc; | 386 | return rc; |
341 | } | 387 | } |
@@ -363,10 +409,15 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb) | |||
363 | cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); | 409 | cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); |
364 | /* validate that new_entry is not past end of SMB */ | 410 | /* validate that new_entry is not past end of SMB */ |
365 | if(new_entry >= end_of_smb) { | 411 | if(new_entry >= end_of_smb) { |
366 | cFYI(1,("search entry %p began after end of SMB %p old entry %p", | 412 | cERROR(1, |
367 | new_entry,end_of_smb,old_entry)); | 413 | ("search entry %p began after end of SMB %p old entry %p", |
414 | new_entry, end_of_smb, old_entry)); | ||
368 | return NULL; | 415 | return NULL; |
369 | } else | 416 | } else if (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb) { |
417 | cERROR(1,("search entry %p extends after end of SMB %p", | ||
418 | new_entry, end_of_smb)); | ||
419 | return NULL; | ||
420 | } else | ||
370 | return new_entry; | 421 | return new_entry; |
371 | 422 | ||
372 | } | 423 | } |
@@ -594,7 +645,12 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, | |||
594 | if(unicode) { | 645 | if(unicode) { |
595 | /* BB fixme - test with long names */ | 646 | /* BB fixme - test with long names */ |
596 | /* Note converted filename can be longer than in unicode */ | 647 | /* Note converted filename can be longer than in unicode */ |
597 | pqst->len = cifs_strfromUCS_le((char *)pqst->name,(wchar_t *)filename,len/2,nlt); | 648 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) |
649 | pqst->len = cifs_convertUCSpath((char *)pqst->name, | ||
650 | (__le16 *)filename, len/2, nlt); | ||
651 | else | ||
652 | pqst->len = cifs_strfromUCS_le((char *)pqst->name, | ||
653 | (wchar_t *)filename,len/2,nlt); | ||
598 | } else { | 654 | } else { |
599 | pqst->name = filename; | 655 | pqst->name = filename; |
600 | pqst->len = len; | 656 | pqst->len = len; |
@@ -654,10 +710,15 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
654 | insert_inode_hash(tmp_inode); | 710 | insert_inode_hash(tmp_inode); |
655 | } | 711 | } |
656 | 712 | ||
713 | /* we pass in rc below, indicating whether it is a new inode, | ||
714 | so we can figure out whether to invalidate the inode cached | ||
715 | data if the file has changed */ | ||
657 | if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) { | 716 | if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) { |
658 | unix_fill_in_inode(tmp_inode,(FILE_UNIX_INFO *)pfindEntry,&obj_type); | 717 | unix_fill_in_inode(tmp_inode, |
718 | (FILE_UNIX_INFO *)pfindEntry,&obj_type, rc); | ||
659 | } else { | 719 | } else { |
660 | fill_in_inode(tmp_inode,(FILE_DIRECTORY_INFO *)pfindEntry,&obj_type); | 720 | fill_in_inode(tmp_inode, |
721 | (FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc); | ||
661 | } | 722 | } |
662 | 723 | ||
663 | rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,tmp_inode->i_ino,obj_type); | 724 | rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,tmp_inode->i_ino,obj_type); |
@@ -823,7 +884,11 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
823 | end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + | 884 | end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + |
824 | smbCalcSize((struct smb_hdr *) | 885 | smbCalcSize((struct smb_hdr *) |
825 | cifsFile->srch_inf.ntwrk_buf_start); | 886 | cifsFile->srch_inf.ntwrk_buf_start); |
826 | tmp_buf = kmalloc(NAME_MAX+1,GFP_KERNEL); | 887 | /* To be safe - for UCS to UTF-8 with strings loaded |
888 | with the rare long characters alloc more to account for | ||
889 | such multibyte target UTF-8 characters. cifs_unicode.c, | ||
890 | which actually does the conversion, has the same limit */ | ||
891 | tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL); | ||
827 | for(i=0;(i<num_to_fill) && (rc == 0);i++) { | 892 | for(i=0;(i<num_to_fill) && (rc == 0);i++) { |
828 | if(current_entry == NULL) { | 893 | if(current_entry == NULL) { |
829 | /* evaluate whether this case is an error */ | 894 | /* evaluate whether this case is an error */ |
@@ -832,19 +897,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
832 | break; | 897 | break; |
833 | } | 898 | } |
834 | 899 | ||
835 | /* BB FIXME - need to enable the below code BB */ | ||
836 | |||
837 | /* if((!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) || | ||
838 | (cifsFile->srch_inf.info_level != | ||
839 | something that supports server inodes)) { | ||
840 | create dentry | ||
841 | create inode | ||
842 | fill in inode new_inode (getting local i_ino) | ||
843 | } | ||
844 | also create local inode for performance reasons (so we | ||
845 | have a cache of inode metadata) unless this new mount | ||
846 | parm says otherwise */ | ||
847 | |||
848 | rc = cifs_filldir(current_entry, file, | 900 | rc = cifs_filldir(current_entry, file, |
849 | filldir, direntry,tmp_buf); | 901 | filldir, direntry,tmp_buf); |
850 | file->f_pos++; | 902 | file->f_pos++; |
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h index e21f1384661f..cd41c67ff8d3 100644 --- a/fs/cifs/smberr.h +++ b/fs/cifs/smberr.h | |||
@@ -22,94 +22,159 @@ | |||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define SUCCESS 0 /* The request was successful. */ | 25 | #define SUCCESS 0x00 /* The request was successful. */ |
26 | #define ERRDOS 0x01 /* Error is from the core DOS operating system set */ | 26 | #define ERRDOS 0x01 /* Error is from the core DOS operating system set */ |
27 | #define ERRSRV 0x02 /* Error is generated by the file server daemon */ | 27 | #define ERRSRV 0x02 /* Error is generated by the file server daemon */ |
28 | #define ERRHRD 0x03 /* Error is a hardware error. */ | 28 | #define ERRHRD 0x03 /* Error is a hardware error. */ |
29 | #define ERRCMD 0xFF /* Command was not in the "SMB" format. */ | 29 | #define ERRCMD 0xFF /* Command was not in the "SMB" format. */ |
30 | 30 | ||
31 | /* The following error codes may be generated with the SUCCESS error class.*/ | 31 | /* The following error codes may be generated with the SUCCESS error class.*/ |
32 | 32 | ||
33 | #define SUCCESS 0 /* The request was successful. */ | 33 | /*#define SUCCESS 0 The request was successful. */ |
34 | 34 | ||
35 | /* The following error codes may be generated with the ERRDOS error class.*/ | 35 | /* The following error codes may be generated with the ERRDOS error class.*/ |
36 | 36 | ||
37 | #define ERRbadfunc 1 /* Invalid function. The server did not recognize or could not perform a system call generated by the server, e.g., set the DIRECTORY attribute on a data file, invalid seek mode. */ | 37 | #define ERRbadfunc 1 /* Invalid function. The server did not |
38 | #define ERRbadfile 2 /*File not found. The last component of a file's pathname could not be found. */ | 38 | recognize or could not perform a |
39 | #define ERRbadpath 3 /* Directory invalid. A directory component in a pathname could not be found. */ | 39 | system call generated by the server, |
40 | #define ERRnofids 4 /* Too many open files. The server has no file handles available. */ | 40 | e.g., set the DIRECTORY attribute on |
41 | #define ERRnoaccess 5 /* Access denied, the client's context does not permit the requested function. This includes the following conditions: invalid rename command, write to Fid open for read only, read on Fid open for write only, attempt to delete a non-empty directory */ | 41 | a data file, invalid seek mode. */ |
42 | #define ERRbadfid 6 /* Invalid file handle. The file handle specified was not recognized by the server. */ | 42 | #define ERRbadfile 2 /* File not found. The last component |
43 | #define ERRbadmcb 7 /* Memory control blocks destroyed. */ | 43 | of a file's pathname could not be |
44 | #define ERRnomem 8 /* Insufficient server memory to perform the requested function. */ | 44 | found. */ |
45 | #define ERRbadmem 9 /* Invalid memory block address. */ | 45 | #define ERRbadpath 3 /* Directory invalid. A directory |
46 | #define ERRbadenv 10 /* Invalid environment. */ | 46 | component in a pathname could not be |
47 | #define ERRbadformat 11 /* Invalid format. */ | 47 | found. */ |
48 | #define ERRbadaccess 12 /* Invalid open mode. */ | 48 | #define ERRnofids 4 /* Too many open files. The server has |
49 | #define ERRbaddata 13 /* Invalid data (generated only by IOCTL calls within the server). */ | 49 | no file handles available. */ |
50 | #define ERRbaddrive 15 /* Invalid drive specified. */ | 50 | #define ERRnoaccess 5 /* Access denied, the client's context |
51 | #define ERRremcd 16 /* A Delete Directory request attempted to remove the server's current directory. */ | 51 | does not permit the requested |
52 | #define ERRdiffdevice 17 /* Not same device (e.g., a cross volume rename was attempted */ | 52 | function. This includes the |
53 | #define ERRnofiles 18 /* A File Search command can find no more files matching the specified criteria. */ | 53 | following conditions: invalid rename |
54 | #define ERRgeneral 31 | 54 | command, write to Fid open for read |
55 | #define ERRbadshare 32 /* The sharing mode specified for an Open conflicts with existing FIDs on the file. */ | 55 | only, read on Fid open for write |
56 | #define ERRlock 33 /* A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process. */ | 56 | only, attempt to delete a non-empty |
57 | #define ERRunsup 50 | 57 | directory */ |
58 | #define ERRnosuchshare 67 | 58 | #define ERRbadfid 6 /* Invalid file handle. The file handle |
59 | #define ERRfilexists 80 /* The file named in the request already exists. */ | 59 | specified was not recognized by the |
60 | #define ERRinvparm 87 | 60 | server. */ |
61 | #define ERRdiskfull 112 | 61 | #define ERRbadmcb 7 /* Memory control blocks destroyed. */ |
62 | #define ERRinvname 123 | 62 | #define ERRnomem 8 /* Insufficient server memory to |
63 | #define ERRinvlevel 124 | 63 | perform the requested function. */ |
64 | #define ERRdirnotempty 145 | 64 | #define ERRbadmem 9 /* Invalid memory block address. */ |
65 | #define ERRnotlocked 158 | 65 | #define ERRbadenv 10 /* Invalid environment. */ |
66 | #define ERRalreadyexists 183 | 66 | #define ERRbadformat 11 /* Invalid format. */ |
67 | #define ERRbadpipe 230 | 67 | #define ERRbadaccess 12 /* Invalid open mode. */ |
68 | #define ERRpipebusy 231 | 68 | #define ERRbaddata 13 /* Invalid data (generated only by |
69 | #define ERRpipeclosing 232 | 69 | IOCTL calls within the server). */ |
70 | #define ERRnotconnected 233 | 70 | #define ERRbaddrive 15 /* Invalid drive specified. */ |
71 | #define ERRmoredata 234 | 71 | #define ERRremcd 16 /* A Delete Directory request attempted |
72 | #define ERReasnotsupported 282 | 72 | to remove the server's current |
73 | #define ErrQuota 0x200 /* The operation would cause a quota limit to be exceeded. */ | 73 | directory. */ |
74 | #define ErrNotALink 0x201 /* A link operation was performed on a pathname that | 74 | #define ERRdiffdevice 17 /* Not same device (e.g., a cross |
75 | was not a link. */ | 75 | volume rename was attempted */ |
76 | #define ERRnofiles 18 /* A File Search command can find no | ||
77 | more files matching the specified | ||
78 | criteria. */ | ||
79 | #define ERRgeneral 31 | ||
80 | #define ERRbadshare 32 /* The sharing mode specified for an | ||
81 | Open conflicts with existing FIDs on | ||
82 | the file. */ | ||
83 | #define ERRlock 33 /* A Lock request conflicted with an | ||
84 | existing lock or specified an | ||
85 | invalid mode, or an Unlock requested | ||
86 | attempted to remove a lock held by | ||
87 | another process. */ | ||
88 | #define ERRunsup 50 | ||
89 | #define ERRnosuchshare 67 | ||
90 | #define ERRfilexists 80 /* The file named in the request | ||
91 | already exists. */ | ||
92 | #define ERRinvparm 87 | ||
93 | #define ERRdiskfull 112 | ||
94 | #define ERRinvname 123 | ||
95 | #define ERRinvlevel 124 | ||
96 | #define ERRdirnotempty 145 | ||
97 | #define ERRnotlocked 158 | ||
98 | #define ERRalreadyexists 183 | ||
99 | #define ERRbadpipe 230 | ||
100 | #define ERRpipebusy 231 | ||
101 | #define ERRpipeclosing 232 | ||
102 | #define ERRnotconnected 233 | ||
103 | #define ERRmoredata 234 | ||
104 | #define ERReasnotsupported 282 | ||
105 | #define ErrQuota 0x200 /* The operation would cause a quota | ||
106 | limit to be exceeded. */ | ||
107 | #define ErrNotALink 0x201 /* A link operation was performed on a | ||
108 | pathname that was not a link. */ | ||
76 | 109 | ||
77 | /* Following error codes may be generated with the ERRSRV error | 110 | /* Below errors are used internally (do not come over the wire) for passthrough |
78 | class.*/ | 111 | from STATUS codes to POSIX only */ |
112 | #define ErrTooManyLinks 0xFFFE | ||
79 | 113 | ||
80 | #define ERRerror 1 /* Non-specific error code. It is returned under the following conditions: resource other than disk space exhausted (e.g. TIDs), first SMB command was not negotiate, multiple negotiates attempted, and internal server error. */ | 114 | /* Following error codes may be generated with the ERRSRV error class.*/ |
81 | #define ERRbadpw 2 /* Bad password - name/password pair in a TreeConnect or Session Setup are invalid. */ | 115 | |
82 | #define ERRbadtype 3 /* used for indicating DFS referral needed */ | 116 | #define ERRerror 1 /* Non-specific error code. It is |
83 | #define ERRaccess 4 /* The client does not have the necessary access rights within the specified context for requested function. */ | 117 | returned under the following |
84 | #define ERRinvtid 5 /* The Tid specified in a command was invalid. */ | 118 | conditions: resource other than disk |
85 | #define ERRinvnetname 6 /* Invalid network name in tree connect. */ | 119 | space exhausted (e.g. TIDs), first |
86 | #define ERRinvdevice 7 /* Invalid device - printer request made to non-printer connection or non-printer request made to printer connection. */ | 120 | SMB command was not negotiate, |
87 | #define ERRqfull 49 /* Print queue full (files) -- returned by open print file. */ | 121 | multiple negotiates attempted, and |
88 | #define ERRqtoobig 50 /* Print queue full -- no space. */ | 122 | internal server error. */ |
89 | #define ERRqeof 51 /* EOF on print queue dump */ | 123 | #define ERRbadpw 2 /* Bad password - name/password pair in |
90 | #define ERRinvpfid 52 /* Invalid print file FID. */ | 124 | a TreeConnect or Session Setup are |
91 | #define ERRsmbcmd 64 /* The server did not recognize the command received. */ | 125 | invalid. */ |
92 | #define ERRsrverror 65 /* The server encountered an internal error, e.g., system file unavailable. */ | 126 | #define ERRbadtype 3 /* used for indicating DFS referral |
93 | #define ERRbadBID 66 /* (obsolete) */ | 127 | needed */ |
94 | #define ERRfilespecs 67 /* The Fid and pathname parameters contained an invalid combination of values. */ | 128 | #define ERRaccess 4 /* The client does not have the |
95 | #define ERRbadLink 68 /* (obsolete) */ | 129 | necessary access rights within the |
96 | #define ERRbadpermits 69 /* The access permissions specified for a file or directory are not a valid combination. */ | 130 | specified context for requested |
97 | #define ERRbadPID 70 | 131 | function. */ |
98 | #define ERRsetattrmode 71 /* attribute (mode) is invalid */ | 132 | #define ERRinvtid 5 /* The Tid specified in a command was |
99 | #define ERRpaused 81 /* Server is paused */ | 133 | invalid. */ |
100 | #define ERRmsgoff 82 /* reserved - messaging off */ | 134 | #define ERRinvnetname 6 /* Invalid network name in tree |
101 | #define ERRnoroom 83 /* reserved - no room for message */ | 135 | connect. */ |
102 | #define ERRrmuns 87 /* reserved - too many remote names */ | 136 | #define ERRinvdevice 7 /* Invalid device - printer request |
103 | #define ERRtimeout 88 /* operation timed out */ | 137 | made to non-printer connection or |
104 | #define ERRnoresource 89 /* No resources available for request */ | 138 | non-printer request made to printer |
105 | #define ERRtoomanyuids 90 /* Too many UIDs active on this session */ | 139 | connection. */ |
106 | #define ERRbaduid 91 /* The UID is not known as a valid user */ | 140 | #define ERRqfull 49 /* Print queue full (files) -- returned |
107 | #define ERRusempx 250 /* temporarily unable to use raw */ | 141 | by open print file. */ |
108 | #define ERRusestd 251 /* temporarily unable to use either raw or mpx */ | 142 | #define ERRqtoobig 50 /* Print queue full -- no space. */ |
109 | #define ERR_NOTIFY_ENUM_DIR 1024 | 143 | #define ERRqeof 51 /* EOF on print queue dump */ |
110 | #define ERRaccountexpired 2239 | 144 | #define ERRinvpfid 52 /* Invalid print file FID. */ |
111 | #define ERRbadclient 2240 | 145 | #define ERRsmbcmd 64 /* The server did not recognize the |
112 | #define ERRbadLogonTime 2241 | 146 | command received. */ |
113 | #define ERRpasswordExpired 2242 | 147 | #define ERRsrverror 65 /* The server encountered an internal |
114 | #define ERRnetlogonNotStarted 2455 | 148 | error, e.g., system file |
115 | #define ERRnosupport 0xFFFF | 149 | unavailable. */ |
150 | #define ERRbadBID 66 /* (obsolete) */ | ||
151 | #define ERRfilespecs 67 /* The Fid and pathname parameters | ||
152 | contained an invalid combination of | ||
153 | values. */ | ||
154 | #define ERRbadLink 68 /* (obsolete) */ | ||
155 | #define ERRbadpermits 69 /* The access permissions specified for | ||
156 | a file or directory are not a valid | ||
157 | combination. */ | ||
158 | #define ERRbadPID 70 | ||
159 | #define ERRsetattrmode 71 /* attribute (mode) is invalid */ | ||
160 | #define ERRpaused 81 /* Server is paused */ | ||
161 | #define ERRmsgoff 82 /* reserved - messaging off */ | ||
162 | #define ERRnoroom 83 /* reserved - no room for message */ | ||
163 | #define ERRrmuns 87 /* reserved - too many remote names */ | ||
164 | #define ERRtimeout 88 /* operation timed out */ | ||
165 | #define ERRnoresource 89 /* No resources available for request | ||
166 | */ | ||
167 | #define ERRtoomanyuids 90 /* Too many UIDs active on this session | ||
168 | */ | ||
169 | #define ERRbaduid 91 /* The UID is not known as a valid user | ||
170 | */ | ||
171 | #define ERRusempx 250 /* temporarily unable to use raw */ | ||
172 | #define ERRusestd 251 /* temporarily unable to use either raw | ||
173 | or mpx */ | ||
174 | #define ERR_NOTIFY_ENUM_DIR 1024 | ||
175 | #define ERRaccountexpired 2239 | ||
176 | #define ERRbadclient 2240 | ||
177 | #define ERRbadLogonTime 2241 | ||
178 | #define ERRpasswordExpired 2242 | ||
179 | #define ERRnetlogonNotStarted 2455 | ||
180 | #define ERRnosupport 0xFFFF | ||
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index af13e526b150..0046c219833d 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/transport.c | 2 | * fs/cifs/transport.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2004 | 4 | * Copyright (C) International Business Machines Corp., 2002,2005 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -41,7 +41,7 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | |||
41 | struct mid_q_entry *temp; | 41 | struct mid_q_entry *temp; |
42 | 42 | ||
43 | if (ses == NULL) { | 43 | if (ses == NULL) { |
44 | cERROR(1, ("Null session passed in to AllocMidQEntry ")); | 44 | cERROR(1, ("Null session passed in to AllocMidQEntry")); |
45 | return NULL; | 45 | return NULL; |
46 | } | 46 | } |
47 | if (ses->server == NULL) { | 47 | if (ses->server == NULL) { |
@@ -79,7 +79,10 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) | |||
79 | list_del(&midEntry->qhead); | 79 | list_del(&midEntry->qhead); |
80 | atomic_dec(&midCount); | 80 | atomic_dec(&midCount); |
81 | spin_unlock(&GlobalMid_Lock); | 81 | spin_unlock(&GlobalMid_Lock); |
82 | cifs_buf_release(midEntry->resp_buf); | 82 | if(midEntry->largeBuf) |
83 | cifs_buf_release(midEntry->resp_buf); | ||
84 | else | ||
85 | cifs_small_buf_release(midEntry->resp_buf); | ||
83 | mempool_free(midEntry, cifs_mid_poolp); | 86 | mempool_free(midEntry, cifs_mid_poolp); |
84 | } | 87 | } |
85 | 88 | ||
@@ -182,14 +185,14 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, | |||
182 | 185 | ||
183 | int | 186 | int |
184 | smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, | 187 | smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, |
185 | unsigned int smb_buf_length, struct kvec * write_vector /* page list */, struct sockaddr *sin) | 188 | unsigned int smb_buf_length, struct kvec * write_vector |
189 | /* page list */, struct sockaddr *sin) | ||
186 | { | 190 | { |
187 | int rc = 0; | 191 | int rc = 0; |
188 | int i = 0; | 192 | int i = 0; |
189 | struct msghdr smb_msg; | 193 | struct msghdr smb_msg; |
190 | number_of_pages += 1; /* account for SMB header */ | 194 | number_of_pages += 1; /* account for SMB header */ |
191 | struct kvec * piov = kmalloc(number_of_pages * sizeof(struct kvec)); | 195 | struct kvec * piov = kmalloc(number_of_pages * sizeof(struct kvec)); |
192 | if(i=0;i<num_pages-1;i++ | ||
193 | unsigned len = smb_buf_length + 4; | 196 | unsigned len = smb_buf_length + 4; |
194 | 197 | ||
195 | if(ssocket == NULL) | 198 | if(ssocket == NULL) |
@@ -213,7 +216,8 @@ smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, | |||
213 | dump_smb(smb_buffer, len); | 216 | dump_smb(smb_buffer, len); |
214 | 217 | ||
215 | while (len > 0) { | 218 | while (len > 0) { |
216 | rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, len?); | 219 | rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, |
220 | len); | ||
217 | if ((rc == -ENOSPC) || (rc == -EAGAIN)) { | 221 | if ((rc == -ENOSPC) || (rc == -EAGAIN)) { |
218 | i++; | 222 | i++; |
219 | if(i > 60) { | 223 | if(i > 60) { |
@@ -266,6 +270,9 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, | |||
266 | 270 | ||
267 | 271 | ||
268 | 272 | ||
273 | if(ses->server->tcpStatus == CIFS_EXITING) | ||
274 | return -ENOENT; | ||
275 | |||
269 | /* Ensure that we do not send more than 50 overlapping requests | 276 | /* Ensure that we do not send more than 50 overlapping requests |
270 | to the same server. We may make this configurable later or | 277 | to the same server. We may make this configurable later or |
271 | use ses->maxReq */ | 278 | use ses->maxReq */ |
@@ -346,11 +353,12 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, | |||
346 | } | 353 | } |
347 | 354 | ||
348 | /* BB can we sign efficiently in this path? */ | 355 | /* BB can we sign efficiently in this path? */ |
349 | rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number); | 356 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); |
350 | 357 | ||
351 | midQ->midState = MID_REQUEST_SUBMITTED; | 358 | midQ->midState = MID_REQUEST_SUBMITTED; |
352 | /* rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, piovec, | 359 | /* rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, |
353 | (struct sockaddr *) &(ses->server->addr.sockAddr));*/ | 360 | piovec, |
361 | (struct sockaddr *) &(ses->server->addr.sockAddr));*/ | ||
354 | if(rc < 0) { | 362 | if(rc < 0) { |
355 | DeleteMidQEntry(midQ); | 363 | DeleteMidQEntry(midQ); |
356 | up(&ses->server->tcpSem); | 364 | up(&ses->server->tcpSem); |
@@ -396,6 +404,9 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
396 | return -EIO; | 404 | return -EIO; |
397 | } | 405 | } |
398 | 406 | ||
407 | if(ses->server->tcpStatus == CifsExiting) | ||
408 | return -ENOENT; | ||
409 | |||
399 | /* Ensure that we do not send more than 50 overlapping requests | 410 | /* Ensure that we do not send more than 50 overlapping requests |
400 | to the same server. We may make this configurable later or | 411 | to the same server. We may make this configurable later or |
401 | use ses->maxReq */ | 412 | use ses->maxReq */ |
@@ -405,7 +416,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
405 | } else { | 416 | } else { |
406 | spin_lock(&GlobalMid_Lock); | 417 | spin_lock(&GlobalMid_Lock); |
407 | while(1) { | 418 | while(1) { |
408 | if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){ | 419 | if(atomic_read(&ses->server->inFlight) >= |
420 | cifs_max_pending){ | ||
409 | spin_unlock(&GlobalMid_Lock); | 421 | spin_unlock(&GlobalMid_Lock); |
410 | wait_event(ses->server->request_q, | 422 | wait_event(ses->server->request_q, |
411 | atomic_read(&ses->server->inFlight) | 423 | atomic_read(&ses->server->inFlight) |
@@ -475,7 +487,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
475 | return -EIO; | 487 | return -EIO; |
476 | } | 488 | } |
477 | 489 | ||
478 | rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number); | 490 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); |
479 | 491 | ||
480 | midQ->midState = MID_REQUEST_SUBMITTED; | 492 | midQ->midState = MID_REQUEST_SUBMITTED; |
481 | rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, | 493 | rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, |
@@ -493,7 +505,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
493 | up(&ses->server->tcpSem); | 505 | up(&ses->server->tcpSem); |
494 | if (long_op == -1) | 506 | if (long_op == -1) |
495 | goto cifs_no_response_exit; | 507 | goto cifs_no_response_exit; |
496 | else if (long_op == 2) /* writes past end of file can take looooong time */ | 508 | else if (long_op == 2) /* writes past end of file can take loong time */ |
497 | timeout = 300 * HZ; | 509 | timeout = 300 * HZ; |
498 | else if (long_op == 1) | 510 | else if (long_op == 1) |
499 | timeout = 45 * HZ; /* should be greater than | 511 | timeout = 45 * HZ; /* should be greater than |
@@ -559,8 +571,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
559 | } | 571 | } |
560 | 572 | ||
561 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { | 573 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { |
562 | cERROR(1, | 574 | cERROR(1, ("Frame too large received. Length: %d Xid: %d", |
563 | ("Frame too large received. Length: %d Xid: %d", | ||
564 | receive_len, xid)); | 575 | receive_len, xid)); |
565 | rc = -EIO; | 576 | rc = -EIO; |
566 | } else { /* rcvd frame is ok */ | 577 | } else { /* rcvd frame is ok */ |
@@ -575,15 +586,20 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
575 | dump_smb(out_buf, 92); | 586 | dump_smb(out_buf, 92); |
576 | /* convert the length into a more usable form */ | 587 | /* convert the length into a more usable form */ |
577 | if((receive_len > 24) && | 588 | if((receive_len > 24) && |
578 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { | 589 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | |
579 | rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */ | 590 | SECMODE_SIGN_ENABLED))) { |
580 | if(rc) | 591 | rc = cifs_verify_signature(out_buf, |
581 | cFYI(1,("Unexpected signature received from server")); | 592 | ses->server->mac_signing_key, |
593 | midQ->sequence_number+1); | ||
594 | if(rc) { | ||
595 | cERROR(1,("Unexpected SMB signature")); | ||
596 | /* BB FIXME add code to kill session */ | ||
597 | } | ||
582 | } | 598 | } |
583 | 599 | ||
584 | *pbytes_returned = out_buf->smb_buf_length; | 600 | *pbytes_returned = out_buf->smb_buf_length; |
585 | 601 | ||
586 | /* BB special case reconnect tid and reconnect uid here? */ | 602 | /* BB special case reconnect tid and uid here? */ |
587 | rc = map_smb_to_linux_error(out_buf); | 603 | rc = map_smb_to_linux_error(out_buf); |
588 | 604 | ||
589 | /* convert ByteCount if necessary */ | 605 | /* convert ByteCount if necessary */ |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 549afa184fd6..c1e02eff1d25 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -83,7 +83,8 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name) | |||
83 | 83 | ||
84 | ea_name+=5; /* skip past user. prefix */ | 84 | ea_name+=5; /* skip past user. prefix */ |
85 | rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL, | 85 | rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL, |
86 | (__u16)0, cifs_sb->local_nls); | 86 | (__u16)0, cifs_sb->local_nls, |
87 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
87 | } | 88 | } |
88 | remove_ea_exit: | 89 | remove_ea_exit: |
89 | if (full_path) | 90 | if (full_path) |
@@ -147,32 +148,40 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name, | |||
147 | } | 148 | } |
148 | ea_name += 5; /* skip past user. prefix */ | 149 | ea_name += 5; /* skip past user. prefix */ |
149 | rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, | 150 | rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, |
150 | (__u16)value_size, cifs_sb->local_nls); | 151 | (__u16)value_size, cifs_sb->local_nls, |
152 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
151 | } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { | 153 | } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { |
152 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) | 154 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) |
153 | goto set_ea_exit; | 155 | goto set_ea_exit; |
154 | 156 | ||
155 | ea_name += 4; /* skip past os2. prefix */ | 157 | ea_name += 4; /* skip past os2. prefix */ |
156 | rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, | 158 | rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, |
157 | (__u16)value_size, cifs_sb->local_nls); | 159 | (__u16)value_size, cifs_sb->local_nls, |
160 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
158 | } else { | 161 | } else { |
159 | int temp; | 162 | int temp; |
160 | temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, | 163 | temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, |
161 | strlen(POSIX_ACL_XATTR_ACCESS)); | 164 | strlen(POSIX_ACL_XATTR_ACCESS)); |
162 | if (temp == 0) { | 165 | if (temp == 0) { |
163 | #ifdef CONFIG_CIFS_POSIX | 166 | #ifdef CONFIG_CIFS_POSIX |
164 | rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,ea_value, | 167 | if(sb->s_flags & MS_POSIXACL) |
165 | (const int)value_size, ACL_TYPE_ACCESS, | 168 | rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, |
166 | cifs_sb->local_nls); | 169 | ea_value, (const int)value_size, |
170 | ACL_TYPE_ACCESS,cifs_sb->local_nls, | ||
171 | cifs_sb->mnt_cifs_flags & | ||
172 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
167 | cFYI(1,("set POSIX ACL rc %d",rc)); | 173 | cFYI(1,("set POSIX ACL rc %d",rc)); |
168 | #else | 174 | #else |
169 | cFYI(1,("set POSIX ACL not supported")); | 175 | cFYI(1,("set POSIX ACL not supported")); |
170 | #endif | 176 | #endif |
171 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { | 177 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { |
172 | #ifdef CONFIG_CIFS_POSIX | 178 | #ifdef CONFIG_CIFS_POSIX |
173 | rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,ea_value, | 179 | if(sb->s_flags & MS_POSIXACL) |
174 | (const int)value_size, ACL_TYPE_DEFAULT, | 180 | rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, |
175 | cifs_sb->local_nls); | 181 | ea_value, (const int)value_size, |
182 | ACL_TYPE_DEFAULT, cifs_sb->local_nls, | ||
183 | cifs_sb->mnt_cifs_flags & | ||
184 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
176 | cFYI(1,("set POSIX default ACL rc %d",rc)); | 185 | cFYI(1,("set POSIX default ACL rc %d",rc)); |
177 | #else | 186 | #else |
178 | cFYI(1,("set default POSIX ACL not supported")); | 187 | cFYI(1,("set default POSIX ACL not supported")); |
@@ -238,27 +247,35 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, | |||
238 | } /* BB add else when above is implemented */ | 247 | } /* BB add else when above is implemented */ |
239 | ea_name += 5; /* skip past user. prefix */ | 248 | ea_name += 5; /* skip past user. prefix */ |
240 | rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, | 249 | rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, |
241 | buf_size, cifs_sb->local_nls); | 250 | buf_size, cifs_sb->local_nls, |
251 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
242 | } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { | 252 | } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { |
243 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) | 253 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) |
244 | goto get_ea_exit; | 254 | goto get_ea_exit; |
245 | 255 | ||
246 | ea_name += 4; /* skip past os2. prefix */ | 256 | ea_name += 4; /* skip past os2. prefix */ |
247 | rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, | 257 | rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, |
248 | buf_size, cifs_sb->local_nls); | 258 | buf_size, cifs_sb->local_nls, |
259 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
249 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { | 260 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { |
250 | #ifdef CONFIG_CIFS_POSIX | 261 | #ifdef CONFIG_CIFS_POSIX |
251 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, | 262 | if(sb->s_flags & MS_POSIXACL) |
263 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, | ||
252 | ea_value, buf_size, ACL_TYPE_ACCESS, | 264 | ea_value, buf_size, ACL_TYPE_ACCESS, |
253 | cifs_sb->local_nls); | 265 | cifs_sb->local_nls, |
266 | cifs_sb->mnt_cifs_flags & | ||
267 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
254 | #else | 268 | #else |
255 | cFYI(1,("query POSIX ACL not supported yet")); | 269 | cFYI(1,("query POSIX ACL not supported yet")); |
256 | #endif /* CONFIG_CIFS_POSIX */ | 270 | #endif /* CONFIG_CIFS_POSIX */ |
257 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { | 271 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { |
258 | #ifdef CONFIG_CIFS_POSIX | 272 | #ifdef CONFIG_CIFS_POSIX |
259 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, | 273 | if(sb->s_flags & MS_POSIXACL) |
274 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, | ||
260 | ea_value, buf_size, ACL_TYPE_DEFAULT, | 275 | ea_value, buf_size, ACL_TYPE_DEFAULT, |
261 | cifs_sb->local_nls); | 276 | cifs_sb->local_nls, |
277 | cifs_sb->mnt_cifs_flags & | ||
278 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
262 | #else | 279 | #else |
263 | cFYI(1,("query POSIX default ACL not supported yet")); | 280 | cFYI(1,("query POSIX default ACL not supported yet")); |
264 | #endif | 281 | #endif |
@@ -324,7 +341,9 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size) | |||
324 | search server for EAs or streams to | 341 | search server for EAs or streams to |
325 | returns as xattrs */ | 342 | returns as xattrs */ |
326 | rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size, | 343 | rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size, |
327 | cifs_sb->local_nls); | 344 | cifs_sb->local_nls, |
345 | cifs_sb->mnt_cifs_flags & | ||
346 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
328 | 347 | ||
329 | if (full_path) | 348 | if (full_path) |
330 | kfree(full_path); | 349 | kfree(full_path); |
diff --git a/fs/compat.c b/fs/compat.c index 67c0b94d1148..728cd8365384 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -809,7 +809,7 @@ static void *do_smb_super_data_conv(void *raw_data) | |||
809 | 809 | ||
810 | struct compat_nfs_string { | 810 | struct compat_nfs_string { |
811 | compat_uint_t len; | 811 | compat_uint_t len; |
812 | compat_uptr_t __user data; | 812 | compat_uptr_t data; |
813 | }; | 813 | }; |
814 | 814 | ||
815 | static inline void compat_nfs_string(struct nfs_string *dst, | 815 | static inline void compat_nfs_string(struct nfs_string *dst, |
@@ -834,10 +834,10 @@ struct compat_nfs4_mount_data_v1 { | |||
834 | struct compat_nfs_string mnt_path; | 834 | struct compat_nfs_string mnt_path; |
835 | struct compat_nfs_string hostname; | 835 | struct compat_nfs_string hostname; |
836 | compat_uint_t host_addrlen; | 836 | compat_uint_t host_addrlen; |
837 | compat_uptr_t __user host_addr; | 837 | compat_uptr_t host_addr; |
838 | compat_int_t proto; | 838 | compat_int_t proto; |
839 | compat_int_t auth_flavourlen; | 839 | compat_int_t auth_flavourlen; |
840 | compat_uptr_t __user auth_flavours; | 840 | compat_uptr_t auth_flavours; |
841 | }; | 841 | }; |
842 | 842 | ||
843 | static int do_nfs4_super_data_conv(void *raw_data) | 843 | static int do_nfs4_super_data_conv(void *raw_data) |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 040eb288bb1c..ea5888688f94 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -455,12 +455,11 @@ static unsigned long ext3_find_near(struct inode *inode, Indirect *ind) | |||
455 | * @goal: place to store the result. | 455 | * @goal: place to store the result. |
456 | * | 456 | * |
457 | * Normally this function find the prefered place for block allocation, | 457 | * Normally this function find the prefered place for block allocation, |
458 | * stores it in *@goal and returns zero. If the branch had been changed | 458 | * stores it in *@goal and returns zero. |
459 | * under us we return -EAGAIN. | ||
460 | */ | 459 | */ |
461 | 460 | ||
462 | static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4], | 461 | static unsigned long ext3_find_goal(struct inode *inode, long block, |
463 | Indirect *partial, unsigned long *goal) | 462 | Indirect chain[4], Indirect *partial) |
464 | { | 463 | { |
465 | struct ext3_block_alloc_info *block_i = EXT3_I(inode)->i_block_alloc_info; | 464 | struct ext3_block_alloc_info *block_i = EXT3_I(inode)->i_block_alloc_info; |
466 | 465 | ||
@@ -470,15 +469,10 @@ static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4], | |||
470 | */ | 469 | */ |
471 | if (block_i && (block == block_i->last_alloc_logical_block + 1) | 470 | if (block_i && (block == block_i->last_alloc_logical_block + 1) |
472 | && (block_i->last_alloc_physical_block != 0)) { | 471 | && (block_i->last_alloc_physical_block != 0)) { |
473 | *goal = block_i->last_alloc_physical_block + 1; | 472 | return block_i->last_alloc_physical_block + 1; |
474 | return 0; | ||
475 | } | 473 | } |
476 | 474 | ||
477 | if (verify_chain(chain, partial)) { | 475 | return ext3_find_near(inode, partial); |
478 | *goal = ext3_find_near(inode, partial); | ||
479 | return 0; | ||
480 | } | ||
481 | return -EAGAIN; | ||
482 | } | 476 | } |
483 | 477 | ||
484 | /** | 478 | /** |
@@ -582,12 +576,9 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, | |||
582 | * @where: location of missing link | 576 | * @where: location of missing link |
583 | * @num: number of blocks we are adding | 577 | * @num: number of blocks we are adding |
584 | * | 578 | * |
585 | * This function verifies that chain (up to the missing link) had not | 579 | * This function fills the missing link and does all housekeeping needed in |
586 | * changed, fills the missing link and does all housekeeping needed in | ||
587 | * inode (->i_blocks, etc.). In case of success we end up with the full | 580 | * inode (->i_blocks, etc.). In case of success we end up with the full |
588 | * chain to new block and return 0. Otherwise (== chain had been changed) | 581 | * chain to new block and return 0. |
589 | * we free the new blocks (forgetting their buffer_heads, indeed) and | ||
590 | * return -EAGAIN. | ||
591 | */ | 582 | */ |
592 | 583 | ||
593 | static int ext3_splice_branch(handle_t *handle, struct inode *inode, long block, | 584 | static int ext3_splice_branch(handle_t *handle, struct inode *inode, long block, |
@@ -608,12 +599,6 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, long block, | |||
608 | if (err) | 599 | if (err) |
609 | goto err_out; | 600 | goto err_out; |
610 | } | 601 | } |
611 | /* Verify that place we are splicing to is still there and vacant */ | ||
612 | |||
613 | if (!verify_chain(chain, where-1) || *where->p) | ||
614 | /* Writer: end */ | ||
615 | goto changed; | ||
616 | |||
617 | /* That's it */ | 602 | /* That's it */ |
618 | 603 | ||
619 | *where->p = where->key; | 604 | *where->p = where->key; |
@@ -657,26 +642,11 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, long block, | |||
657 | } | 642 | } |
658 | return err; | 643 | return err; |
659 | 644 | ||
660 | changed: | ||
661 | /* | ||
662 | * AKPM: if where[i].bh isn't part of the current updating | ||
663 | * transaction then we explode nastily. Test this code path. | ||
664 | */ | ||
665 | jbd_debug(1, "the chain changed: try again\n"); | ||
666 | err = -EAGAIN; | ||
667 | |||
668 | err_out: | 645 | err_out: |
669 | for (i = 1; i < num; i++) { | 646 | for (i = 1; i < num; i++) { |
670 | BUFFER_TRACE(where[i].bh, "call journal_forget"); | 647 | BUFFER_TRACE(where[i].bh, "call journal_forget"); |
671 | ext3_journal_forget(handle, where[i].bh); | 648 | ext3_journal_forget(handle, where[i].bh); |
672 | } | 649 | } |
673 | /* For the normal collision cleanup case, we free up the blocks. | ||
674 | * On genuine filesystem errors we don't even think about doing | ||
675 | * that. */ | ||
676 | if (err == -EAGAIN) | ||
677 | for (i = 0; i < num; i++) | ||
678 | ext3_free_blocks(handle, inode, | ||
679 | le32_to_cpu(where[i].key), 1); | ||
680 | return err; | 650 | return err; |
681 | } | 651 | } |
682 | 652 | ||
@@ -708,7 +678,7 @@ ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock, | |||
708 | unsigned long goal; | 678 | unsigned long goal; |
709 | int left; | 679 | int left; |
710 | int boundary = 0; | 680 | int boundary = 0; |
711 | int depth = ext3_block_to_path(inode, iblock, offsets, &boundary); | 681 | const int depth = ext3_block_to_path(inode, iblock, offsets, &boundary); |
712 | struct ext3_inode_info *ei = EXT3_I(inode); | 682 | struct ext3_inode_info *ei = EXT3_I(inode); |
713 | 683 | ||
714 | J_ASSERT(handle != NULL || create == 0); | 684 | J_ASSERT(handle != NULL || create == 0); |
@@ -716,54 +686,55 @@ ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock, | |||
716 | if (depth == 0) | 686 | if (depth == 0) |
717 | goto out; | 687 | goto out; |
718 | 688 | ||
719 | reread: | ||
720 | partial = ext3_get_branch(inode, depth, offsets, chain, &err); | 689 | partial = ext3_get_branch(inode, depth, offsets, chain, &err); |
721 | 690 | ||
722 | /* Simplest case - block found, no allocation needed */ | 691 | /* Simplest case - block found, no allocation needed */ |
723 | if (!partial) { | 692 | if (!partial) { |
724 | clear_buffer_new(bh_result); | 693 | clear_buffer_new(bh_result); |
725 | got_it: | 694 | goto got_it; |
726 | map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); | ||
727 | if (boundary) | ||
728 | set_buffer_boundary(bh_result); | ||
729 | /* Clean up and exit */ | ||
730 | partial = chain+depth-1; /* the whole chain */ | ||
731 | goto cleanup; | ||
732 | } | 695 | } |
733 | 696 | ||
734 | /* Next simple case - plain lookup or failed read of indirect block */ | 697 | /* Next simple case - plain lookup or failed read of indirect block */ |
735 | if (!create || err == -EIO) { | 698 | if (!create || err == -EIO) |
736 | cleanup: | 699 | goto cleanup; |
700 | |||
701 | down(&ei->truncate_sem); | ||
702 | |||
703 | /* | ||
704 | * If the indirect block is missing while we are reading | ||
705 | * the chain(ext3_get_branch() returns -EAGAIN err), or | ||
706 | * if the chain has been changed after we grab the semaphore, | ||
707 | * (either because another process truncated this branch, or | ||
708 | * another get_block allocated this branch) re-grab the chain to see if | ||
709 | * the request block has been allocated or not. | ||
710 | * | ||
711 | * Since we already block the truncate/other get_block | ||
712 | * at this point, we will have the current copy of the chain when we | ||
713 | * splice the branch into the tree. | ||
714 | */ | ||
715 | if (err == -EAGAIN || !verify_chain(chain, partial)) { | ||
737 | while (partial > chain) { | 716 | while (partial > chain) { |
738 | BUFFER_TRACE(partial->bh, "call brelse"); | ||
739 | brelse(partial->bh); | 717 | brelse(partial->bh); |
740 | partial--; | 718 | partial--; |
741 | } | 719 | } |
742 | BUFFER_TRACE(bh_result, "returned"); | 720 | partial = ext3_get_branch(inode, depth, offsets, chain, &err); |
743 | out: | 721 | if (!partial) { |
744 | return err; | 722 | up(&ei->truncate_sem); |
723 | if (err) | ||
724 | goto cleanup; | ||
725 | clear_buffer_new(bh_result); | ||
726 | goto got_it; | ||
727 | } | ||
745 | } | 728 | } |
746 | 729 | ||
747 | /* | 730 | /* |
748 | * Indirect block might be removed by truncate while we were | 731 | * Okay, we need to do block allocation. Lazily initialize the block |
749 | * reading it. Handling of that case (forget what we've got and | 732 | * allocation info here if necessary |
750 | * reread) is taken out of the main path. | 733 | */ |
751 | */ | 734 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) |
752 | if (err == -EAGAIN) | ||
753 | goto changed; | ||
754 | |||
755 | goal = 0; | ||
756 | down(&ei->truncate_sem); | ||
757 | |||
758 | /* lazy initialize the block allocation info here if necessary */ | ||
759 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) { | ||
760 | ext3_init_block_alloc_info(inode); | 735 | ext3_init_block_alloc_info(inode); |
761 | } | ||
762 | 736 | ||
763 | if (ext3_find_goal(inode, iblock, chain, partial, &goal) < 0) { | 737 | goal = ext3_find_goal(inode, iblock, chain, partial); |
764 | up(&ei->truncate_sem); | ||
765 | goto changed; | ||
766 | } | ||
767 | 738 | ||
768 | left = (chain + depth) - partial; | 739 | left = (chain + depth) - partial; |
769 | 740 | ||
@@ -771,38 +742,45 @@ out: | |||
771 | * Block out ext3_truncate while we alter the tree | 742 | * Block out ext3_truncate while we alter the tree |
772 | */ | 743 | */ |
773 | err = ext3_alloc_branch(handle, inode, left, goal, | 744 | err = ext3_alloc_branch(handle, inode, left, goal, |
774 | offsets+(partial-chain), partial); | 745 | offsets + (partial - chain), partial); |
775 | 746 | ||
776 | /* The ext3_splice_branch call will free and forget any buffers | 747 | /* |
748 | * The ext3_splice_branch call will free and forget any buffers | ||
777 | * on the new chain if there is a failure, but that risks using | 749 | * on the new chain if there is a failure, but that risks using |
778 | * up transaction credits, especially for bitmaps where the | 750 | * up transaction credits, especially for bitmaps where the |
779 | * credits cannot be returned. Can we handle this somehow? We | 751 | * credits cannot be returned. Can we handle this somehow? We |
780 | * may need to return -EAGAIN upwards in the worst case. --sct */ | 752 | * may need to return -EAGAIN upwards in the worst case. --sct |
753 | */ | ||
781 | if (!err) | 754 | if (!err) |
782 | err = ext3_splice_branch(handle, inode, iblock, chain, | 755 | err = ext3_splice_branch(handle, inode, iblock, chain, |
783 | partial, left); | 756 | partial, left); |
784 | /* i_disksize growing is protected by truncate_sem | 757 | /* |
785 | * don't forget to protect it if you're about to implement | 758 | * i_disksize growing is protected by truncate_sem. Don't forget to |
786 | * concurrent ext3_get_block() -bzzz */ | 759 | * protect it if you're about to implement concurrent |
760 | * ext3_get_block() -bzzz | ||
761 | */ | ||
787 | if (!err && extend_disksize && inode->i_size > ei->i_disksize) | 762 | if (!err && extend_disksize && inode->i_size > ei->i_disksize) |
788 | ei->i_disksize = inode->i_size; | 763 | ei->i_disksize = inode->i_size; |
789 | up(&ei->truncate_sem); | 764 | up(&ei->truncate_sem); |
790 | if (err == -EAGAIN) | ||
791 | goto changed; | ||
792 | if (err) | 765 | if (err) |
793 | goto cleanup; | 766 | goto cleanup; |
794 | 767 | ||
795 | set_buffer_new(bh_result); | 768 | set_buffer_new(bh_result); |
796 | goto got_it; | 769 | got_it: |
797 | 770 | map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); | |
798 | changed: | 771 | if (boundary) |
772 | set_buffer_boundary(bh_result); | ||
773 | /* Clean up and exit */ | ||
774 | partial = chain + depth - 1; /* the whole chain */ | ||
775 | cleanup: | ||
799 | while (partial > chain) { | 776 | while (partial > chain) { |
800 | jbd_debug(1, "buffer chain changed, retrying\n"); | 777 | BUFFER_TRACE(partial->bh, "call brelse"); |
801 | BUFFER_TRACE(partial->bh, "brelsing"); | ||
802 | brelse(partial->bh); | 778 | brelse(partial->bh); |
803 | partial--; | 779 | partial--; |
804 | } | 780 | } |
805 | goto reread; | 781 | BUFFER_TRACE(bh_result, "returned"); |
782 | out: | ||
783 | return err; | ||
806 | } | 784 | } |
807 | 785 | ||
808 | static int ext3_get_block(struct inode *inode, sector_t iblock, | 786 | static int ext3_get_block(struct inode *inode, sector_t iblock, |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 3e7ab16ed154..286a9f8f3d49 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/security.h> | 16 | #include <linux/security.h> |
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/signal.h> | ||
18 | 19 | ||
19 | #include <asm/poll.h> | 20 | #include <asm/poll.h> |
20 | #include <asm/siginfo.h> | 21 | #include <asm/siginfo.h> |
@@ -308,7 +309,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | |||
308 | break; | 309 | break; |
309 | case F_SETSIG: | 310 | case F_SETSIG: |
310 | /* arg == 0 restores default behaviour. */ | 311 | /* arg == 0 restores default behaviour. */ |
311 | if (arg < 0 || arg > _NSIG) { | 312 | if (!valid_signal(arg)) { |
312 | break; | 313 | break; |
313 | } | 314 | } |
314 | err = 0; | 315 | err = 0; |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index d6efb36cab2a..8e050fa58218 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -512,7 +512,8 @@ restart: | |||
512 | } | 512 | } |
513 | 513 | ||
514 | /** | 514 | /** |
515 | * sync_inodes | 515 | * sync_inodes - writes all inodes to disk |
516 | * @wait: wait for completion | ||
516 | * | 517 | * |
517 | * sync_inodes() goes through each super block's dirty inode list, writes the | 518 | * sync_inodes() goes through each super block's dirty inode list, writes the |
518 | * inodes out, waits on the writeout and puts the inodes back on the normal | 519 | * inodes out, waits on the writeout and puts the inodes back on the normal |
@@ -604,6 +605,7 @@ EXPORT_SYMBOL(sync_inode); | |||
604 | /** | 605 | /** |
605 | * generic_osync_inode - flush all dirty data for a given inode to disk | 606 | * generic_osync_inode - flush all dirty data for a given inode to disk |
606 | * @inode: inode to write | 607 | * @inode: inode to write |
608 | * @mapping: the address_space that should be flushed | ||
607 | * @what: what to write and wait upon | 609 | * @what: what to write and wait upon |
608 | * | 610 | * |
609 | * This can be called by file_write functions for files which have the | 611 | * This can be called by file_write functions for files which have the |
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 4efb640c4d0c..217e32f37e0b 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c | |||
@@ -333,6 +333,8 @@ void hfs_mdb_close(struct super_block *sb) | |||
333 | * Release the resources associated with the in-core MDB. */ | 333 | * Release the resources associated with the in-core MDB. */ |
334 | void hfs_mdb_put(struct super_block *sb) | 334 | void hfs_mdb_put(struct super_block *sb) |
335 | { | 335 | { |
336 | if (!HFS_SB(sb)) | ||
337 | return; | ||
336 | /* free the B-trees */ | 338 | /* free the B-trees */ |
337 | hfs_btree_close(HFS_SB(sb)->ext_tree); | 339 | hfs_btree_close(HFS_SB(sb)->ext_tree); |
338 | hfs_btree_close(HFS_SB(sb)->cat_tree); | 340 | hfs_btree_close(HFS_SB(sb)->cat_tree); |
@@ -340,4 +342,7 @@ void hfs_mdb_put(struct super_block *sb) | |||
340 | /* free the buffers holding the primary and alternate MDBs */ | 342 | /* free the buffers holding the primary and alternate MDBs */ |
341 | brelse(HFS_SB(sb)->mdb_bh); | 343 | brelse(HFS_SB(sb)->mdb_bh); |
342 | brelse(HFS_SB(sb)->alt_mdb_bh); | 344 | brelse(HFS_SB(sb)->alt_mdb_bh); |
345 | |||
346 | kfree(HFS_SB(sb)); | ||
347 | sb->s_fs_info = NULL; | ||
343 | } | 348 | } |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 1e2c193134cc..ab783f6afa3b 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -297,7 +297,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
297 | res = -EINVAL; | 297 | res = -EINVAL; |
298 | if (!parse_options((char *)data, sbi)) { | 298 | if (!parse_options((char *)data, sbi)) { |
299 | hfs_warn("hfs_fs: unable to parse mount options.\n"); | 299 | hfs_warn("hfs_fs: unable to parse mount options.\n"); |
300 | goto bail3; | 300 | goto bail; |
301 | } | 301 | } |
302 | 302 | ||
303 | sb->s_op = &hfs_super_operations; | 303 | sb->s_op = &hfs_super_operations; |
@@ -310,7 +310,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
310 | hfs_warn("VFS: Can't find a HFS filesystem on dev %s.\n", | 310 | hfs_warn("VFS: Can't find a HFS filesystem on dev %s.\n", |
311 | hfs_mdb_name(sb)); | 311 | hfs_mdb_name(sb)); |
312 | res = -EINVAL; | 312 | res = -EINVAL; |
313 | goto bail2; | 313 | goto bail; |
314 | } | 314 | } |
315 | 315 | ||
316 | /* try to get the root inode */ | 316 | /* try to get the root inode */ |
@@ -340,10 +340,8 @@ bail_iput: | |||
340 | iput(root_inode); | 340 | iput(root_inode); |
341 | bail_no_root: | 341 | bail_no_root: |
342 | hfs_warn("hfs_fs: get root inode failed.\n"); | 342 | hfs_warn("hfs_fs: get root inode failed.\n"); |
343 | bail: | ||
343 | hfs_mdb_put(sb); | 344 | hfs_mdb_put(sb); |
344 | bail2: | ||
345 | bail3: | ||
346 | kfree(sbi); | ||
347 | return res; | 345 | return res; |
348 | } | 346 | } |
349 | 347 | ||
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 5f8044664a3c..d55ad67b8e42 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -208,7 +208,9 @@ static void hfsplus_write_super(struct super_block *sb) | |||
208 | static void hfsplus_put_super(struct super_block *sb) | 208 | static void hfsplus_put_super(struct super_block *sb) |
209 | { | 209 | { |
210 | dprint(DBG_SUPER, "hfsplus_put_super\n"); | 210 | dprint(DBG_SUPER, "hfsplus_put_super\n"); |
211 | if (!(sb->s_flags & MS_RDONLY)) { | 211 | if (!sb->s_fs_info) |
212 | return; | ||
213 | if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) { | ||
212 | struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; | 214 | struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; |
213 | 215 | ||
214 | vhdr->modify_date = hfsp_now2mt(); | 216 | vhdr->modify_date = hfsp_now2mt(); |
@@ -226,6 +228,8 @@ static void hfsplus_put_super(struct super_block *sb) | |||
226 | brelse(HFSPLUS_SB(sb).s_vhbh); | 228 | brelse(HFSPLUS_SB(sb).s_vhbh); |
227 | if (HFSPLUS_SB(sb).nls) | 229 | if (HFSPLUS_SB(sb).nls) |
228 | unload_nls(HFSPLUS_SB(sb).nls); | 230 | unload_nls(HFSPLUS_SB(sb).nls); |
231 | kfree(sb->s_fs_info); | ||
232 | sb->s_fs_info = NULL; | ||
229 | } | 233 | } |
230 | 234 | ||
231 | static int hfsplus_statfs(struct super_block *sb, struct kstatfs *buf) | 235 | static int hfsplus_statfs(struct super_block *sb, struct kstatfs *buf) |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index a88ad2924851..e6c63d9cac7b 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -521,7 +521,7 @@ int hostfs_commit_write(struct file *file, struct page *page, unsigned from, | |||
521 | static struct address_space_operations hostfs_aops = { | 521 | static struct address_space_operations hostfs_aops = { |
522 | .writepage = hostfs_writepage, | 522 | .writepage = hostfs_writepage, |
523 | .readpage = hostfs_readpage, | 523 | .readpage = hostfs_readpage, |
524 | /* .set_page_dirty = __set_page_dirty_nobuffers, */ | 524 | .set_page_dirty = __set_page_dirty_nobuffers, |
525 | .prepare_write = hostfs_prepare_write, | 525 | .prepare_write = hostfs_prepare_write, |
526 | .commit_write = hostfs_commit_write | 526 | .commit_write = hostfs_commit_write |
527 | }; | 527 | }; |
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 0c607c1388f4..771a554701d6 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
@@ -79,8 +79,7 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) | |||
79 | 79 | ||
80 | D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT)); | 80 | D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT)); |
81 | 81 | ||
82 | if (!PageLocked(pg)) | 82 | BUG_ON(!PageLocked(pg)); |
83 | PAGE_BUG(pg); | ||
84 | 83 | ||
85 | pg_buf = kmap(pg); | 84 | pg_buf = kmap(pg); |
86 | /* FIXME: Can kmap fail? */ | 85 | /* FIXME: Can kmap fail? */ |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 7bc906677b0d..24a689179af2 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -175,31 +175,22 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | |||
175 | { | 175 | { |
176 | s64 lblock64 = lblock; | 176 | s64 lblock64 = lblock; |
177 | int rc = 0; | 177 | int rc = 0; |
178 | int take_locks; | ||
179 | xad_t xad; | 178 | xad_t xad; |
180 | s64 xaddr; | 179 | s64 xaddr; |
181 | int xflag; | 180 | int xflag; |
182 | s32 xlen; | 181 | s32 xlen = max_blocks; |
183 | |||
184 | /* | ||
185 | * If this is a special inode (imap, dmap) | ||
186 | * the lock should already be taken | ||
187 | */ | ||
188 | take_locks = (JFS_IP(ip)->fileset != AGGREGATE_I); | ||
189 | 182 | ||
190 | /* | 183 | /* |
191 | * Take appropriate lock on inode | 184 | * Take appropriate lock on inode |
192 | */ | 185 | */ |
193 | if (take_locks) { | 186 | if (create) |
194 | if (create) | 187 | IWRITE_LOCK(ip); |
195 | IWRITE_LOCK(ip); | 188 | else |
196 | else | 189 | IREAD_LOCK(ip); |
197 | IREAD_LOCK(ip); | ||
198 | } | ||
199 | 190 | ||
200 | if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && | 191 | if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && |
201 | (xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0) | 192 | (!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) && |
202 | == 0) && xlen) { | 193 | xaddr) { |
203 | if (xflag & XAD_NOTRECORDED) { | 194 | if (xflag & XAD_NOTRECORDED) { |
204 | if (!create) | 195 | if (!create) |
205 | /* | 196 | /* |
@@ -238,7 +229,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | |||
238 | #ifdef _JFS_4K | 229 | #ifdef _JFS_4K |
239 | if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) | 230 | if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) |
240 | goto unlock; | 231 | goto unlock; |
241 | rc = extAlloc(ip, max_blocks, lblock64, &xad, FALSE); | 232 | rc = extAlloc(ip, xlen, lblock64, &xad, FALSE); |
242 | if (rc) | 233 | if (rc) |
243 | goto unlock; | 234 | goto unlock; |
244 | 235 | ||
@@ -258,12 +249,10 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | |||
258 | /* | 249 | /* |
259 | * Release lock on inode | 250 | * Release lock on inode |
260 | */ | 251 | */ |
261 | if (take_locks) { | 252 | if (create) |
262 | if (create) | 253 | IWRITE_UNLOCK(ip); |
263 | IWRITE_UNLOCK(ip); | 254 | else |
264 | else | 255 | IREAD_UNLOCK(ip); |
265 | IREAD_UNLOCK(ip); | ||
266 | } | ||
267 | return rc; | 256 | return rc; |
268 | } | 257 | } |
269 | 258 | ||
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index d86e467c6e42..69007fd546ef 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c | |||
@@ -471,6 +471,7 @@ dbUpdatePMap(struct inode *ipbmap, | |||
471 | struct metapage *mp; | 471 | struct metapage *mp; |
472 | struct jfs_log *log; | 472 | struct jfs_log *log; |
473 | int lsn, difft, diffp; | 473 | int lsn, difft, diffp; |
474 | unsigned long flags; | ||
474 | 475 | ||
475 | /* the blocks better be within the mapsize. */ | 476 | /* the blocks better be within the mapsize. */ |
476 | if (blkno + nblocks > bmp->db_mapsize) { | 477 | if (blkno + nblocks > bmp->db_mapsize) { |
@@ -504,6 +505,7 @@ dbUpdatePMap(struct inode *ipbmap, | |||
504 | 0); | 505 | 0); |
505 | if (mp == NULL) | 506 | if (mp == NULL) |
506 | return -EIO; | 507 | return -EIO; |
508 | metapage_wait_for_io(mp); | ||
507 | } | 509 | } |
508 | dp = (struct dmap *) mp->data; | 510 | dp = (struct dmap *) mp->data; |
509 | 511 | ||
@@ -578,34 +580,32 @@ dbUpdatePMap(struct inode *ipbmap, | |||
578 | if (mp->lsn != 0) { | 580 | if (mp->lsn != 0) { |
579 | /* inherit older/smaller lsn */ | 581 | /* inherit older/smaller lsn */ |
580 | logdiff(diffp, mp->lsn, log); | 582 | logdiff(diffp, mp->lsn, log); |
583 | LOGSYNC_LOCK(log, flags); | ||
581 | if (difft < diffp) { | 584 | if (difft < diffp) { |
582 | mp->lsn = lsn; | 585 | mp->lsn = lsn; |
583 | 586 | ||
584 | /* move bp after tblock in logsync list */ | 587 | /* move bp after tblock in logsync list */ |
585 | LOGSYNC_LOCK(log); | ||
586 | list_move(&mp->synclist, &tblk->synclist); | 588 | list_move(&mp->synclist, &tblk->synclist); |
587 | LOGSYNC_UNLOCK(log); | ||
588 | } | 589 | } |
589 | 590 | ||
590 | /* inherit younger/larger clsn */ | 591 | /* inherit younger/larger clsn */ |
591 | LOGSYNC_LOCK(log); | ||
592 | logdiff(difft, tblk->clsn, log); | 592 | logdiff(difft, tblk->clsn, log); |
593 | logdiff(diffp, mp->clsn, log); | 593 | logdiff(diffp, mp->clsn, log); |
594 | if (difft > diffp) | 594 | if (difft > diffp) |
595 | mp->clsn = tblk->clsn; | 595 | mp->clsn = tblk->clsn; |
596 | LOGSYNC_UNLOCK(log); | 596 | LOGSYNC_UNLOCK(log, flags); |
597 | } else { | 597 | } else { |
598 | mp->log = log; | 598 | mp->log = log; |
599 | mp->lsn = lsn; | 599 | mp->lsn = lsn; |
600 | 600 | ||
601 | /* insert bp after tblock in logsync list */ | 601 | /* insert bp after tblock in logsync list */ |
602 | LOGSYNC_LOCK(log); | 602 | LOGSYNC_LOCK(log, flags); |
603 | 603 | ||
604 | log->count++; | 604 | log->count++; |
605 | list_add(&mp->synclist, &tblk->synclist); | 605 | list_add(&mp->synclist, &tblk->synclist); |
606 | 606 | ||
607 | mp->clsn = tblk->clsn; | 607 | mp->clsn = tblk->clsn; |
608 | LOGSYNC_UNLOCK(log); | 608 | LOGSYNC_UNLOCK(log, flags); |
609 | } | 609 | } |
610 | } | 610 | } |
611 | 611 | ||
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index e357890adfb2..ac41f72d6d50 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c | |||
@@ -212,7 +212,7 @@ static struct metapage *read_index_page(struct inode *inode, s64 blkno) | |||
212 | s32 xlen; | 212 | s32 xlen; |
213 | 213 | ||
214 | rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); | 214 | rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); |
215 | if (rc || (xlen == 0)) | 215 | if (rc || (xaddr == 0)) |
216 | return NULL; | 216 | return NULL; |
217 | 217 | ||
218 | return read_metapage(inode, xaddr, PSIZE, 1); | 218 | return read_metapage(inode, xaddr, PSIZE, 1); |
@@ -231,7 +231,7 @@ static struct metapage *get_index_page(struct inode *inode, s64 blkno) | |||
231 | s32 xlen; | 231 | s32 xlen; |
232 | 232 | ||
233 | rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); | 233 | rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); |
234 | if (rc || (xlen == 0)) | 234 | if (rc || (xaddr == 0)) |
235 | return NULL; | 235 | return NULL; |
236 | 236 | ||
237 | return get_metapage(inode, xaddr, PSIZE, 1); | 237 | return get_metapage(inode, xaddr, PSIZE, 1); |
@@ -3181,7 +3181,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
3181 | d = (struct ldtentry *) & p->slot[stbl[i]]; | 3181 | d = (struct ldtentry *) & p->slot[stbl[i]]; |
3182 | 3182 | ||
3183 | if (((long) jfs_dirent + d->namlen + 1) > | 3183 | if (((long) jfs_dirent + d->namlen + 1) > |
3184 | (dirent_buf + PSIZE)) { | 3184 | (dirent_buf + PAGE_SIZE)) { |
3185 | /* DBCS codepages could overrun dirent_buf */ | 3185 | /* DBCS codepages could overrun dirent_buf */ |
3186 | index = i; | 3186 | index = i; |
3187 | overflow = 1; | 3187 | overflow = 1; |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 783831301625..7acff2ce3c80 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -502,7 +502,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) | |||
502 | 502 | ||
503 | } | 503 | } |
504 | 504 | ||
505 | ip->i_mapping->a_ops = &jfs_aops; | 505 | ip->i_mapping->a_ops = &jfs_metapage_aops; |
506 | mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS); | 506 | mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS); |
507 | 507 | ||
508 | /* Allocations to metadata inodes should not affect quotas */ | 508 | /* Allocations to metadata inodes should not affect quotas */ |
@@ -2573,9 +2573,18 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) | |||
2573 | goto out; | 2573 | goto out; |
2574 | } | 2574 | } |
2575 | 2575 | ||
2576 | /* assign a buffer for the page */ | 2576 | /* |
2577 | mp = get_metapage(ipimap, xaddr, PSIZE, 1); | 2577 | * start transaction of update of the inode map |
2578 | if (!mp) { | 2578 | * addressing structure pointing to the new iag page; |
2579 | */ | ||
2580 | tid = txBegin(sb, COMMIT_FORCE); | ||
2581 | down(&JFS_IP(ipimap)->commit_sem); | ||
2582 | |||
2583 | /* update the inode map addressing structure to point to it */ | ||
2584 | if ((rc = | ||
2585 | xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { | ||
2586 | txEnd(tid); | ||
2587 | up(&JFS_IP(ipimap)->commit_sem); | ||
2579 | /* Free the blocks allocated for the iag since it was | 2588 | /* Free the blocks allocated for the iag since it was |
2580 | * not successfully added to the inode map | 2589 | * not successfully added to the inode map |
2581 | */ | 2590 | */ |
@@ -2584,6 +2593,29 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) | |||
2584 | /* release the inode map lock */ | 2593 | /* release the inode map lock */ |
2585 | IWRITE_UNLOCK(ipimap); | 2594 | IWRITE_UNLOCK(ipimap); |
2586 | 2595 | ||
2596 | goto out; | ||
2597 | } | ||
2598 | |||
2599 | /* update the inode map's inode to reflect the extension */ | ||
2600 | ipimap->i_size += PSIZE; | ||
2601 | inode_add_bytes(ipimap, PSIZE); | ||
2602 | |||
2603 | /* assign a buffer for the page */ | ||
2604 | mp = get_metapage(ipimap, blkno, PSIZE, 0); | ||
2605 | if (!mp) { | ||
2606 | /* | ||
2607 | * This is very unlikely since we just created the | ||
2608 | * extent, but let's try to handle it correctly | ||
2609 | */ | ||
2610 | xtTruncate(tid, ipimap, ipimap->i_size - PSIZE, | ||
2611 | COMMIT_PWMAP); | ||
2612 | |||
2613 | txAbort(tid, 0); | ||
2614 | txEnd(tid); | ||
2615 | |||
2616 | /* release the inode map lock */ | ||
2617 | IWRITE_UNLOCK(ipimap); | ||
2618 | |||
2587 | rc = -EIO; | 2619 | rc = -EIO; |
2588 | goto out; | 2620 | goto out; |
2589 | } | 2621 | } |
@@ -2605,41 +2637,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) | |||
2605 | iagp->inosmap[i] = cpu_to_le32(ONES); | 2637 | iagp->inosmap[i] = cpu_to_le32(ONES); |
2606 | 2638 | ||
2607 | /* | 2639 | /* |
2608 | * Invalidate the page after writing and syncing it. | 2640 | * Write and sync the metapage |
2609 | * After it's initialized, we access it in a different | ||
2610 | * address space | ||
2611 | */ | 2641 | */ |
2612 | set_bit(META_discard, &mp->flag); | ||
2613 | flush_metapage(mp); | 2642 | flush_metapage(mp); |
2614 | 2643 | ||
2615 | /* | 2644 | /* |
2616 | * start tyransaction of update of the inode map | ||
2617 | * addressing structure pointing to the new iag page; | ||
2618 | */ | ||
2619 | tid = txBegin(sb, COMMIT_FORCE); | ||
2620 | down(&JFS_IP(ipimap)->commit_sem); | ||
2621 | |||
2622 | /* update the inode map addressing structure to point to it */ | ||
2623 | if ((rc = | ||
2624 | xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { | ||
2625 | txEnd(tid); | ||
2626 | up(&JFS_IP(ipimap)->commit_sem); | ||
2627 | /* Free the blocks allocated for the iag since it was | ||
2628 | * not successfully added to the inode map | ||
2629 | */ | ||
2630 | dbFree(ipimap, xaddr, (s64) xlen); | ||
2631 | |||
2632 | /* release the inode map lock */ | ||
2633 | IWRITE_UNLOCK(ipimap); | ||
2634 | |||
2635 | goto out; | ||
2636 | } | ||
2637 | |||
2638 | /* update the inode map's inode to reflect the extension */ | ||
2639 | ipimap->i_size += PSIZE; | ||
2640 | inode_add_bytes(ipimap, PSIZE); | ||
2641 | |||
2642 | /* | ||
2643 | * txCommit(COMMIT_FORCE) will synchronously write address | 2645 | * txCommit(COMMIT_FORCE) will synchronously write address |
2644 | * index pages and inode after commit in careful update order | 2646 | * index pages and inode after commit in careful update order |
2645 | * of address index pages (right to left, bottom up); | 2647 | * of address index pages (right to left, bottom up); |
@@ -2789,6 +2791,7 @@ diUpdatePMap(struct inode *ipimap, | |||
2789 | u32 mask; | 2791 | u32 mask; |
2790 | struct jfs_log *log; | 2792 | struct jfs_log *log; |
2791 | int lsn, difft, diffp; | 2793 | int lsn, difft, diffp; |
2794 | unsigned long flags; | ||
2792 | 2795 | ||
2793 | imap = JFS_IP(ipimap)->i_imap; | 2796 | imap = JFS_IP(ipimap)->i_imap; |
2794 | /* get the iag number containing the inode */ | 2797 | /* get the iag number containing the inode */ |
@@ -2805,6 +2808,7 @@ diUpdatePMap(struct inode *ipimap, | |||
2805 | IREAD_UNLOCK(ipimap); | 2808 | IREAD_UNLOCK(ipimap); |
2806 | if (rc) | 2809 | if (rc) |
2807 | return (rc); | 2810 | return (rc); |
2811 | metapage_wait_for_io(mp); | ||
2808 | iagp = (struct iag *) mp->data; | 2812 | iagp = (struct iag *) mp->data; |
2809 | /* get the inode number and extent number of the inode within | 2813 | /* get the inode number and extent number of the inode within |
2810 | * the iag and the inode number within the extent. | 2814 | * the iag and the inode number within the extent. |
@@ -2868,30 +2872,28 @@ diUpdatePMap(struct inode *ipimap, | |||
2868 | /* inherit older/smaller lsn */ | 2872 | /* inherit older/smaller lsn */ |
2869 | logdiff(difft, lsn, log); | 2873 | logdiff(difft, lsn, log); |
2870 | logdiff(diffp, mp->lsn, log); | 2874 | logdiff(diffp, mp->lsn, log); |
2875 | LOGSYNC_LOCK(log, flags); | ||
2871 | if (difft < diffp) { | 2876 | if (difft < diffp) { |
2872 | mp->lsn = lsn; | 2877 | mp->lsn = lsn; |
2873 | /* move mp after tblock in logsync list */ | 2878 | /* move mp after tblock in logsync list */ |
2874 | LOGSYNC_LOCK(log); | ||
2875 | list_move(&mp->synclist, &tblk->synclist); | 2879 | list_move(&mp->synclist, &tblk->synclist); |
2876 | LOGSYNC_UNLOCK(log); | ||
2877 | } | 2880 | } |
2878 | /* inherit younger/larger clsn */ | 2881 | /* inherit younger/larger clsn */ |
2879 | LOGSYNC_LOCK(log); | ||
2880 | assert(mp->clsn); | 2882 | assert(mp->clsn); |
2881 | logdiff(difft, tblk->clsn, log); | 2883 | logdiff(difft, tblk->clsn, log); |
2882 | logdiff(diffp, mp->clsn, log); | 2884 | logdiff(diffp, mp->clsn, log); |
2883 | if (difft > diffp) | 2885 | if (difft > diffp) |
2884 | mp->clsn = tblk->clsn; | 2886 | mp->clsn = tblk->clsn; |
2885 | LOGSYNC_UNLOCK(log); | 2887 | LOGSYNC_UNLOCK(log, flags); |
2886 | } else { | 2888 | } else { |
2887 | mp->log = log; | 2889 | mp->log = log; |
2888 | mp->lsn = lsn; | 2890 | mp->lsn = lsn; |
2889 | /* insert mp after tblock in logsync list */ | 2891 | /* insert mp after tblock in logsync list */ |
2890 | LOGSYNC_LOCK(log); | 2892 | LOGSYNC_LOCK(log, flags); |
2891 | log->count++; | 2893 | log->count++; |
2892 | list_add(&mp->synclist, &tblk->synclist); | 2894 | list_add(&mp->synclist, &tblk->synclist); |
2893 | mp->clsn = tblk->clsn; | 2895 | mp->clsn = tblk->clsn; |
2894 | LOGSYNC_UNLOCK(log); | 2896 | LOGSYNC_UNLOCK(log, flags); |
2895 | } | 2897 | } |
2896 | write_metapage(mp); | 2898 | write_metapage(mp); |
2897 | return (0); | 2899 | return (0); |
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index ebd77c1bed66..c0fd7b3eadc6 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h | |||
@@ -165,6 +165,7 @@ struct jfs_sb_info { | |||
165 | /* Formerly in ipbmap */ | 165 | /* Formerly in ipbmap */ |
166 | struct bmap *bmap; /* incore bmap descriptor */ | 166 | struct bmap *bmap; /* incore bmap descriptor */ |
167 | struct nls_table *nls_tab; /* current codepage */ | 167 | struct nls_table *nls_tab; /* current codepage */ |
168 | struct inode *direct_inode; /* metadata inode */ | ||
168 | uint state; /* mount/recovery state */ | 169 | uint state; /* mount/recovery state */ |
169 | unsigned long flag; /* mount time flags */ | 170 | unsigned long flag; /* mount time flags */ |
170 | uint p_state; /* state prior to going no integrity */ | 171 | uint p_state; /* state prior to going no integrity */ |
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index b6a6869ebb4f..dfa1200daa61 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -234,6 +234,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
234 | int lsn; | 234 | int lsn; |
235 | int diffp, difft; | 235 | int diffp, difft; |
236 | struct metapage *mp = NULL; | 236 | struct metapage *mp = NULL; |
237 | unsigned long flags; | ||
237 | 238 | ||
238 | jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p", | 239 | jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p", |
239 | log, tblk, lrd, tlck); | 240 | log, tblk, lrd, tlck); |
@@ -254,7 +255,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
254 | */ | 255 | */ |
255 | lsn = log->lsn; | 256 | lsn = log->lsn; |
256 | 257 | ||
257 | LOGSYNC_LOCK(log); | 258 | LOGSYNC_LOCK(log, flags); |
258 | 259 | ||
259 | /* | 260 | /* |
260 | * initialize page lsn if first log write of the page | 261 | * initialize page lsn if first log write of the page |
@@ -310,7 +311,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
310 | } | 311 | } |
311 | } | 312 | } |
312 | 313 | ||
313 | LOGSYNC_UNLOCK(log); | 314 | LOGSYNC_UNLOCK(log, flags); |
314 | 315 | ||
315 | /* | 316 | /* |
316 | * write the log record | 317 | * write the log record |
@@ -334,7 +335,6 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
334 | return lsn; | 335 | return lsn; |
335 | } | 336 | } |
336 | 337 | ||
337 | |||
338 | /* | 338 | /* |
339 | * NAME: lmWriteRecord() | 339 | * NAME: lmWriteRecord() |
340 | * | 340 | * |
@@ -927,9 +927,8 @@ static void lmPostGC(struct lbuf * bp) | |||
927 | * calculate new value of i_nextsync which determines when | 927 | * calculate new value of i_nextsync which determines when |
928 | * this code is called again. | 928 | * this code is called again. |
929 | * | 929 | * |
930 | * this is called only from lmLog(). | 930 | * PARAMETERS: log - log structure |
931 | * | 931 | * nosyncwait - 1 if called asynchronously |
932 | * PARAMETER: ip - pointer to logs inode. | ||
933 | * | 932 | * |
934 | * RETURN: 0 | 933 | * RETURN: 0 |
935 | * | 934 | * |
@@ -945,6 +944,15 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
945 | struct lrd lrd; | 944 | struct lrd lrd; |
946 | int lsn; | 945 | int lsn; |
947 | struct logsyncblk *lp; | 946 | struct logsyncblk *lp; |
947 | struct jfs_sb_info *sbi; | ||
948 | unsigned long flags; | ||
949 | |||
950 | /* push dirty metapages out to disk */ | ||
951 | list_for_each_entry(sbi, &log->sb_list, log_list) { | ||
952 | filemap_flush(sbi->ipbmap->i_mapping); | ||
953 | filemap_flush(sbi->ipimap->i_mapping); | ||
954 | filemap_flush(sbi->direct_inode->i_mapping); | ||
955 | } | ||
948 | 956 | ||
949 | /* | 957 | /* |
950 | * forward syncpt | 958 | * forward syncpt |
@@ -954,10 +962,7 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
954 | */ | 962 | */ |
955 | 963 | ||
956 | if (log->sync == log->syncpt) { | 964 | if (log->sync == log->syncpt) { |
957 | LOGSYNC_LOCK(log); | 965 | LOGSYNC_LOCK(log, flags); |
958 | /* ToDo: push dirty metapages out to disk */ | ||
959 | // bmLogSync(log); | ||
960 | |||
961 | if (list_empty(&log->synclist)) | 966 | if (list_empty(&log->synclist)) |
962 | log->sync = log->lsn; | 967 | log->sync = log->lsn; |
963 | else { | 968 | else { |
@@ -965,7 +970,7 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
965 | struct logsyncblk, synclist); | 970 | struct logsyncblk, synclist); |
966 | log->sync = lp->lsn; | 971 | log->sync = lp->lsn; |
967 | } | 972 | } |
968 | LOGSYNC_UNLOCK(log); | 973 | LOGSYNC_UNLOCK(log, flags); |
969 | 974 | ||
970 | } | 975 | } |
971 | 976 | ||
@@ -974,27 +979,6 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
974 | * reset syncpt = sync | 979 | * reset syncpt = sync |
975 | */ | 980 | */ |
976 | if (log->sync != log->syncpt) { | 981 | if (log->sync != log->syncpt) { |
977 | struct jfs_sb_info *sbi; | ||
978 | |||
979 | /* | ||
980 | * We need to make sure all of the "written" metapages | ||
981 | * actually make it to disk | ||
982 | */ | ||
983 | list_for_each_entry(sbi, &log->sb_list, log_list) { | ||
984 | if (sbi->flag & JFS_NOINTEGRITY) | ||
985 | continue; | ||
986 | filemap_fdatawrite(sbi->ipbmap->i_mapping); | ||
987 | filemap_fdatawrite(sbi->ipimap->i_mapping); | ||
988 | filemap_fdatawrite(sbi->sb->s_bdev->bd_inode->i_mapping); | ||
989 | } | ||
990 | list_for_each_entry(sbi, &log->sb_list, log_list) { | ||
991 | if (sbi->flag & JFS_NOINTEGRITY) | ||
992 | continue; | ||
993 | filemap_fdatawait(sbi->ipbmap->i_mapping); | ||
994 | filemap_fdatawait(sbi->ipimap->i_mapping); | ||
995 | filemap_fdatawait(sbi->sb->s_bdev->bd_inode->i_mapping); | ||
996 | } | ||
997 | |||
998 | lrd.logtid = 0; | 982 | lrd.logtid = 0; |
999 | lrd.backchain = 0; | 983 | lrd.backchain = 0; |
1000 | lrd.type = cpu_to_le16(LOG_SYNCPT); | 984 | lrd.type = cpu_to_le16(LOG_SYNCPT); |
@@ -1066,6 +1050,18 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
1066 | return lsn; | 1050 | return lsn; |
1067 | } | 1051 | } |
1068 | 1052 | ||
1053 | /* | ||
1054 | * NAME: jfs_syncpt | ||
1055 | * | ||
1056 | * FUNCTION: write log SYNCPT record for specified log | ||
1057 | * | ||
1058 | * PARAMETERS: log - log structure | ||
1059 | */ | ||
1060 | void jfs_syncpt(struct jfs_log *log) | ||
1061 | { LOG_LOCK(log); | ||
1062 | lmLogSync(log, 1); | ||
1063 | LOG_UNLOCK(log); | ||
1064 | } | ||
1069 | 1065 | ||
1070 | /* | 1066 | /* |
1071 | * NAME: lmLogOpen() | 1067 | * NAME: lmLogOpen() |
@@ -1547,6 +1543,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait) | |||
1547 | { | 1543 | { |
1548 | int i; | 1544 | int i; |
1549 | struct tblock *target = NULL; | 1545 | struct tblock *target = NULL; |
1546 | struct jfs_sb_info *sbi; | ||
1550 | 1547 | ||
1551 | /* jfs_write_inode may call us during read-only mount */ | 1548 | /* jfs_write_inode may call us during read-only mount */ |
1552 | if (!log) | 1549 | if (!log) |
@@ -1608,12 +1605,18 @@ void jfs_flush_journal(struct jfs_log *log, int wait) | |||
1608 | if (wait < 2) | 1605 | if (wait < 2) |
1609 | return; | 1606 | return; |
1610 | 1607 | ||
1608 | list_for_each_entry(sbi, &log->sb_list, log_list) { | ||
1609 | filemap_fdatawrite(sbi->ipbmap->i_mapping); | ||
1610 | filemap_fdatawrite(sbi->ipimap->i_mapping); | ||
1611 | filemap_fdatawrite(sbi->direct_inode->i_mapping); | ||
1612 | } | ||
1613 | |||
1611 | /* | 1614 | /* |
1612 | * If there was recent activity, we may need to wait | 1615 | * If there was recent activity, we may need to wait |
1613 | * for the lazycommit thread to catch up | 1616 | * for the lazycommit thread to catch up |
1614 | */ | 1617 | */ |
1615 | if ((!list_empty(&log->cqueue)) || !list_empty(&log->synclist)) { | 1618 | if ((!list_empty(&log->cqueue)) || !list_empty(&log->synclist)) { |
1616 | for (i = 0; i < 800; i++) { /* Too much? */ | 1619 | for (i = 0; i < 200; i++) { /* Too much? */ |
1617 | msleep(250); | 1620 | msleep(250); |
1618 | if (list_empty(&log->cqueue) && | 1621 | if (list_empty(&log->cqueue) && |
1619 | list_empty(&log->synclist)) | 1622 | list_empty(&log->synclist)) |
@@ -1621,7 +1624,24 @@ void jfs_flush_journal(struct jfs_log *log, int wait) | |||
1621 | } | 1624 | } |
1622 | } | 1625 | } |
1623 | assert(list_empty(&log->cqueue)); | 1626 | assert(list_empty(&log->cqueue)); |
1624 | assert(list_empty(&log->synclist)); | 1627 | if (!list_empty(&log->synclist)) { |
1628 | struct logsyncblk *lp; | ||
1629 | |||
1630 | list_for_each_entry(lp, &log->synclist, synclist) { | ||
1631 | if (lp->xflag & COMMIT_PAGE) { | ||
1632 | struct metapage *mp = (struct metapage *)lp; | ||
1633 | dump_mem("orphan metapage", lp, | ||
1634 | sizeof(struct metapage)); | ||
1635 | dump_mem("page", mp->page, sizeof(struct page)); | ||
1636 | } | ||
1637 | else | ||
1638 | dump_mem("orphan tblock", lp, | ||
1639 | sizeof(struct tblock)); | ||
1640 | } | ||
1641 | // current->state = TASK_INTERRUPTIBLE; | ||
1642 | // schedule(); | ||
1643 | } | ||
1644 | //assert(list_empty(&log->synclist)); | ||
1625 | clear_bit(log_FLUSH, &log->flag); | 1645 | clear_bit(log_FLUSH, &log->flag); |
1626 | } | 1646 | } |
1627 | 1647 | ||
@@ -1669,6 +1689,7 @@ int lmLogShutdown(struct jfs_log * log) | |||
1669 | lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); | 1689 | lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); |
1670 | lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0); | 1690 | lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0); |
1671 | lbmIOWait(log->bp, lbmFREE); | 1691 | lbmIOWait(log->bp, lbmFREE); |
1692 | log->bp = NULL; | ||
1672 | 1693 | ||
1673 | /* | 1694 | /* |
1674 | * synchronous update log superblock | 1695 | * synchronous update log superblock |
@@ -1819,20 +1840,34 @@ static int lbmLogInit(struct jfs_log * log) | |||
1819 | 1840 | ||
1820 | log->lbuf_free = NULL; | 1841 | log->lbuf_free = NULL; |
1821 | 1842 | ||
1822 | for (i = 0; i < LOGPAGES; i++) { | 1843 | for (i = 0; i < LOGPAGES;) { |
1823 | lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL); | 1844 | char *buffer; |
1824 | if (lbuf == 0) | 1845 | uint offset; |
1825 | goto error; | 1846 | struct page *page; |
1826 | lbuf->l_ldata = (char *) get_zeroed_page(GFP_KERNEL); | 1847 | |
1827 | if (lbuf->l_ldata == 0) { | 1848 | buffer = (char *) get_zeroed_page(GFP_KERNEL); |
1828 | kfree(lbuf); | 1849 | if (buffer == NULL) |
1829 | goto error; | 1850 | goto error; |
1851 | page = virt_to_page(buffer); | ||
1852 | for (offset = 0; offset < PAGE_SIZE; offset += LOGPSIZE) { | ||
1853 | lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL); | ||
1854 | if (lbuf == NULL) { | ||
1855 | if (offset == 0) | ||
1856 | free_page((unsigned long) buffer); | ||
1857 | goto error; | ||
1858 | } | ||
1859 | if (offset) /* we already have one reference */ | ||
1860 | get_page(page); | ||
1861 | lbuf->l_offset = offset; | ||
1862 | lbuf->l_ldata = buffer + offset; | ||
1863 | lbuf->l_page = page; | ||
1864 | lbuf->l_log = log; | ||
1865 | init_waitqueue_head(&lbuf->l_ioevent); | ||
1866 | |||
1867 | lbuf->l_freelist = log->lbuf_free; | ||
1868 | log->lbuf_free = lbuf; | ||
1869 | i++; | ||
1830 | } | 1870 | } |
1831 | lbuf->l_log = log; | ||
1832 | init_waitqueue_head(&lbuf->l_ioevent); | ||
1833 | |||
1834 | lbuf->l_freelist = log->lbuf_free; | ||
1835 | log->lbuf_free = lbuf; | ||
1836 | } | 1871 | } |
1837 | 1872 | ||
1838 | return (0); | 1873 | return (0); |
@@ -1857,12 +1892,10 @@ static void lbmLogShutdown(struct jfs_log * log) | |||
1857 | lbuf = log->lbuf_free; | 1892 | lbuf = log->lbuf_free; |
1858 | while (lbuf) { | 1893 | while (lbuf) { |
1859 | struct lbuf *next = lbuf->l_freelist; | 1894 | struct lbuf *next = lbuf->l_freelist; |
1860 | free_page((unsigned long) lbuf->l_ldata); | 1895 | __free_page(lbuf->l_page); |
1861 | kfree(lbuf); | 1896 | kfree(lbuf); |
1862 | lbuf = next; | 1897 | lbuf = next; |
1863 | } | 1898 | } |
1864 | |||
1865 | log->bp = NULL; | ||
1866 | } | 1899 | } |
1867 | 1900 | ||
1868 | 1901 | ||
@@ -1974,9 +2007,9 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp) | |||
1974 | 2007 | ||
1975 | bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); | 2008 | bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); |
1976 | bio->bi_bdev = log->bdev; | 2009 | bio->bi_bdev = log->bdev; |
1977 | bio->bi_io_vec[0].bv_page = virt_to_page(bp->l_ldata); | 2010 | bio->bi_io_vec[0].bv_page = bp->l_page; |
1978 | bio->bi_io_vec[0].bv_len = LOGPSIZE; | 2011 | bio->bi_io_vec[0].bv_len = LOGPSIZE; |
1979 | bio->bi_io_vec[0].bv_offset = 0; | 2012 | bio->bi_io_vec[0].bv_offset = bp->l_offset; |
1980 | 2013 | ||
1981 | bio->bi_vcnt = 1; | 2014 | bio->bi_vcnt = 1; |
1982 | bio->bi_idx = 0; | 2015 | bio->bi_idx = 0; |
@@ -2115,9 +2148,9 @@ static void lbmStartIO(struct lbuf * bp) | |||
2115 | bio = bio_alloc(GFP_NOFS, 1); | 2148 | bio = bio_alloc(GFP_NOFS, 1); |
2116 | bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); | 2149 | bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); |
2117 | bio->bi_bdev = log->bdev; | 2150 | bio->bi_bdev = log->bdev; |
2118 | bio->bi_io_vec[0].bv_page = virt_to_page(bp->l_ldata); | 2151 | bio->bi_io_vec[0].bv_page = bp->l_page; |
2119 | bio->bi_io_vec[0].bv_len = LOGPSIZE; | 2152 | bio->bi_io_vec[0].bv_len = LOGPSIZE; |
2120 | bio->bi_io_vec[0].bv_offset = 0; | 2153 | bio->bi_io_vec[0].bv_offset = bp->l_offset; |
2121 | 2154 | ||
2122 | bio->bi_vcnt = 1; | 2155 | bio->bi_vcnt = 1; |
2123 | bio->bi_idx = 0; | 2156 | bio->bi_idx = 0; |
@@ -2127,16 +2160,13 @@ static void lbmStartIO(struct lbuf * bp) | |||
2127 | bio->bi_private = bp; | 2160 | bio->bi_private = bp; |
2128 | 2161 | ||
2129 | /* check if journaling to disk has been disabled */ | 2162 | /* check if journaling to disk has been disabled */ |
2130 | if (!log->no_integrity) { | 2163 | if (log->no_integrity) { |
2164 | bio->bi_size = 0; | ||
2165 | lbmIODone(bio, 0, 0); | ||
2166 | } else { | ||
2131 | submit_bio(WRITE_SYNC, bio); | 2167 | submit_bio(WRITE_SYNC, bio); |
2132 | INCREMENT(lmStat.submitted); | 2168 | INCREMENT(lmStat.submitted); |
2133 | } | 2169 | } |
2134 | else { | ||
2135 | bio->bi_size = 0; | ||
2136 | lbmIODone(bio, 0, 0); /* 2nd argument appears to not be used => 0 | ||
2137 | * 3rd argument appears to not be used => 0 | ||
2138 | */ | ||
2139 | } | ||
2140 | } | 2170 | } |
2141 | 2171 | ||
2142 | 2172 | ||
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h index 141ad74010c9..51291fbc420c 100644 --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h | |||
@@ -463,9 +463,10 @@ struct lbuf { | |||
463 | 463 | ||
464 | s64 l_blkno; /* 8: log page block number */ | 464 | s64 l_blkno; /* 8: log page block number */ |
465 | caddr_t l_ldata; /* 4: data page */ | 465 | caddr_t l_ldata; /* 4: data page */ |
466 | struct page *l_page; /* The page itself */ | ||
467 | uint l_offset; /* Offset of l_ldata within the page */ | ||
466 | 468 | ||
467 | wait_queue_head_t l_ioevent; /* 4: i/o done event */ | 469 | wait_queue_head_t l_ioevent; /* 4: i/o done event */ |
468 | struct page *l_page; /* The page itself */ | ||
469 | }; | 470 | }; |
470 | 471 | ||
471 | /* Reuse l_freelist for redrive list */ | 472 | /* Reuse l_freelist for redrive list */ |
@@ -489,8 +490,9 @@ struct logsyncblk { | |||
489 | */ | 490 | */ |
490 | 491 | ||
491 | #define LOGSYNC_LOCK_INIT(log) spin_lock_init(&(log)->synclock) | 492 | #define LOGSYNC_LOCK_INIT(log) spin_lock_init(&(log)->synclock) |
492 | #define LOGSYNC_LOCK(log) spin_lock(&(log)->synclock) | 493 | #define LOGSYNC_LOCK(log, flags) spin_lock_irqsave(&(log)->synclock, flags) |
493 | #define LOGSYNC_UNLOCK(log) spin_unlock(&(log)->synclock) | 494 | #define LOGSYNC_UNLOCK(log, flags) \ |
495 | spin_unlock_irqrestore(&(log)->synclock, flags) | ||
494 | 496 | ||
495 | /* compute the difference in bytes of lsn from sync point */ | 497 | /* compute the difference in bytes of lsn from sync point */ |
496 | #define logdiff(diff, lsn, log)\ | 498 | #define logdiff(diff, lsn, log)\ |
@@ -506,5 +508,6 @@ extern int lmLogShutdown(struct jfs_log * log); | |||
506 | extern int lmLogInit(struct jfs_log * log); | 508 | extern int lmLogInit(struct jfs_log * log); |
507 | extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize); | 509 | extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize); |
508 | extern void jfs_flush_journal(struct jfs_log * log, int wait); | 510 | extern void jfs_flush_journal(struct jfs_log * log, int wait); |
511 | extern void jfs_syncpt(struct jfs_log *log); | ||
509 | 512 | ||
510 | #endif /* _H_JFS_LOGMGR */ | 513 | #endif /* _H_JFS_LOGMGR */ |
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 4c0a3ac75c08..41bf078dce05 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) International Business Machines Corp., 2000-2003 | 2 | * Copyright (C) International Business Machines Corp., 2000-2005 |
3 | * Portions Copyright (C) Christoph Hellwig, 2001-2002 | 3 | * Portions Copyright (C) Christoph Hellwig, 2001-2002 |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
@@ -18,10 +18,11 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/mm.h> | ||
22 | #include <linux/bio.h> | ||
21 | #include <linux/init.h> | 23 | #include <linux/init.h> |
22 | #include <linux/buffer_head.h> | 24 | #include <linux/buffer_head.h> |
23 | #include <linux/mempool.h> | 25 | #include <linux/mempool.h> |
24 | #include <linux/delay.h> | ||
25 | #include "jfs_incore.h" | 26 | #include "jfs_incore.h" |
26 | #include "jfs_superblock.h" | 27 | #include "jfs_superblock.h" |
27 | #include "jfs_filsys.h" | 28 | #include "jfs_filsys.h" |
@@ -29,8 +30,6 @@ | |||
29 | #include "jfs_txnmgr.h" | 30 | #include "jfs_txnmgr.h" |
30 | #include "jfs_debug.h" | 31 | #include "jfs_debug.h" |
31 | 32 | ||
32 | static DEFINE_SPINLOCK(meta_lock); | ||
33 | |||
34 | #ifdef CONFIG_JFS_STATISTICS | 33 | #ifdef CONFIG_JFS_STATISTICS |
35 | static struct { | 34 | static struct { |
36 | uint pagealloc; /* # of page allocations */ | 35 | uint pagealloc; /* # of page allocations */ |
@@ -39,22 +38,8 @@ static struct { | |||
39 | } mpStat; | 38 | } mpStat; |
40 | #endif | 39 | #endif |
41 | 40 | ||
42 | 41 | #define metapage_locked(mp) test_bit(META_locked, &(mp)->flag) | |
43 | #define HASH_BITS 10 /* This makes hash_table 1 4K page */ | 42 | #define trylock_metapage(mp) test_and_set_bit(META_locked, &(mp)->flag) |
44 | #define HASH_SIZE (1 << HASH_BITS) | ||
45 | static struct metapage **hash_table = NULL; | ||
46 | static unsigned long hash_order; | ||
47 | |||
48 | |||
49 | static inline int metapage_locked(struct metapage *mp) | ||
50 | { | ||
51 | return test_bit(META_locked, &mp->flag); | ||
52 | } | ||
53 | |||
54 | static inline int trylock_metapage(struct metapage *mp) | ||
55 | { | ||
56 | return test_and_set_bit(META_locked, &mp->flag); | ||
57 | } | ||
58 | 43 | ||
59 | static inline void unlock_metapage(struct metapage *mp) | 44 | static inline void unlock_metapage(struct metapage *mp) |
60 | { | 45 | { |
@@ -62,26 +47,26 @@ static inline void unlock_metapage(struct metapage *mp) | |||
62 | wake_up(&mp->wait); | 47 | wake_up(&mp->wait); |
63 | } | 48 | } |
64 | 49 | ||
65 | static void __lock_metapage(struct metapage *mp) | 50 | static inline void __lock_metapage(struct metapage *mp) |
66 | { | 51 | { |
67 | DECLARE_WAITQUEUE(wait, current); | 52 | DECLARE_WAITQUEUE(wait, current); |
68 | |||
69 | INCREMENT(mpStat.lockwait); | 53 | INCREMENT(mpStat.lockwait); |
70 | |||
71 | add_wait_queue_exclusive(&mp->wait, &wait); | 54 | add_wait_queue_exclusive(&mp->wait, &wait); |
72 | do { | 55 | do { |
73 | set_current_state(TASK_UNINTERRUPTIBLE); | 56 | set_current_state(TASK_UNINTERRUPTIBLE); |
74 | if (metapage_locked(mp)) { | 57 | if (metapage_locked(mp)) { |
75 | spin_unlock(&meta_lock); | 58 | unlock_page(mp->page); |
76 | schedule(); | 59 | schedule(); |
77 | spin_lock(&meta_lock); | 60 | lock_page(mp->page); |
78 | } | 61 | } |
79 | } while (trylock_metapage(mp)); | 62 | } while (trylock_metapage(mp)); |
80 | __set_current_state(TASK_RUNNING); | 63 | __set_current_state(TASK_RUNNING); |
81 | remove_wait_queue(&mp->wait, &wait); | 64 | remove_wait_queue(&mp->wait, &wait); |
82 | } | 65 | } |
83 | 66 | ||
84 | /* needs meta_lock */ | 67 | /* |
68 | * Must have mp->page locked | ||
69 | */ | ||
85 | static inline void lock_metapage(struct metapage *mp) | 70 | static inline void lock_metapage(struct metapage *mp) |
86 | { | 71 | { |
87 | if (trylock_metapage(mp)) | 72 | if (trylock_metapage(mp)) |
@@ -92,6 +77,110 @@ static inline void lock_metapage(struct metapage *mp) | |||
92 | static kmem_cache_t *metapage_cache; | 77 | static kmem_cache_t *metapage_cache; |
93 | static mempool_t *metapage_mempool; | 78 | static mempool_t *metapage_mempool; |
94 | 79 | ||
80 | #define MPS_PER_PAGE (PAGE_CACHE_SIZE >> L2PSIZE) | ||
81 | |||
82 | #if MPS_PER_PAGE > 1 | ||
83 | |||
84 | struct meta_anchor { | ||
85 | int mp_count; | ||
86 | atomic_t io_count; | ||
87 | struct metapage *mp[MPS_PER_PAGE]; | ||
88 | }; | ||
89 | #define mp_anchor(page) ((struct meta_anchor *)page->private) | ||
90 | |||
91 | static inline struct metapage *page_to_mp(struct page *page, uint offset) | ||
92 | { | ||
93 | if (!PagePrivate(page)) | ||
94 | return NULL; | ||
95 | return mp_anchor(page)->mp[offset >> L2PSIZE]; | ||
96 | } | ||
97 | |||
98 | static inline int insert_metapage(struct page *page, struct metapage *mp) | ||
99 | { | ||
100 | struct meta_anchor *a; | ||
101 | int index; | ||
102 | int l2mp_blocks; /* log2 blocks per metapage */ | ||
103 | |||
104 | if (PagePrivate(page)) | ||
105 | a = mp_anchor(page); | ||
106 | else { | ||
107 | a = kmalloc(sizeof(struct meta_anchor), GFP_NOFS); | ||
108 | if (!a) | ||
109 | return -ENOMEM; | ||
110 | memset(a, 0, sizeof(struct meta_anchor)); | ||
111 | page->private = (unsigned long)a; | ||
112 | SetPagePrivate(page); | ||
113 | kmap(page); | ||
114 | } | ||
115 | |||
116 | if (mp) { | ||
117 | l2mp_blocks = L2PSIZE - page->mapping->host->i_blkbits; | ||
118 | index = (mp->index >> l2mp_blocks) & (MPS_PER_PAGE - 1); | ||
119 | a->mp_count++; | ||
120 | a->mp[index] = mp; | ||
121 | } | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static inline void remove_metapage(struct page *page, struct metapage *mp) | ||
127 | { | ||
128 | struct meta_anchor *a = mp_anchor(page); | ||
129 | int l2mp_blocks = L2PSIZE - page->mapping->host->i_blkbits; | ||
130 | int index; | ||
131 | |||
132 | index = (mp->index >> l2mp_blocks) & (MPS_PER_PAGE - 1); | ||
133 | |||
134 | BUG_ON(a->mp[index] != mp); | ||
135 | |||
136 | a->mp[index] = NULL; | ||
137 | if (--a->mp_count == 0) { | ||
138 | kfree(a); | ||
139 | page->private = 0; | ||
140 | ClearPagePrivate(page); | ||
141 | kunmap(page); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static inline void inc_io(struct page *page) | ||
146 | { | ||
147 | atomic_inc(&mp_anchor(page)->io_count); | ||
148 | } | ||
149 | |||
150 | static inline void dec_io(struct page *page, void (*handler) (struct page *)) | ||
151 | { | ||
152 | if (atomic_dec_and_test(&mp_anchor(page)->io_count)) | ||
153 | handler(page); | ||
154 | } | ||
155 | |||
156 | #else | ||
157 | static inline struct metapage *page_to_mp(struct page *page, uint offset) | ||
158 | { | ||
159 | return PagePrivate(page) ? (struct metapage *)page->private : NULL; | ||
160 | } | ||
161 | |||
162 | static inline int insert_metapage(struct page *page, struct metapage *mp) | ||
163 | { | ||
164 | if (mp) { | ||
165 | page->private = (unsigned long)mp; | ||
166 | SetPagePrivate(page); | ||
167 | kmap(page); | ||
168 | } | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static inline void remove_metapage(struct page *page, struct metapage *mp) | ||
173 | { | ||
174 | page->private = 0; | ||
175 | ClearPagePrivate(page); | ||
176 | kunmap(page); | ||
177 | } | ||
178 | |||
179 | #define inc_io(page) do {} while(0) | ||
180 | #define dec_io(page, handler) handler(page) | ||
181 | |||
182 | #endif | ||
183 | |||
95 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 184 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) |
96 | { | 185 | { |
97 | struct metapage *mp = (struct metapage *)foo; | 186 | struct metapage *mp = (struct metapage *)foo; |
@@ -139,16 +228,6 @@ int __init metapage_init(void) | |||
139 | kmem_cache_destroy(metapage_cache); | 228 | kmem_cache_destroy(metapage_cache); |
140 | return -ENOMEM; | 229 | return -ENOMEM; |
141 | } | 230 | } |
142 | /* | ||
143 | * Now the hash list | ||
144 | */ | ||
145 | for (hash_order = 0; | ||
146 | ((PAGE_SIZE << hash_order) / sizeof(void *)) < HASH_SIZE; | ||
147 | hash_order++); | ||
148 | hash_table = | ||
149 | (struct metapage **) __get_free_pages(GFP_KERNEL, hash_order); | ||
150 | assert(hash_table); | ||
151 | memset(hash_table, 0, PAGE_SIZE << hash_order); | ||
152 | 231 | ||
153 | return 0; | 232 | return 0; |
154 | } | 233 | } |
@@ -159,73 +238,388 @@ void metapage_exit(void) | |||
159 | kmem_cache_destroy(metapage_cache); | 238 | kmem_cache_destroy(metapage_cache); |
160 | } | 239 | } |
161 | 240 | ||
241 | static inline void drop_metapage(struct page *page, struct metapage *mp) | ||
242 | { | ||
243 | if (mp->count || mp->nohomeok || test_bit(META_dirty, &mp->flag) || | ||
244 | test_bit(META_io, &mp->flag)) | ||
245 | return; | ||
246 | remove_metapage(page, mp); | ||
247 | INCREMENT(mpStat.pagefree); | ||
248 | free_metapage(mp); | ||
249 | } | ||
250 | |||
162 | /* | 251 | /* |
163 | * Basically same hash as in pagemap.h, but using our hash table | 252 | * Metapage address space operations |
164 | */ | 253 | */ |
165 | static struct metapage **meta_hash(struct address_space *mapping, | 254 | |
166 | unsigned long index) | 255 | static sector_t metapage_get_blocks(struct inode *inode, sector_t lblock, |
256 | unsigned int *len) | ||
167 | { | 257 | { |
168 | #define i (((unsigned long)mapping)/ \ | 258 | int rc = 0; |
169 | (sizeof(struct inode) & ~(sizeof(struct inode) -1 ))) | 259 | int xflag; |
170 | #define s(x) ((x) + ((x) >> HASH_BITS)) | 260 | s64 xaddr; |
171 | return hash_table + (s(i + index) & (HASH_SIZE - 1)); | 261 | sector_t file_blocks = (inode->i_size + inode->i_blksize - 1) >> |
172 | #undef i | 262 | inode->i_blkbits; |
173 | #undef s | 263 | |
264 | if (lblock >= file_blocks) | ||
265 | return 0; | ||
266 | if (lblock + *len > file_blocks) | ||
267 | *len = file_blocks - lblock; | ||
268 | |||
269 | if (inode->i_ino) { | ||
270 | rc = xtLookup(inode, (s64)lblock, *len, &xflag, &xaddr, len, 0); | ||
271 | if ((rc == 0) && *len) | ||
272 | lblock = (sector_t)xaddr; | ||
273 | else | ||
274 | lblock = 0; | ||
275 | } /* else no mapping */ | ||
276 | |||
277 | return lblock; | ||
174 | } | 278 | } |
175 | 279 | ||
176 | static struct metapage *search_hash(struct metapage ** hash_ptr, | 280 | static void last_read_complete(struct page *page) |
177 | struct address_space *mapping, | ||
178 | unsigned long index) | ||
179 | { | 281 | { |
180 | struct metapage *ptr; | 282 | if (!PageError(page)) |
283 | SetPageUptodate(page); | ||
284 | unlock_page(page); | ||
285 | } | ||
286 | |||
287 | static int metapage_read_end_io(struct bio *bio, unsigned int bytes_done, | ||
288 | int err) | ||
289 | { | ||
290 | struct page *page = bio->bi_private; | ||
291 | |||
292 | if (bio->bi_size) | ||
293 | return 1; | ||
181 | 294 | ||
182 | for (ptr = *hash_ptr; ptr; ptr = ptr->hash_next) { | 295 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { |
183 | if ((ptr->mapping == mapping) && (ptr->index == index)) | 296 | printk(KERN_ERR "metapage_read_end_io: I/O error\n"); |
184 | return ptr; | 297 | SetPageError(page); |
185 | } | 298 | } |
186 | 299 | ||
187 | return NULL; | 300 | dec_io(page, last_read_complete); |
301 | bio_put(bio); | ||
302 | |||
303 | return 0; | ||
188 | } | 304 | } |
189 | 305 | ||
190 | static void add_to_hash(struct metapage * mp, struct metapage ** hash_ptr) | 306 | static void remove_from_logsync(struct metapage *mp) |
191 | { | 307 | { |
192 | if (*hash_ptr) | 308 | struct jfs_log *log = mp->log; |
193 | (*hash_ptr)->hash_prev = mp; | 309 | unsigned long flags; |
310 | /* | ||
311 | * This can race. Recheck that log hasn't been set to null, and after | ||
312 | * acquiring logsync lock, recheck lsn | ||
313 | */ | ||
314 | if (!log) | ||
315 | return; | ||
316 | |||
317 | LOGSYNC_LOCK(log, flags); | ||
318 | if (mp->lsn) { | ||
319 | mp->log = NULL; | ||
320 | mp->lsn = 0; | ||
321 | mp->clsn = 0; | ||
322 | log->count--; | ||
323 | list_del(&mp->synclist); | ||
324 | } | ||
325 | LOGSYNC_UNLOCK(log, flags); | ||
326 | } | ||
194 | 327 | ||
195 | mp->hash_prev = NULL; | 328 | static void last_write_complete(struct page *page) |
196 | mp->hash_next = *hash_ptr; | 329 | { |
197 | *hash_ptr = mp; | 330 | struct metapage *mp; |
331 | unsigned int offset; | ||
332 | |||
333 | for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) { | ||
334 | mp = page_to_mp(page, offset); | ||
335 | if (mp && test_bit(META_io, &mp->flag)) { | ||
336 | if (mp->lsn) | ||
337 | remove_from_logsync(mp); | ||
338 | clear_bit(META_io, &mp->flag); | ||
339 | } | ||
340 | /* | ||
341 | * I'd like to call drop_metapage here, but I don't think it's | ||
342 | * safe unless I have the page locked | ||
343 | */ | ||
344 | } | ||
345 | end_page_writeback(page); | ||
198 | } | 346 | } |
199 | 347 | ||
200 | static void remove_from_hash(struct metapage * mp, struct metapage ** hash_ptr) | 348 | static int metapage_write_end_io(struct bio *bio, unsigned int bytes_done, |
349 | int err) | ||
201 | { | 350 | { |
202 | if (mp->hash_prev) | 351 | struct page *page = bio->bi_private; |
203 | mp->hash_prev->hash_next = mp->hash_next; | 352 | |
204 | else { | 353 | BUG_ON(!PagePrivate(page)); |
205 | assert(*hash_ptr == mp); | 354 | |
206 | *hash_ptr = mp->hash_next; | 355 | if (bio->bi_size) |
356 | return 1; | ||
357 | |||
358 | if (! test_bit(BIO_UPTODATE, &bio->bi_flags)) { | ||
359 | printk(KERN_ERR "metapage_write_end_io: I/O error\n"); | ||
360 | SetPageError(page); | ||
361 | } | ||
362 | dec_io(page, last_write_complete); | ||
363 | bio_put(bio); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int metapage_writepage(struct page *page, struct writeback_control *wbc) | ||
368 | { | ||
369 | struct bio *bio = NULL; | ||
370 | unsigned int block_offset; /* block offset of mp within page */ | ||
371 | struct inode *inode = page->mapping->host; | ||
372 | unsigned int blocks_per_mp = JFS_SBI(inode->i_sb)->nbperpage; | ||
373 | unsigned int len; | ||
374 | unsigned int xlen; | ||
375 | struct metapage *mp; | ||
376 | int redirty = 0; | ||
377 | sector_t lblock; | ||
378 | sector_t pblock; | ||
379 | sector_t next_block = 0; | ||
380 | sector_t page_start; | ||
381 | unsigned long bio_bytes = 0; | ||
382 | unsigned long bio_offset = 0; | ||
383 | unsigned int offset; | ||
384 | |||
385 | page_start = (sector_t)page->index << | ||
386 | (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
387 | BUG_ON(!PageLocked(page)); | ||
388 | BUG_ON(PageWriteback(page)); | ||
389 | |||
390 | for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) { | ||
391 | mp = page_to_mp(page, offset); | ||
392 | |||
393 | if (!mp || !test_bit(META_dirty, &mp->flag)) | ||
394 | continue; | ||
395 | |||
396 | if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) { | ||
397 | redirty = 1; | ||
398 | continue; | ||
399 | } | ||
400 | |||
401 | clear_bit(META_dirty, &mp->flag); | ||
402 | block_offset = offset >> inode->i_blkbits; | ||
403 | lblock = page_start + block_offset; | ||
404 | if (bio) { | ||
405 | if (xlen && lblock == next_block) { | ||
406 | /* Contiguous, in memory & on disk */ | ||
407 | len = min(xlen, blocks_per_mp); | ||
408 | xlen -= len; | ||
409 | bio_bytes += len << inode->i_blkbits; | ||
410 | set_bit(META_io, &mp->flag); | ||
411 | continue; | ||
412 | } | ||
413 | /* Not contiguous */ | ||
414 | if (bio_add_page(bio, page, bio_bytes, bio_offset) < | ||
415 | bio_bytes) | ||
416 | goto add_failed; | ||
417 | /* | ||
418 | * Increment counter before submitting i/o to keep | ||
419 | * count from hitting zero before we're through | ||
420 | */ | ||
421 | inc_io(page); | ||
422 | if (!bio->bi_size) | ||
423 | goto dump_bio; | ||
424 | submit_bio(WRITE, bio); | ||
425 | bio = NULL; | ||
426 | } else { | ||
427 | set_page_writeback(page); | ||
428 | inc_io(page); | ||
429 | } | ||
430 | xlen = (PAGE_CACHE_SIZE - offset) >> inode->i_blkbits; | ||
431 | pblock = metapage_get_blocks(inode, lblock, &xlen); | ||
432 | if (!pblock) { | ||
433 | /* Need better error handling */ | ||
434 | printk(KERN_ERR "JFS: metapage_get_blocks failed\n"); | ||
435 | dec_io(page, last_write_complete); | ||
436 | continue; | ||
437 | } | ||
438 | set_bit(META_io, &mp->flag); | ||
439 | len = min(xlen, (uint) JFS_SBI(inode->i_sb)->nbperpage); | ||
440 | |||
441 | bio = bio_alloc(GFP_NOFS, 1); | ||
442 | bio->bi_bdev = inode->i_sb->s_bdev; | ||
443 | bio->bi_sector = pblock << (inode->i_blkbits - 9); | ||
444 | bio->bi_end_io = metapage_write_end_io; | ||
445 | bio->bi_private = page; | ||
446 | |||
447 | /* Don't call bio_add_page yet, we may add to this vec */ | ||
448 | bio_offset = offset; | ||
449 | bio_bytes = len << inode->i_blkbits; | ||
450 | |||
451 | xlen -= len; | ||
452 | next_block = lblock + len; | ||
453 | } | ||
454 | if (bio) { | ||
455 | if (bio_add_page(bio, page, bio_bytes, bio_offset) < bio_bytes) | ||
456 | goto add_failed; | ||
457 | if (!bio->bi_size) | ||
458 | goto dump_bio; | ||
459 | |||
460 | submit_bio(WRITE, bio); | ||
461 | } | ||
462 | if (redirty) | ||
463 | redirty_page_for_writepage(wbc, page); | ||
464 | |||
465 | unlock_page(page); | ||
466 | |||
467 | return 0; | ||
468 | add_failed: | ||
469 | /* We should never reach here, since we're only adding one vec */ | ||
470 | printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n"); | ||
471 | goto skip; | ||
472 | dump_bio: | ||
473 | dump_mem("bio", bio, sizeof(*bio)); | ||
474 | skip: | ||
475 | bio_put(bio); | ||
476 | unlock_page(page); | ||
477 | dec_io(page, last_write_complete); | ||
478 | |||
479 | return -EIO; | ||
480 | } | ||
481 | |||
482 | static int metapage_readpage(struct file *fp, struct page *page) | ||
483 | { | ||
484 | struct inode *inode = page->mapping->host; | ||
485 | struct bio *bio = NULL; | ||
486 | unsigned int block_offset; | ||
487 | unsigned int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits; | ||
488 | sector_t page_start; /* address of page in fs blocks */ | ||
489 | sector_t pblock; | ||
490 | unsigned int xlen; | ||
491 | unsigned int len; | ||
492 | unsigned int offset; | ||
493 | |||
494 | BUG_ON(!PageLocked(page)); | ||
495 | page_start = (sector_t)page->index << | ||
496 | (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
497 | |||
498 | block_offset = 0; | ||
499 | while (block_offset < blocks_per_page) { | ||
500 | xlen = blocks_per_page - block_offset; | ||
501 | pblock = metapage_get_blocks(inode, page_start + block_offset, | ||
502 | &xlen); | ||
503 | if (pblock) { | ||
504 | if (!PagePrivate(page)) | ||
505 | insert_metapage(page, NULL); | ||
506 | inc_io(page); | ||
507 | if (bio) | ||
508 | submit_bio(READ, bio); | ||
509 | |||
510 | bio = bio_alloc(GFP_NOFS, 1); | ||
511 | bio->bi_bdev = inode->i_sb->s_bdev; | ||
512 | bio->bi_sector = pblock << (inode->i_blkbits - 9); | ||
513 | bio->bi_end_io = metapage_read_end_io; | ||
514 | bio->bi_private = page; | ||
515 | len = xlen << inode->i_blkbits; | ||
516 | offset = block_offset << inode->i_blkbits; | ||
517 | if (bio_add_page(bio, page, len, offset) < len) | ||
518 | goto add_failed; | ||
519 | block_offset += xlen; | ||
520 | } else | ||
521 | block_offset++; | ||
207 | } | 522 | } |
523 | if (bio) | ||
524 | submit_bio(READ, bio); | ||
525 | else | ||
526 | unlock_page(page); | ||
527 | |||
528 | return 0; | ||
208 | 529 | ||
209 | if (mp->hash_next) | 530 | add_failed: |
210 | mp->hash_next->hash_prev = mp->hash_prev; | 531 | printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n"); |
532 | bio_put(bio); | ||
533 | dec_io(page, last_read_complete); | ||
534 | return -EIO; | ||
211 | } | 535 | } |
212 | 536 | ||
537 | static int metapage_releasepage(struct page *page, int gfp_mask) | ||
538 | { | ||
539 | struct metapage *mp; | ||
540 | int busy = 0; | ||
541 | unsigned int offset; | ||
542 | |||
543 | for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) { | ||
544 | mp = page_to_mp(page, offset); | ||
545 | |||
546 | if (!mp) | ||
547 | continue; | ||
548 | |||
549 | jfs_info("metapage_releasepage: mp = 0x%p", mp); | ||
550 | if (mp->count || mp->nohomeok) { | ||
551 | jfs_info("count = %ld, nohomeok = %d", mp->count, | ||
552 | mp->nohomeok); | ||
553 | busy = 1; | ||
554 | continue; | ||
555 | } | ||
556 | wait_on_page_writeback(page); | ||
557 | //WARN_ON(test_bit(META_dirty, &mp->flag)); | ||
558 | if (test_bit(META_dirty, &mp->flag)) { | ||
559 | dump_mem("dirty mp in metapage_releasepage", mp, | ||
560 | sizeof(struct metapage)); | ||
561 | dump_mem("page", page, sizeof(struct page)); | ||
562 | dump_stack(); | ||
563 | } | ||
564 | WARN_ON(mp->lsn); | ||
565 | if (mp->lsn) | ||
566 | remove_from_logsync(mp); | ||
567 | remove_metapage(page, mp); | ||
568 | INCREMENT(mpStat.pagefree); | ||
569 | free_metapage(mp); | ||
570 | } | ||
571 | if (busy) | ||
572 | return -1; | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int metapage_invalidatepage(struct page *page, unsigned long offset) | ||
578 | { | ||
579 | BUG_ON(offset); | ||
580 | |||
581 | if (PageWriteback(page)) | ||
582 | return 0; | ||
583 | |||
584 | return metapage_releasepage(page, 0); | ||
585 | } | ||
586 | |||
587 | struct address_space_operations jfs_metapage_aops = { | ||
588 | .readpage = metapage_readpage, | ||
589 | .writepage = metapage_writepage, | ||
590 | .sync_page = block_sync_page, | ||
591 | .releasepage = metapage_releasepage, | ||
592 | .invalidatepage = metapage_invalidatepage, | ||
593 | .set_page_dirty = __set_page_dirty_nobuffers, | ||
594 | }; | ||
595 | |||
213 | struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, | 596 | struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, |
214 | unsigned int size, int absolute, | 597 | unsigned int size, int absolute, |
215 | unsigned long new) | 598 | unsigned long new) |
216 | { | 599 | { |
217 | struct metapage **hash_ptr; | ||
218 | int l2BlocksPerPage; | 600 | int l2BlocksPerPage; |
219 | int l2bsize; | 601 | int l2bsize; |
220 | struct address_space *mapping; | 602 | struct address_space *mapping; |
221 | struct metapage *mp; | 603 | struct metapage *mp = NULL; |
604 | struct page *page; | ||
222 | unsigned long page_index; | 605 | unsigned long page_index; |
223 | unsigned long page_offset; | 606 | unsigned long page_offset; |
224 | 607 | ||
225 | jfs_info("__get_metapage: inode = 0x%p, lblock = 0x%lx", inode, lblock); | 608 | jfs_info("__get_metapage: ino = %ld, lblock = 0x%lx, abs=%d", |
226 | 609 | inode->i_ino, lblock, absolute); | |
610 | |||
611 | l2bsize = inode->i_blkbits; | ||
612 | l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize; | ||
613 | page_index = lblock >> l2BlocksPerPage; | ||
614 | page_offset = (lblock - (page_index << l2BlocksPerPage)) << l2bsize; | ||
615 | if ((page_offset + size) > PAGE_CACHE_SIZE) { | ||
616 | jfs_err("MetaData crosses page boundary!!"); | ||
617 | jfs_err("lblock = %lx, size = %d", lblock, size); | ||
618 | dump_stack(); | ||
619 | return NULL; | ||
620 | } | ||
227 | if (absolute) | 621 | if (absolute) |
228 | mapping = inode->i_sb->s_bdev->bd_inode->i_mapping; | 622 | mapping = JFS_SBI(inode->i_sb)->direct_inode->i_mapping; |
229 | else { | 623 | else { |
230 | /* | 624 | /* |
231 | * If an nfs client tries to read an inode that is larger | 625 | * If an nfs client tries to read an inode that is larger |
@@ -237,312 +631,212 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, | |||
237 | mapping = inode->i_mapping; | 631 | mapping = inode->i_mapping; |
238 | } | 632 | } |
239 | 633 | ||
240 | hash_ptr = meta_hash(mapping, lblock); | 634 | if (new && (PSIZE == PAGE_CACHE_SIZE)) { |
241 | again: | 635 | page = grab_cache_page(mapping, page_index); |
242 | spin_lock(&meta_lock); | 636 | if (!page) { |
243 | mp = search_hash(hash_ptr, mapping, lblock); | 637 | jfs_err("grab_cache_page failed!"); |
638 | return NULL; | ||
639 | } | ||
640 | SetPageUptodate(page); | ||
641 | } else { | ||
642 | page = read_cache_page(mapping, page_index, | ||
643 | (filler_t *)mapping->a_ops->readpage, NULL); | ||
644 | if (IS_ERR(page)) { | ||
645 | jfs_err("read_cache_page failed!"); | ||
646 | return NULL; | ||
647 | } | ||
648 | lock_page(page); | ||
649 | } | ||
650 | |||
651 | mp = page_to_mp(page, page_offset); | ||
244 | if (mp) { | 652 | if (mp) { |
245 | page_found: | 653 | if (mp->logical_size != size) { |
246 | if (test_bit(META_stale, &mp->flag)) { | 654 | jfs_error(inode->i_sb, |
247 | spin_unlock(&meta_lock); | 655 | "__get_metapage: mp->logical_size != size"); |
248 | msleep(1); | 656 | jfs_err("logical_size = %d, size = %d", |
249 | goto again; | 657 | mp->logical_size, size); |
658 | dump_stack(); | ||
659 | goto unlock; | ||
250 | } | 660 | } |
251 | mp->count++; | 661 | mp->count++; |
252 | lock_metapage(mp); | 662 | lock_metapage(mp); |
253 | spin_unlock(&meta_lock); | ||
254 | if (test_bit(META_discard, &mp->flag)) { | 663 | if (test_bit(META_discard, &mp->flag)) { |
255 | if (!new) { | 664 | if (!new) { |
256 | jfs_error(inode->i_sb, | 665 | jfs_error(inode->i_sb, |
257 | "__get_metapage: using a " | 666 | "__get_metapage: using a " |
258 | "discarded metapage"); | 667 | "discarded metapage"); |
259 | release_metapage(mp); | 668 | discard_metapage(mp); |
260 | return NULL; | 669 | goto unlock; |
261 | } | 670 | } |
262 | clear_bit(META_discard, &mp->flag); | 671 | clear_bit(META_discard, &mp->flag); |
263 | } | 672 | } |
264 | jfs_info("__get_metapage: found 0x%p, in hash", mp); | ||
265 | if (mp->logical_size != size) { | ||
266 | jfs_error(inode->i_sb, | ||
267 | "__get_metapage: mp->logical_size != size"); | ||
268 | release_metapage(mp); | ||
269 | return NULL; | ||
270 | } | ||
271 | } else { | 673 | } else { |
272 | l2bsize = inode->i_blkbits; | 674 | INCREMENT(mpStat.pagealloc); |
273 | l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize; | 675 | mp = alloc_metapage(GFP_NOFS); |
274 | page_index = lblock >> l2BlocksPerPage; | 676 | mp->page = page; |
275 | page_offset = (lblock - (page_index << l2BlocksPerPage)) << | ||
276 | l2bsize; | ||
277 | if ((page_offset + size) > PAGE_CACHE_SIZE) { | ||
278 | spin_unlock(&meta_lock); | ||
279 | jfs_err("MetaData crosses page boundary!!"); | ||
280 | return NULL; | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Locks held on aggregate inode pages are usually | ||
285 | * not held long, and they are taken in critical code | ||
286 | * paths (committing dirty inodes, txCommit thread) | ||
287 | * | ||
288 | * Attempt to get metapage without blocking, tapping into | ||
289 | * reserves if necessary. | ||
290 | */ | ||
291 | mp = NULL; | ||
292 | if (JFS_IP(inode)->fileset == AGGREGATE_I) { | ||
293 | mp = alloc_metapage(GFP_ATOMIC); | ||
294 | if (!mp) { | ||
295 | /* | ||
296 | * mempool is supposed to protect us from | ||
297 | * failing here. We will try a blocking | ||
298 | * call, but a deadlock is possible here | ||
299 | */ | ||
300 | printk(KERN_WARNING | ||
301 | "__get_metapage: atomic call to mempool_alloc failed.\n"); | ||
302 | printk(KERN_WARNING | ||
303 | "Will attempt blocking call\n"); | ||
304 | } | ||
305 | } | ||
306 | if (!mp) { | ||
307 | struct metapage *mp2; | ||
308 | |||
309 | spin_unlock(&meta_lock); | ||
310 | mp = alloc_metapage(GFP_NOFS); | ||
311 | spin_lock(&meta_lock); | ||
312 | |||
313 | /* we dropped the meta_lock, we need to search the | ||
314 | * hash again. | ||
315 | */ | ||
316 | mp2 = search_hash(hash_ptr, mapping, lblock); | ||
317 | if (mp2) { | ||
318 | free_metapage(mp); | ||
319 | mp = mp2; | ||
320 | goto page_found; | ||
321 | } | ||
322 | } | ||
323 | mp->flag = 0; | 677 | mp->flag = 0; |
324 | lock_metapage(mp); | ||
325 | if (absolute) | ||
326 | set_bit(META_absolute, &mp->flag); | ||
327 | mp->xflag = COMMIT_PAGE; | 678 | mp->xflag = COMMIT_PAGE; |
328 | mp->count = 1; | 679 | mp->count = 1; |
329 | atomic_set(&mp->nohomeok,0); | 680 | mp->nohomeok = 0; |
330 | mp->mapping = mapping; | ||
331 | mp->index = lblock; | ||
332 | mp->page = NULL; | ||
333 | mp->logical_size = size; | 681 | mp->logical_size = size; |
334 | add_to_hash(mp, hash_ptr); | 682 | mp->data = page_address(page) + page_offset; |
335 | spin_unlock(&meta_lock); | 683 | mp->index = lblock; |
336 | 684 | if (unlikely(insert_metapage(page, mp))) { | |
337 | if (new) { | 685 | free_metapage(mp); |
338 | jfs_info("__get_metapage: Calling grab_cache_page"); | 686 | goto unlock; |
339 | mp->page = grab_cache_page(mapping, page_index); | ||
340 | if (!mp->page) { | ||
341 | jfs_err("grab_cache_page failed!"); | ||
342 | goto freeit; | ||
343 | } else { | ||
344 | INCREMENT(mpStat.pagealloc); | ||
345 | unlock_page(mp->page); | ||
346 | } | ||
347 | } else { | ||
348 | jfs_info("__get_metapage: Calling read_cache_page"); | ||
349 | mp->page = read_cache_page(mapping, lblock, | ||
350 | (filler_t *)mapping->a_ops->readpage, NULL); | ||
351 | if (IS_ERR(mp->page)) { | ||
352 | jfs_err("read_cache_page failed!"); | ||
353 | goto freeit; | ||
354 | } else | ||
355 | INCREMENT(mpStat.pagealloc); | ||
356 | } | 687 | } |
357 | mp->data = kmap(mp->page) + page_offset; | 688 | lock_metapage(mp); |
358 | } | 689 | } |
359 | 690 | ||
360 | if (new) | 691 | if (new) { |
692 | jfs_info("zeroing mp = 0x%p", mp); | ||
361 | memset(mp->data, 0, PSIZE); | 693 | memset(mp->data, 0, PSIZE); |
694 | } | ||
362 | 695 | ||
363 | jfs_info("__get_metapage: returning = 0x%p", mp); | 696 | unlock_page(page); |
697 | jfs_info("__get_metapage: returning = 0x%p data = 0x%p", mp, mp->data); | ||
364 | return mp; | 698 | return mp; |
365 | 699 | ||
366 | freeit: | 700 | unlock: |
367 | spin_lock(&meta_lock); | 701 | unlock_page(page); |
368 | remove_from_hash(mp, hash_ptr); | ||
369 | free_metapage(mp); | ||
370 | spin_unlock(&meta_lock); | ||
371 | return NULL; | 702 | return NULL; |
372 | } | 703 | } |
373 | 704 | ||
374 | void hold_metapage(struct metapage * mp, int force) | 705 | void grab_metapage(struct metapage * mp) |
375 | { | 706 | { |
376 | spin_lock(&meta_lock); | 707 | jfs_info("grab_metapage: mp = 0x%p", mp); |
377 | 708 | page_cache_get(mp->page); | |
709 | lock_page(mp->page); | ||
378 | mp->count++; | 710 | mp->count++; |
379 | 711 | lock_metapage(mp); | |
380 | if (force) { | 712 | unlock_page(mp->page); |
381 | ASSERT (!(test_bit(META_forced, &mp->flag))); | ||
382 | if (trylock_metapage(mp)) | ||
383 | set_bit(META_forced, &mp->flag); | ||
384 | } else | ||
385 | lock_metapage(mp); | ||
386 | |||
387 | spin_unlock(&meta_lock); | ||
388 | } | 713 | } |
389 | 714 | ||
390 | static void __write_metapage(struct metapage * mp) | 715 | void force_metapage(struct metapage *mp) |
391 | { | 716 | { |
392 | int l2bsize = mp->mapping->host->i_blkbits; | 717 | struct page *page = mp->page; |
393 | int l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize; | 718 | jfs_info("force_metapage: mp = 0x%p", mp); |
394 | unsigned long page_index; | 719 | set_bit(META_forcewrite, &mp->flag); |
395 | unsigned long page_offset; | 720 | clear_bit(META_sync, &mp->flag); |
396 | int rc; | 721 | page_cache_get(page); |
397 | 722 | lock_page(page); | |
398 | jfs_info("__write_metapage: mp = 0x%p", mp); | 723 | set_page_dirty(page); |
399 | 724 | write_one_page(page, 1); | |
400 | page_index = mp->page->index; | 725 | clear_bit(META_forcewrite, &mp->flag); |
401 | page_offset = | 726 | page_cache_release(page); |
402 | (mp->index - (page_index << l2BlocksPerPage)) << l2bsize; | 727 | } |
403 | 728 | ||
729 | extern void hold_metapage(struct metapage *mp) | ||
730 | { | ||
404 | lock_page(mp->page); | 731 | lock_page(mp->page); |
405 | rc = mp->mapping->a_ops->prepare_write(NULL, mp->page, page_offset, | 732 | } |
406 | page_offset + | 733 | |
407 | mp->logical_size); | 734 | extern void put_metapage(struct metapage *mp) |
408 | if (rc) { | 735 | { |
409 | jfs_err("prepare_write return %d!", rc); | 736 | if (mp->count || mp->nohomeok) { |
410 | ClearPageUptodate(mp->page); | 737 | /* Someone else will release this */ |
411 | unlock_page(mp->page); | 738 | unlock_page(mp->page); |
412 | clear_bit(META_dirty, &mp->flag); | ||
413 | return; | 739 | return; |
414 | } | 740 | } |
415 | rc = mp->mapping->a_ops->commit_write(NULL, mp->page, page_offset, | 741 | page_cache_get(mp->page); |
416 | page_offset + | 742 | mp->count++; |
417 | mp->logical_size); | 743 | lock_metapage(mp); |
418 | if (rc) { | ||
419 | jfs_err("commit_write returned %d", rc); | ||
420 | } | ||
421 | |||
422 | unlock_page(mp->page); | 744 | unlock_page(mp->page); |
423 | clear_bit(META_dirty, &mp->flag); | 745 | release_metapage(mp); |
424 | |||
425 | jfs_info("__write_metapage done"); | ||
426 | } | ||
427 | |||
428 | static inline void sync_metapage(struct metapage *mp) | ||
429 | { | ||
430 | struct page *page = mp->page; | ||
431 | |||
432 | page_cache_get(page); | ||
433 | lock_page(page); | ||
434 | |||
435 | /* we're done with this page - no need to check for errors */ | ||
436 | if (page_has_buffers(page)) | ||
437 | write_one_page(page, 1); | ||
438 | else | ||
439 | unlock_page(page); | ||
440 | page_cache_release(page); | ||
441 | } | 746 | } |
442 | 747 | ||
443 | void release_metapage(struct metapage * mp) | 748 | void release_metapage(struct metapage * mp) |
444 | { | 749 | { |
445 | struct jfs_log *log; | 750 | struct page *page = mp->page; |
446 | |||
447 | jfs_info("release_metapage: mp = 0x%p, flag = 0x%lx", mp, mp->flag); | 751 | jfs_info("release_metapage: mp = 0x%p, flag = 0x%lx", mp, mp->flag); |
448 | 752 | ||
449 | spin_lock(&meta_lock); | 753 | BUG_ON(!page); |
450 | if (test_bit(META_forced, &mp->flag)) { | 754 | |
451 | clear_bit(META_forced, &mp->flag); | 755 | lock_page(page); |
452 | mp->count--; | 756 | unlock_metapage(mp); |
453 | spin_unlock(&meta_lock); | ||
454 | return; | ||
455 | } | ||
456 | 757 | ||
457 | assert(mp->count); | 758 | assert(mp->count); |
458 | if (--mp->count || atomic_read(&mp->nohomeok)) { | 759 | if (--mp->count || mp->nohomeok) { |
459 | unlock_metapage(mp); | 760 | unlock_page(page); |
460 | spin_unlock(&meta_lock); | 761 | page_cache_release(page); |
461 | return; | 762 | return; |
462 | } | 763 | } |
463 | 764 | ||
464 | if (mp->page) { | 765 | if (test_bit(META_dirty, &mp->flag)) { |
465 | set_bit(META_stale, &mp->flag); | 766 | set_page_dirty(page); |
466 | spin_unlock(&meta_lock); | ||
467 | kunmap(mp->page); | ||
468 | mp->data = NULL; | ||
469 | if (test_bit(META_dirty, &mp->flag)) | ||
470 | __write_metapage(mp); | ||
471 | if (test_bit(META_sync, &mp->flag)) { | 767 | if (test_bit(META_sync, &mp->flag)) { |
472 | sync_metapage(mp); | ||
473 | clear_bit(META_sync, &mp->flag); | 768 | clear_bit(META_sync, &mp->flag); |
769 | write_one_page(page, 1); | ||
770 | lock_page(page); /* write_one_page unlocks the page */ | ||
474 | } | 771 | } |
772 | } else if (mp->lsn) /* discard_metapage doesn't remove it */ | ||
773 | remove_from_logsync(mp); | ||
475 | 774 | ||
476 | if (test_bit(META_discard, &mp->flag)) { | 775 | #if MPS_PER_PAGE == 1 |
477 | lock_page(mp->page); | 776 | /* |
478 | block_invalidatepage(mp->page, 0); | 777 | * If we know this is the only thing in the page, we can throw |
479 | unlock_page(mp->page); | 778 | * the page out of the page cache. If pages are larger, we |
480 | } | 779 | * don't want to do this. |
481 | 780 | */ | |
482 | page_cache_release(mp->page); | ||
483 | mp->page = NULL; | ||
484 | INCREMENT(mpStat.pagefree); | ||
485 | spin_lock(&meta_lock); | ||
486 | } | ||
487 | 781 | ||
488 | if (mp->lsn) { | 782 | /* Retest mp->count since we may have released page lock */ |
489 | /* | 783 | if (test_bit(META_discard, &mp->flag) && !mp->count) { |
490 | * Remove metapage from logsynclist. | 784 | clear_page_dirty(page); |
491 | */ | 785 | ClearPageUptodate(page); |
492 | log = mp->log; | 786 | #ifdef _NOT_YET |
493 | LOGSYNC_LOCK(log); | 787 | if (page->mapping) { |
494 | mp->log = NULL; | 788 | /* Remove from page cache and page cache reference */ |
495 | mp->lsn = 0; | 789 | remove_from_page_cache(page); |
496 | mp->clsn = 0; | 790 | page_cache_release(page); |
497 | log->count--; | 791 | metapage_releasepage(page, 0); |
498 | list_del(&mp->synclist); | 792 | } |
499 | LOGSYNC_UNLOCK(log); | 793 | #endif |
500 | } | 794 | } |
501 | remove_from_hash(mp, meta_hash(mp->mapping, mp->index)); | 795 | #else |
502 | spin_unlock(&meta_lock); | 796 | /* Try to keep metapages from using up too much memory */ |
503 | 797 | drop_metapage(page, mp); | |
504 | free_metapage(mp); | 798 | #endif |
799 | unlock_page(page); | ||
800 | page_cache_release(page); | ||
505 | } | 801 | } |
506 | 802 | ||
507 | void __invalidate_metapages(struct inode *ip, s64 addr, int len) | 803 | void __invalidate_metapages(struct inode *ip, s64 addr, int len) |
508 | { | 804 | { |
509 | struct metapage **hash_ptr; | 805 | sector_t lblock; |
510 | unsigned long lblock; | ||
511 | int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_blkbits; | 806 | int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_blkbits; |
807 | int BlocksPerPage = 1 << l2BlocksPerPage; | ||
512 | /* All callers are interested in block device's mapping */ | 808 | /* All callers are interested in block device's mapping */ |
513 | struct address_space *mapping = ip->i_sb->s_bdev->bd_inode->i_mapping; | 809 | struct address_space *mapping = |
810 | JFS_SBI(ip->i_sb)->direct_inode->i_mapping; | ||
514 | struct metapage *mp; | 811 | struct metapage *mp; |
515 | struct page *page; | 812 | struct page *page; |
813 | unsigned int offset; | ||
516 | 814 | ||
517 | /* | 815 | /* |
518 | * First, mark metapages to discard. They will eventually be | 816 | * Mark metapages to discard. They will eventually be |
519 | * released, but should not be written. | 817 | * released, but should not be written. |
520 | */ | 818 | */ |
521 | for (lblock = addr; lblock < addr + len; | 819 | for (lblock = addr & ~(BlocksPerPage - 1); lblock < addr + len; |
522 | lblock += 1 << l2BlocksPerPage) { | 820 | lblock += BlocksPerPage) { |
523 | hash_ptr = meta_hash(mapping, lblock); | 821 | page = find_lock_page(mapping, lblock >> l2BlocksPerPage); |
524 | again: | 822 | if (!page) |
525 | spin_lock(&meta_lock); | 823 | continue; |
526 | mp = search_hash(hash_ptr, mapping, lblock); | 824 | for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) { |
527 | if (mp) { | 825 | mp = page_to_mp(page, offset); |
528 | if (test_bit(META_stale, &mp->flag)) { | 826 | if (!mp) |
529 | spin_unlock(&meta_lock); | 827 | continue; |
530 | msleep(1); | 828 | if (mp->index < addr) |
531 | goto again; | 829 | continue; |
532 | } | 830 | if (mp->index >= addr + len) |
831 | break; | ||
533 | 832 | ||
534 | clear_bit(META_dirty, &mp->flag); | 833 | clear_bit(META_dirty, &mp->flag); |
535 | set_bit(META_discard, &mp->flag); | 834 | set_bit(META_discard, &mp->flag); |
536 | spin_unlock(&meta_lock); | 835 | if (mp->lsn) |
537 | } else { | 836 | remove_from_logsync(mp); |
538 | spin_unlock(&meta_lock); | ||
539 | page = find_lock_page(mapping, lblock>>l2BlocksPerPage); | ||
540 | if (page) { | ||
541 | block_invalidatepage(page, 0); | ||
542 | unlock_page(page); | ||
543 | page_cache_release(page); | ||
544 | } | ||
545 | } | 837 | } |
838 | unlock_page(page); | ||
839 | page_cache_release(page); | ||
546 | } | 840 | } |
547 | } | 841 | } |
548 | 842 | ||
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h index 0e58aba58c37..991e9fb84c75 100644 --- a/fs/jfs/jfs_metapage.h +++ b/fs/jfs/jfs_metapage.h | |||
@@ -33,38 +33,27 @@ struct metapage { | |||
33 | unsigned long flag; /* See Below */ | 33 | unsigned long flag; /* See Below */ |
34 | unsigned long count; /* Reference count */ | 34 | unsigned long count; /* Reference count */ |
35 | void *data; /* Data pointer */ | 35 | void *data; /* Data pointer */ |
36 | 36 | sector_t index; /* block address of page */ | |
37 | /* list management stuff */ | ||
38 | struct metapage *hash_prev; | ||
39 | struct metapage *hash_next; /* Also used for free list */ | ||
40 | |||
41 | /* | ||
42 | * mapping & index become redundant, but we need these here to | ||
43 | * add the metapage to the hash before we have the real page | ||
44 | */ | ||
45 | struct address_space *mapping; | ||
46 | unsigned long index; | ||
47 | wait_queue_head_t wait; | 37 | wait_queue_head_t wait; |
48 | 38 | ||
49 | /* implementation */ | 39 | /* implementation */ |
50 | struct page *page; | 40 | struct page *page; |
51 | unsigned long logical_size; | 41 | unsigned int logical_size; |
52 | 42 | ||
53 | /* Journal management */ | 43 | /* Journal management */ |
54 | int clsn; | 44 | int clsn; |
55 | atomic_t nohomeok; | 45 | int nohomeok; |
56 | struct jfs_log *log; | 46 | struct jfs_log *log; |
57 | }; | 47 | }; |
58 | 48 | ||
59 | /* metapage flag */ | 49 | /* metapage flag */ |
60 | #define META_locked 0 | 50 | #define META_locked 0 |
61 | #define META_absolute 1 | 51 | #define META_free 1 |
62 | #define META_free 2 | 52 | #define META_dirty 2 |
63 | #define META_dirty 3 | 53 | #define META_sync 3 |
64 | #define META_sync 4 | 54 | #define META_discard 4 |
65 | #define META_discard 5 | 55 | #define META_forcewrite 5 |
66 | #define META_forced 6 | 56 | #define META_io 6 |
67 | #define META_stale 7 | ||
68 | 57 | ||
69 | #define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag) | 58 | #define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag) |
70 | 59 | ||
@@ -80,7 +69,16 @@ extern struct metapage *__get_metapage(struct inode *inode, | |||
80 | __get_metapage(inode, lblock, size, absolute, TRUE) | 69 | __get_metapage(inode, lblock, size, absolute, TRUE) |
81 | 70 | ||
82 | extern void release_metapage(struct metapage *); | 71 | extern void release_metapage(struct metapage *); |
83 | extern void hold_metapage(struct metapage *, int); | 72 | extern void grab_metapage(struct metapage *); |
73 | extern void force_metapage(struct metapage *); | ||
74 | |||
75 | /* | ||
76 | * hold_metapage and put_metapage are used in conjuction. The page lock | ||
77 | * is not dropped between the two, so no other threads can get or release | ||
78 | * the metapage | ||
79 | */ | ||
80 | extern void hold_metapage(struct metapage *); | ||
81 | extern void put_metapage(struct metapage *); | ||
84 | 82 | ||
85 | static inline void write_metapage(struct metapage *mp) | 83 | static inline void write_metapage(struct metapage *mp) |
86 | { | 84 | { |
@@ -101,6 +99,46 @@ static inline void discard_metapage(struct metapage *mp) | |||
101 | release_metapage(mp); | 99 | release_metapage(mp); |
102 | } | 100 | } |
103 | 101 | ||
102 | static inline void metapage_nohomeok(struct metapage *mp) | ||
103 | { | ||
104 | struct page *page = mp->page; | ||
105 | lock_page(page); | ||
106 | if (!mp->nohomeok++) { | ||
107 | mark_metapage_dirty(mp); | ||
108 | page_cache_get(page); | ||
109 | wait_on_page_writeback(page); | ||
110 | } | ||
111 | unlock_page(page); | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * This serializes access to mp->lsn when metapages are added to logsynclist | ||
116 | * without setting nohomeok. i.e. updating imap & dmap | ||
117 | */ | ||
118 | static inline void metapage_wait_for_io(struct metapage *mp) | ||
119 | { | ||
120 | if (test_bit(META_io, &mp->flag)) | ||
121 | wait_on_page_writeback(mp->page); | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * This is called when already holding the metapage | ||
126 | */ | ||
127 | static inline void _metapage_homeok(struct metapage *mp) | ||
128 | { | ||
129 | if (!--mp->nohomeok) | ||
130 | page_cache_release(mp->page); | ||
131 | } | ||
132 | |||
133 | static inline void metapage_homeok(struct metapage *mp) | ||
134 | { | ||
135 | hold_metapage(mp); | ||
136 | _metapage_homeok(mp); | ||
137 | put_metapage(mp); | ||
138 | } | ||
139 | |||
140 | extern struct address_space_operations jfs_metapage_aops; | ||
141 | |||
104 | /* | 142 | /* |
105 | * This routines invalidate all pages for an extent. | 143 | * This routines invalidate all pages for an extent. |
106 | */ | 144 | */ |
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c index c535ffd638e8..032d111bc330 100644 --- a/fs/jfs/jfs_mount.c +++ b/fs/jfs/jfs_mount.c | |||
@@ -285,11 +285,6 @@ int jfs_mount_rw(struct super_block *sb, int remount) | |||
285 | */ | 285 | */ |
286 | logMOUNT(sb); | 286 | logMOUNT(sb); |
287 | 287 | ||
288 | /* | ||
289 | * Set page cache allocation policy | ||
290 | */ | ||
291 | mapping_set_gfp_mask(sb->s_bdev->bd_inode->i_mapping, GFP_NOFS); | ||
292 | |||
293 | return rc; | 288 | return rc; |
294 | } | 289 | } |
295 | 290 | ||
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index f40301d93f74..e93d01aa12c4 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -227,6 +227,7 @@ static lid_t txLockAlloc(void) | |||
227 | 227 | ||
228 | static void txLockFree(lid_t lid) | 228 | static void txLockFree(lid_t lid) |
229 | { | 229 | { |
230 | TxLock[lid].tid = 0; | ||
230 | TxLock[lid].next = TxAnchor.freelock; | 231 | TxLock[lid].next = TxAnchor.freelock; |
231 | TxAnchor.freelock = lid; | 232 | TxAnchor.freelock = lid; |
232 | TxAnchor.tlocksInUse--; | 233 | TxAnchor.tlocksInUse--; |
@@ -566,9 +567,6 @@ void txEnd(tid_t tid) | |||
566 | * synchronize with logsync barrier | 567 | * synchronize with logsync barrier |
567 | */ | 568 | */ |
568 | if (test_bit(log_SYNCBARRIER, &log->flag)) { | 569 | if (test_bit(log_SYNCBARRIER, &log->flag)) { |
569 | /* forward log syncpt */ | ||
570 | /* lmSync(log); */ | ||
571 | |||
572 | jfs_info("log barrier off: 0x%x", log->lsn); | 570 | jfs_info("log barrier off: 0x%x", log->lsn); |
573 | 571 | ||
574 | /* enable new transactions start */ | 572 | /* enable new transactions start */ |
@@ -576,15 +574,22 @@ void txEnd(tid_t tid) | |||
576 | 574 | ||
577 | /* wakeup all waitors for logsync barrier */ | 575 | /* wakeup all waitors for logsync barrier */ |
578 | TXN_WAKEUP(&log->syncwait); | 576 | TXN_WAKEUP(&log->syncwait); |
577 | |||
578 | TXN_UNLOCK(); | ||
579 | |||
580 | /* forward log syncpt */ | ||
581 | jfs_syncpt(log); | ||
582 | |||
583 | goto wakeup; | ||
579 | } | 584 | } |
580 | } | 585 | } |
581 | 586 | ||
587 | TXN_UNLOCK(); | ||
588 | wakeup: | ||
582 | /* | 589 | /* |
583 | * wakeup all waitors for a free tblock | 590 | * wakeup all waitors for a free tblock |
584 | */ | 591 | */ |
585 | TXN_WAKEUP(&TxAnchor.freewait); | 592 | TXN_WAKEUP(&TxAnchor.freewait); |
586 | |||
587 | TXN_UNLOCK(); | ||
588 | } | 593 | } |
589 | 594 | ||
590 | 595 | ||
@@ -633,8 +638,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
633 | 638 | ||
634 | /* is page locked by the requester transaction ? */ | 639 | /* is page locked by the requester transaction ? */ |
635 | tlck = lid_to_tlock(lid); | 640 | tlck = lid_to_tlock(lid); |
636 | if ((xtid = tlck->tid) == tid) | 641 | if ((xtid = tlck->tid) == tid) { |
642 | TXN_UNLOCK(); | ||
637 | goto grantLock; | 643 | goto grantLock; |
644 | } | ||
638 | 645 | ||
639 | /* | 646 | /* |
640 | * is page locked by anonymous transaction/lock ? | 647 | * is page locked by anonymous transaction/lock ? |
@@ -649,6 +656,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
649 | */ | 656 | */ |
650 | if (xtid == 0) { | 657 | if (xtid == 0) { |
651 | tlck->tid = tid; | 658 | tlck->tid = tid; |
659 | TXN_UNLOCK(); | ||
652 | tblk = tid_to_tblock(tid); | 660 | tblk = tid_to_tblock(tid); |
653 | /* | 661 | /* |
654 | * The order of the tlocks in the transaction is important | 662 | * The order of the tlocks in the transaction is important |
@@ -706,17 +714,18 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
706 | */ | 714 | */ |
707 | tlck->tid = tid; | 715 | tlck->tid = tid; |
708 | 716 | ||
717 | TXN_UNLOCK(); | ||
718 | |||
709 | /* mark tlock for meta-data page */ | 719 | /* mark tlock for meta-data page */ |
710 | if (mp->xflag & COMMIT_PAGE) { | 720 | if (mp->xflag & COMMIT_PAGE) { |
711 | 721 | ||
712 | tlck->flag = tlckPAGELOCK; | 722 | tlck->flag = tlckPAGELOCK; |
713 | 723 | ||
714 | /* mark the page dirty and nohomeok */ | 724 | /* mark the page dirty and nohomeok */ |
715 | mark_metapage_dirty(mp); | 725 | metapage_nohomeok(mp); |
716 | atomic_inc(&mp->nohomeok); | ||
717 | 726 | ||
718 | jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p", | 727 | jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p", |
719 | mp, atomic_read(&mp->nohomeok), tid, tlck); | 728 | mp, mp->nohomeok, tid, tlck); |
720 | 729 | ||
721 | /* if anonymous transaction, and buffer is on the group | 730 | /* if anonymous transaction, and buffer is on the group |
722 | * commit synclist, mark inode to show this. This will | 731 | * commit synclist, mark inode to show this. This will |
@@ -762,8 +771,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
762 | if (tlck->next == 0) { | 771 | if (tlck->next == 0) { |
763 | /* This inode's first anonymous transaction */ | 772 | /* This inode's first anonymous transaction */ |
764 | jfs_ip->atltail = lid; | 773 | jfs_ip->atltail = lid; |
774 | TXN_LOCK(); | ||
765 | list_add_tail(&jfs_ip->anon_inode_list, | 775 | list_add_tail(&jfs_ip->anon_inode_list, |
766 | &TxAnchor.anon_list); | 776 | &TxAnchor.anon_list); |
777 | TXN_UNLOCK(); | ||
767 | } | 778 | } |
768 | } | 779 | } |
769 | 780 | ||
@@ -821,8 +832,6 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
821 | grantLock: | 832 | grantLock: |
822 | tlck->type |= type; | 833 | tlck->type |= type; |
823 | 834 | ||
824 | TXN_UNLOCK(); | ||
825 | |||
826 | return tlck; | 835 | return tlck; |
827 | 836 | ||
828 | /* | 837 | /* |
@@ -841,11 +850,19 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
841 | BUG(); | 850 | BUG(); |
842 | } | 851 | } |
843 | INCREMENT(stattx.waitlock); /* statistics */ | 852 | INCREMENT(stattx.waitlock); /* statistics */ |
853 | TXN_UNLOCK(); | ||
844 | release_metapage(mp); | 854 | release_metapage(mp); |
855 | TXN_LOCK(); | ||
856 | xtid = tlck->tid; /* reaquire after dropping TXN_LOCK */ | ||
845 | 857 | ||
846 | jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d", | 858 | jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d", |
847 | tid, xtid, lid); | 859 | tid, xtid, lid); |
848 | TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor); | 860 | |
861 | /* Recheck everything since dropping TXN_LOCK */ | ||
862 | if (xtid && (tlck->mp == mp) && (mp->lid == lid)) | ||
863 | TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor); | ||
864 | else | ||
865 | TXN_UNLOCK(); | ||
849 | jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid); | 866 | jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid); |
850 | 867 | ||
851 | return NULL; | 868 | return NULL; |
@@ -906,6 +923,7 @@ static void txUnlock(struct tblock * tblk) | |||
906 | struct metapage *mp; | 923 | struct metapage *mp; |
907 | struct jfs_log *log; | 924 | struct jfs_log *log; |
908 | int difft, diffp; | 925 | int difft, diffp; |
926 | unsigned long flags; | ||
909 | 927 | ||
910 | jfs_info("txUnlock: tblk = 0x%p", tblk); | 928 | jfs_info("txUnlock: tblk = 0x%p", tblk); |
911 | log = JFS_SBI(tblk->sb)->log; | 929 | log = JFS_SBI(tblk->sb)->log; |
@@ -925,19 +943,14 @@ static void txUnlock(struct tblock * tblk) | |||
925 | assert(mp->xflag & COMMIT_PAGE); | 943 | assert(mp->xflag & COMMIT_PAGE); |
926 | 944 | ||
927 | /* hold buffer | 945 | /* hold buffer |
928 | * | ||
929 | * It's possible that someone else has the metapage. | ||
930 | * The only things were changing are nohomeok, which | ||
931 | * is handled atomically, and clsn which is protected | ||
932 | * by the LOGSYNC_LOCK. | ||
933 | */ | 946 | */ |
934 | hold_metapage(mp, 1); | 947 | hold_metapage(mp); |
935 | 948 | ||
936 | assert(atomic_read(&mp->nohomeok) > 0); | 949 | assert(mp->nohomeok > 0); |
937 | atomic_dec(&mp->nohomeok); | 950 | _metapage_homeok(mp); |
938 | 951 | ||
939 | /* inherit younger/larger clsn */ | 952 | /* inherit younger/larger clsn */ |
940 | LOGSYNC_LOCK(log); | 953 | LOGSYNC_LOCK(log, flags); |
941 | if (mp->clsn) { | 954 | if (mp->clsn) { |
942 | logdiff(difft, tblk->clsn, log); | 955 | logdiff(difft, tblk->clsn, log); |
943 | logdiff(diffp, mp->clsn, log); | 956 | logdiff(diffp, mp->clsn, log); |
@@ -945,16 +958,11 @@ static void txUnlock(struct tblock * tblk) | |||
945 | mp->clsn = tblk->clsn; | 958 | mp->clsn = tblk->clsn; |
946 | } else | 959 | } else |
947 | mp->clsn = tblk->clsn; | 960 | mp->clsn = tblk->clsn; |
948 | LOGSYNC_UNLOCK(log); | 961 | LOGSYNC_UNLOCK(log, flags); |
949 | 962 | ||
950 | assert(!(tlck->flag & tlckFREEPAGE)); | 963 | assert(!(tlck->flag & tlckFREEPAGE)); |
951 | 964 | ||
952 | if (tlck->flag & tlckWRITEPAGE) { | 965 | put_metapage(mp); |
953 | write_metapage(mp); | ||
954 | } else { | ||
955 | /* release page which has been forced */ | ||
956 | release_metapage(mp); | ||
957 | } | ||
958 | } | 966 | } |
959 | 967 | ||
960 | /* insert tlock, and linelock(s) of the tlock if any, | 968 | /* insert tlock, and linelock(s) of the tlock if any, |
@@ -981,10 +989,10 @@ static void txUnlock(struct tblock * tblk) | |||
981 | * has been inserted in logsync list at txUpdateMap()) | 989 | * has been inserted in logsync list at txUpdateMap()) |
982 | */ | 990 | */ |
983 | if (tblk->lsn) { | 991 | if (tblk->lsn) { |
984 | LOGSYNC_LOCK(log); | 992 | LOGSYNC_LOCK(log, flags); |
985 | log->count--; | 993 | log->count--; |
986 | list_del(&tblk->synclist); | 994 | list_del(&tblk->synclist); |
987 | LOGSYNC_UNLOCK(log); | 995 | LOGSYNC_UNLOCK(log, flags); |
988 | } | 996 | } |
989 | } | 997 | } |
990 | 998 | ||
@@ -1573,8 +1581,8 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1573 | * the last entry, so don't bother logging this | 1581 | * the last entry, so don't bother logging this |
1574 | */ | 1582 | */ |
1575 | mp->lid = 0; | 1583 | mp->lid = 0; |
1576 | hold_metapage(mp, 0); | 1584 | grab_metapage(mp); |
1577 | atomic_dec(&mp->nohomeok); | 1585 | metapage_homeok(mp); |
1578 | discard_metapage(mp); | 1586 | discard_metapage(mp); |
1579 | tlck->mp = NULL; | 1587 | tlck->mp = NULL; |
1580 | return 0; | 1588 | return 0; |
@@ -1712,7 +1720,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1712 | struct maplock *maplock; | 1720 | struct maplock *maplock; |
1713 | struct xdlistlock *xadlock; | 1721 | struct xdlistlock *xadlock; |
1714 | struct pxd_lock *pxdlock; | 1722 | struct pxd_lock *pxdlock; |
1715 | pxd_t *pxd; | 1723 | pxd_t *page_pxd; |
1716 | int next, lwm, hwm; | 1724 | int next, lwm, hwm; |
1717 | 1725 | ||
1718 | ip = tlck->ip; | 1726 | ip = tlck->ip; |
@@ -1722,7 +1730,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1722 | lrd->log.redopage.type = cpu_to_le16(LOG_XTREE); | 1730 | lrd->log.redopage.type = cpu_to_le16(LOG_XTREE); |
1723 | lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE); | 1731 | lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE); |
1724 | 1732 | ||
1725 | pxd = &lrd->log.redopage.pxd; | 1733 | page_pxd = &lrd->log.redopage.pxd; |
1726 | 1734 | ||
1727 | if (tlck->type & tlckBTROOT) { | 1735 | if (tlck->type & tlckBTROOT) { |
1728 | lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); | 1736 | lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); |
@@ -1752,9 +1760,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1752 | * applying the after-image to the meta-data page. | 1760 | * applying the after-image to the meta-data page. |
1753 | */ | 1761 | */ |
1754 | lrd->type = cpu_to_le16(LOG_REDOPAGE); | 1762 | lrd->type = cpu_to_le16(LOG_REDOPAGE); |
1755 | // *pxd = mp->cm_pxd; | 1763 | // *page_pxd = mp->cm_pxd; |
1756 | PXDaddress(pxd, mp->index); | 1764 | PXDaddress(page_pxd, mp->index); |
1757 | PXDlength(pxd, | 1765 | PXDlength(page_pxd, |
1758 | mp->logical_size >> tblk->sb->s_blocksize_bits); | 1766 | mp->logical_size >> tblk->sb->s_blocksize_bits); |
1759 | lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); | 1767 | lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); |
1760 | 1768 | ||
@@ -1776,25 +1784,31 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1776 | tlck->flag |= tlckUPDATEMAP; | 1784 | tlck->flag |= tlckUPDATEMAP; |
1777 | xadlock->flag = mlckALLOCXADLIST; | 1785 | xadlock->flag = mlckALLOCXADLIST; |
1778 | xadlock->count = next - lwm; | 1786 | xadlock->count = next - lwm; |
1779 | if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) { | 1787 | if ((xadlock->count <= 4) && (tblk->xflag & COMMIT_LAZY)) { |
1780 | int i; | 1788 | int i; |
1789 | pxd_t *pxd; | ||
1781 | /* | 1790 | /* |
1782 | * Lazy commit may allow xtree to be modified before | 1791 | * Lazy commit may allow xtree to be modified before |
1783 | * txUpdateMap runs. Copy xad into linelock to | 1792 | * txUpdateMap runs. Copy xad into linelock to |
1784 | * preserve correct data. | 1793 | * preserve correct data. |
1794 | * | ||
1795 | * We can fit twice as may pxd's as xads in the lock | ||
1785 | */ | 1796 | */ |
1786 | xadlock->xdlist = &xtlck->pxdlock; | 1797 | xadlock->flag = mlckALLOCPXDLIST; |
1787 | memcpy(xadlock->xdlist, &p->xad[lwm], | 1798 | pxd = xadlock->xdlist = &xtlck->pxdlock; |
1788 | sizeof(xad_t) * xadlock->count); | 1799 | for (i = 0; i < xadlock->count; i++) { |
1789 | 1800 | PXDaddress(pxd, addressXAD(&p->xad[lwm + i])); | |
1790 | for (i = 0; i < xadlock->count; i++) | 1801 | PXDlength(pxd, lengthXAD(&p->xad[lwm + i])); |
1791 | p->xad[lwm + i].flag &= | 1802 | p->xad[lwm + i].flag &= |
1792 | ~(XAD_NEW | XAD_EXTENDED); | 1803 | ~(XAD_NEW | XAD_EXTENDED); |
1804 | pxd++; | ||
1805 | } | ||
1793 | } else { | 1806 | } else { |
1794 | /* | 1807 | /* |
1795 | * xdlist will point to into inode's xtree, ensure | 1808 | * xdlist will point to into inode's xtree, ensure |
1796 | * that transaction is not committed lazily. | 1809 | * that transaction is not committed lazily. |
1797 | */ | 1810 | */ |
1811 | xadlock->flag = mlckALLOCXADLIST; | ||
1798 | xadlock->xdlist = &p->xad[lwm]; | 1812 | xadlock->xdlist = &p->xad[lwm]; |
1799 | tblk->xflag &= ~COMMIT_LAZY; | 1813 | tblk->xflag &= ~COMMIT_LAZY; |
1800 | } | 1814 | } |
@@ -1836,8 +1850,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1836 | if (tblk->xflag & COMMIT_TRUNCATE) { | 1850 | if (tblk->xflag & COMMIT_TRUNCATE) { |
1837 | /* write NOREDOPAGE for the page */ | 1851 | /* write NOREDOPAGE for the page */ |
1838 | lrd->type = cpu_to_le16(LOG_NOREDOPAGE); | 1852 | lrd->type = cpu_to_le16(LOG_NOREDOPAGE); |
1839 | PXDaddress(pxd, mp->index); | 1853 | PXDaddress(page_pxd, mp->index); |
1840 | PXDlength(pxd, | 1854 | PXDlength(page_pxd, |
1841 | mp->logical_size >> tblk->sb-> | 1855 | mp->logical_size >> tblk->sb-> |
1842 | s_blocksize_bits); | 1856 | s_blocksize_bits); |
1843 | lrd->backchain = | 1857 | lrd->backchain = |
@@ -1872,22 +1886,32 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1872 | * deleted page itself; | 1886 | * deleted page itself; |
1873 | */ | 1887 | */ |
1874 | tlck->flag |= tlckUPDATEMAP; | 1888 | tlck->flag |= tlckUPDATEMAP; |
1875 | xadlock->flag = mlckFREEXADLIST; | ||
1876 | xadlock->count = hwm - XTENTRYSTART + 1; | 1889 | xadlock->count = hwm - XTENTRYSTART + 1; |
1877 | if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) { | 1890 | if ((xadlock->count <= 4) && (tblk->xflag & COMMIT_LAZY)) { |
1891 | int i; | ||
1892 | pxd_t *pxd; | ||
1878 | /* | 1893 | /* |
1879 | * Lazy commit may allow xtree to be modified before | 1894 | * Lazy commit may allow xtree to be modified before |
1880 | * txUpdateMap runs. Copy xad into linelock to | 1895 | * txUpdateMap runs. Copy xad into linelock to |
1881 | * preserve correct data. | 1896 | * preserve correct data. |
1897 | * | ||
1898 | * We can fit twice as may pxd's as xads in the lock | ||
1882 | */ | 1899 | */ |
1883 | xadlock->xdlist = &xtlck->pxdlock; | 1900 | xadlock->flag = mlckFREEPXDLIST; |
1884 | memcpy(xadlock->xdlist, &p->xad[XTENTRYSTART], | 1901 | pxd = xadlock->xdlist = &xtlck->pxdlock; |
1885 | sizeof(xad_t) * xadlock->count); | 1902 | for (i = 0; i < xadlock->count; i++) { |
1903 | PXDaddress(pxd, | ||
1904 | addressXAD(&p->xad[XTENTRYSTART + i])); | ||
1905 | PXDlength(pxd, | ||
1906 | lengthXAD(&p->xad[XTENTRYSTART + i])); | ||
1907 | pxd++; | ||
1908 | } | ||
1886 | } else { | 1909 | } else { |
1887 | /* | 1910 | /* |
1888 | * xdlist will point to into inode's xtree, ensure | 1911 | * xdlist will point to into inode's xtree, ensure |
1889 | * that transaction is not committed lazily. | 1912 | * that transaction is not committed lazily. |
1890 | */ | 1913 | */ |
1914 | xadlock->flag = mlckFREEXADLIST; | ||
1891 | xadlock->xdlist = &p->xad[XTENTRYSTART]; | 1915 | xadlock->xdlist = &p->xad[XTENTRYSTART]; |
1892 | tblk->xflag &= ~COMMIT_LAZY; | 1916 | tblk->xflag &= ~COMMIT_LAZY; |
1893 | } | 1917 | } |
@@ -1918,7 +1942,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1918 | * header ? | 1942 | * header ? |
1919 | */ | 1943 | */ |
1920 | if (tlck->type & tlckTRUNCATE) { | 1944 | if (tlck->type & tlckTRUNCATE) { |
1921 | pxd_t tpxd; /* truncated extent of xad */ | 1945 | pxd_t pxd; /* truncated extent of xad */ |
1922 | int twm; | 1946 | int twm; |
1923 | 1947 | ||
1924 | /* | 1948 | /* |
@@ -1947,8 +1971,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1947 | * applying the after-image to the meta-data page. | 1971 | * applying the after-image to the meta-data page. |
1948 | */ | 1972 | */ |
1949 | lrd->type = cpu_to_le16(LOG_REDOPAGE); | 1973 | lrd->type = cpu_to_le16(LOG_REDOPAGE); |
1950 | PXDaddress(pxd, mp->index); | 1974 | PXDaddress(page_pxd, mp->index); |
1951 | PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits); | 1975 | PXDlength(page_pxd, |
1976 | mp->logical_size >> tblk->sb->s_blocksize_bits); | ||
1952 | lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); | 1977 | lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); |
1953 | 1978 | ||
1954 | /* | 1979 | /* |
@@ -1966,7 +1991,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
1966 | lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD); | 1991 | lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD); |
1967 | lrd->log.updatemap.nxd = cpu_to_le16(1); | 1992 | lrd->log.updatemap.nxd = cpu_to_le16(1); |
1968 | lrd->log.updatemap.pxd = pxdlock->pxd; | 1993 | lrd->log.updatemap.pxd = pxdlock->pxd; |
1969 | tpxd = pxdlock->pxd; /* save to format maplock */ | 1994 | pxd = pxdlock->pxd; /* save to format maplock */ |
1970 | lrd->backchain = | 1995 | lrd->backchain = |
1971 | cpu_to_le32(lmLog(log, tblk, lrd, NULL)); | 1996 | cpu_to_le32(lmLog(log, tblk, lrd, NULL)); |
1972 | } | 1997 | } |
@@ -2035,7 +2060,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, | |||
2035 | pxdlock = (struct pxd_lock *) xadlock; | 2060 | pxdlock = (struct pxd_lock *) xadlock; |
2036 | pxdlock->flag = mlckFREEPXD; | 2061 | pxdlock->flag = mlckFREEPXD; |
2037 | pxdlock->count = 1; | 2062 | pxdlock->count = 1; |
2038 | pxdlock->pxd = tpxd; | 2063 | pxdlock->pxd = pxd; |
2039 | 2064 | ||
2040 | jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d " | 2065 | jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d " |
2041 | "hwm:%d", ip, mp, pxdlock->count, hwm); | 2066 | "hwm:%d", ip, mp, pxdlock->count, hwm); |
@@ -2253,7 +2278,8 @@ void txForce(struct tblock * tblk) | |||
2253 | tlck->flag &= ~tlckWRITEPAGE; | 2278 | tlck->flag &= ~tlckWRITEPAGE; |
2254 | 2279 | ||
2255 | /* do not release page to freelist */ | 2280 | /* do not release page to freelist */ |
2256 | 2281 | force_metapage(mp); | |
2282 | #if 0 | ||
2257 | /* | 2283 | /* |
2258 | * The "right" thing to do here is to | 2284 | * The "right" thing to do here is to |
2259 | * synchronously write the metadata. | 2285 | * synchronously write the metadata. |
@@ -2265,9 +2291,10 @@ void txForce(struct tblock * tblk) | |||
2265 | * we can get by with synchronously writing | 2291 | * we can get by with synchronously writing |
2266 | * the pages when they are released. | 2292 | * the pages when they are released. |
2267 | */ | 2293 | */ |
2268 | assert(atomic_read(&mp->nohomeok)); | 2294 | assert(mp->nohomeok); |
2269 | set_bit(META_dirty, &mp->flag); | 2295 | set_bit(META_dirty, &mp->flag); |
2270 | set_bit(META_sync, &mp->flag); | 2296 | set_bit(META_sync, &mp->flag); |
2297 | #endif | ||
2271 | } | 2298 | } |
2272 | } | 2299 | } |
2273 | } | 2300 | } |
@@ -2327,7 +2354,7 @@ static void txUpdateMap(struct tblock * tblk) | |||
2327 | */ | 2354 | */ |
2328 | mp = tlck->mp; | 2355 | mp = tlck->mp; |
2329 | ASSERT(mp->xflag & COMMIT_PAGE); | 2356 | ASSERT(mp->xflag & COMMIT_PAGE); |
2330 | hold_metapage(mp, 0); | 2357 | grab_metapage(mp); |
2331 | } | 2358 | } |
2332 | 2359 | ||
2333 | /* | 2360 | /* |
@@ -2377,8 +2404,8 @@ static void txUpdateMap(struct tblock * tblk) | |||
2377 | ASSERT(mp->lid == lid); | 2404 | ASSERT(mp->lid == lid); |
2378 | tlck->mp->lid = 0; | 2405 | tlck->mp->lid = 0; |
2379 | } | 2406 | } |
2380 | assert(atomic_read(&mp->nohomeok) == 1); | 2407 | assert(mp->nohomeok == 1); |
2381 | atomic_dec(&mp->nohomeok); | 2408 | metapage_homeok(mp); |
2382 | discard_metapage(mp); | 2409 | discard_metapage(mp); |
2383 | tlck->mp = NULL; | 2410 | tlck->mp = NULL; |
2384 | } | 2411 | } |
@@ -2844,24 +2871,9 @@ static void LogSyncRelease(struct metapage * mp) | |||
2844 | { | 2871 | { |
2845 | struct jfs_log *log = mp->log; | 2872 | struct jfs_log *log = mp->log; |
2846 | 2873 | ||
2847 | assert(atomic_read(&mp->nohomeok)); | 2874 | assert(mp->nohomeok); |
2848 | assert(log); | 2875 | assert(log); |
2849 | atomic_dec(&mp->nohomeok); | 2876 | metapage_homeok(mp); |
2850 | |||
2851 | if (atomic_read(&mp->nohomeok)) | ||
2852 | return; | ||
2853 | |||
2854 | hold_metapage(mp, 0); | ||
2855 | |||
2856 | LOGSYNC_LOCK(log); | ||
2857 | mp->log = NULL; | ||
2858 | mp->lsn = 0; | ||
2859 | mp->clsn = 0; | ||
2860 | log->count--; | ||
2861 | list_del_init(&mp->synclist); | ||
2862 | LOGSYNC_UNLOCK(log); | ||
2863 | |||
2864 | release_metapage(mp); | ||
2865 | } | 2877 | } |
2866 | 2878 | ||
2867 | /* | 2879 | /* |
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c index f31a9e3f3fec..5cf91785b541 100644 --- a/fs/jfs/jfs_umount.c +++ b/fs/jfs/jfs_umount.c | |||
@@ -49,7 +49,6 @@ | |||
49 | */ | 49 | */ |
50 | int jfs_umount(struct super_block *sb) | 50 | int jfs_umount(struct super_block *sb) |
51 | { | 51 | { |
52 | struct address_space *bdev_mapping = sb->s_bdev->bd_inode->i_mapping; | ||
53 | struct jfs_sb_info *sbi = JFS_SBI(sb); | 52 | struct jfs_sb_info *sbi = JFS_SBI(sb); |
54 | struct inode *ipbmap = sbi->ipbmap; | 53 | struct inode *ipbmap = sbi->ipbmap; |
55 | struct inode *ipimap = sbi->ipimap; | 54 | struct inode *ipimap = sbi->ipimap; |
@@ -109,8 +108,8 @@ int jfs_umount(struct super_block *sb) | |||
109 | * Make sure all metadata makes it to disk before we mark | 108 | * Make sure all metadata makes it to disk before we mark |
110 | * the superblock as clean | 109 | * the superblock as clean |
111 | */ | 110 | */ |
112 | filemap_fdatawrite(bdev_mapping); | 111 | filemap_fdatawrite(sbi->direct_inode->i_mapping); |
113 | filemap_fdatawait(bdev_mapping); | 112 | filemap_fdatawait(sbi->direct_inode->i_mapping); |
114 | 113 | ||
115 | /* | 114 | /* |
116 | * ensure all file system file pages are propagated to their | 115 | * ensure all file system file pages are propagated to their |
@@ -123,9 +122,6 @@ int jfs_umount(struct super_block *sb) | |||
123 | if (log) { /* log = NULL if read-only mount */ | 122 | if (log) { /* log = NULL if read-only mount */ |
124 | updateSuper(sb, FM_CLEAN); | 123 | updateSuper(sb, FM_CLEAN); |
125 | 124 | ||
126 | /* Restore default gfp_mask for bdev */ | ||
127 | mapping_set_gfp_mask(bdev_mapping, GFP_USER); | ||
128 | |||
129 | /* | 125 | /* |
130 | * close log: | 126 | * close log: |
131 | * | 127 | * |
@@ -140,7 +136,6 @@ int jfs_umount(struct super_block *sb) | |||
140 | 136 | ||
141 | int jfs_umount_rw(struct super_block *sb) | 137 | int jfs_umount_rw(struct super_block *sb) |
142 | { | 138 | { |
143 | struct address_space *bdev_mapping = sb->s_bdev->bd_inode->i_mapping; | ||
144 | struct jfs_sb_info *sbi = JFS_SBI(sb); | 139 | struct jfs_sb_info *sbi = JFS_SBI(sb); |
145 | struct jfs_log *log = sbi->log; | 140 | struct jfs_log *log = sbi->log; |
146 | 141 | ||
@@ -166,13 +161,10 @@ int jfs_umount_rw(struct super_block *sb) | |||
166 | * mark the superblock clean before everything is flushed to | 161 | * mark the superblock clean before everything is flushed to |
167 | * disk. | 162 | * disk. |
168 | */ | 163 | */ |
169 | filemap_fdatawrite(bdev_mapping); | 164 | filemap_fdatawrite(sbi->direct_inode->i_mapping); |
170 | filemap_fdatawait(bdev_mapping); | 165 | filemap_fdatawait(sbi->direct_inode->i_mapping); |
171 | 166 | ||
172 | updateSuper(sb, FM_CLEAN); | 167 | updateSuper(sb, FM_CLEAN); |
173 | 168 | ||
174 | /* Restore default gfp_mask for bdev */ | ||
175 | mapping_set_gfp_mask(bdev_mapping, GFP_USER); | ||
176 | |||
177 | return lmLogClose(sb); | 169 | return lmLogClose(sb); |
178 | } | 170 | } |
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index 11c58c54b818..2c1f311914a1 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c | |||
@@ -111,8 +111,8 @@ static struct { | |||
111 | /* | 111 | /* |
112 | * forward references | 112 | * forward references |
113 | */ | 113 | */ |
114 | static int xtSearch(struct inode *ip, | 114 | static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp, |
115 | s64 xoff, int *cmpp, struct btstack * btstack, int flag); | 115 | struct btstack * btstack, int flag); |
116 | 116 | ||
117 | static int xtSplitUp(tid_t tid, | 117 | static int xtSplitUp(tid_t tid, |
118 | struct inode *ip, | 118 | struct inode *ip, |
@@ -159,11 +159,12 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
159 | xtpage_t *p; | 159 | xtpage_t *p; |
160 | int index; | 160 | int index; |
161 | xad_t *xad; | 161 | xad_t *xad; |
162 | s64 size, xoff, xend; | 162 | s64 next, size, xoff, xend; |
163 | int xlen; | 163 | int xlen; |
164 | s64 xaddr; | 164 | s64 xaddr; |
165 | 165 | ||
166 | *plen = 0; | 166 | *paddr = 0; |
167 | *plen = llen; | ||
167 | 168 | ||
168 | if (!no_check) { | 169 | if (!no_check) { |
169 | /* is lookup offset beyond eof ? */ | 170 | /* is lookup offset beyond eof ? */ |
@@ -180,7 +181,7 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
180 | * search for the xad entry covering the logical extent | 181 | * search for the xad entry covering the logical extent |
181 | */ | 182 | */ |
182 | //search: | 183 | //search: |
183 | if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) { | 184 | if ((rc = xtSearch(ip, lstart, &next, &cmp, &btstack, 0))) { |
184 | jfs_err("xtLookup: xtSearch returned %d", rc); | 185 | jfs_err("xtLookup: xtSearch returned %d", rc); |
185 | return rc; | 186 | return rc; |
186 | } | 187 | } |
@@ -198,8 +199,11 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
198 | * lstart is a page start address, | 199 | * lstart is a page start address, |
199 | * i.e., lstart cannot start in a hole; | 200 | * i.e., lstart cannot start in a hole; |
200 | */ | 201 | */ |
201 | if (cmp) | 202 | if (cmp) { |
203 | if (next) | ||
204 | *plen = min(next - lstart, llen); | ||
202 | goto out; | 205 | goto out; |
206 | } | ||
203 | 207 | ||
204 | /* | 208 | /* |
205 | * lxd covered by xad | 209 | * lxd covered by xad |
@@ -284,7 +288,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | |||
284 | if (lstart >= size) | 288 | if (lstart >= size) |
285 | return 0; | 289 | return 0; |
286 | 290 | ||
287 | if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) | 291 | if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0))) |
288 | return rc; | 292 | return rc; |
289 | 293 | ||
290 | /* | 294 | /* |
@@ -488,6 +492,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | |||
488 | * parameters: | 492 | * parameters: |
489 | * ip - file object; | 493 | * ip - file object; |
490 | * xoff - extent offset; | 494 | * xoff - extent offset; |
495 | * nextp - address of next extent (if any) for search miss | ||
491 | * cmpp - comparison result: | 496 | * cmpp - comparison result: |
492 | * btstack - traverse stack; | 497 | * btstack - traverse stack; |
493 | * flag - search process flag (XT_INSERT); | 498 | * flag - search process flag (XT_INSERT); |
@@ -497,7 +502,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | |||
497 | * *cmpp is set to result of comparison with the entry returned. | 502 | * *cmpp is set to result of comparison with the entry returned. |
498 | * the page containing the entry is pinned at exit. | 503 | * the page containing the entry is pinned at exit. |
499 | */ | 504 | */ |
500 | static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | 505 | static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, |
501 | int *cmpp, struct btstack * btstack, int flag) | 506 | int *cmpp, struct btstack * btstack, int flag) |
502 | { | 507 | { |
503 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); | 508 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); |
@@ -511,6 +516,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
511 | struct btframe *btsp; | 516 | struct btframe *btsp; |
512 | int nsplit = 0; /* number of pages to split */ | 517 | int nsplit = 0; /* number of pages to split */ |
513 | s64 t64; | 518 | s64 t64; |
519 | s64 next = 0; | ||
514 | 520 | ||
515 | INCREMENT(xtStat.search); | 521 | INCREMENT(xtStat.search); |
516 | 522 | ||
@@ -579,6 +585,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
579 | * previous and this entry | 585 | * previous and this entry |
580 | */ | 586 | */ |
581 | *cmpp = 1; | 587 | *cmpp = 1; |
588 | next = t64; | ||
582 | goto out; | 589 | goto out; |
583 | } | 590 | } |
584 | 591 | ||
@@ -623,6 +630,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
623 | /* update sequential access heuristics */ | 630 | /* update sequential access heuristics */ |
624 | jfs_ip->btindex = index; | 631 | jfs_ip->btindex = index; |
625 | 632 | ||
633 | if (nextp) | ||
634 | *nextp = next; | ||
635 | |||
626 | INCREMENT(xtStat.fastSearch); | 636 | INCREMENT(xtStat.fastSearch); |
627 | return 0; | 637 | return 0; |
628 | } | 638 | } |
@@ -675,10 +685,11 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
675 | 685 | ||
676 | return 0; | 686 | return 0; |
677 | } | 687 | } |
678 | |||
679 | /* search hit - internal page: | 688 | /* search hit - internal page: |
680 | * descend/search its child page | 689 | * descend/search its child page |
681 | */ | 690 | */ |
691 | if (index < p->header.nextindex - 1) | ||
692 | next = offsetXAD(&p->xad[index + 1]); | ||
682 | goto next; | 693 | goto next; |
683 | } | 694 | } |
684 | 695 | ||
@@ -694,6 +705,8 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
694 | * base is the smallest index with key (Kj) greater than | 705 | * base is the smallest index with key (Kj) greater than |
695 | * search key (K) and may be zero or maxentry index. | 706 | * search key (K) and may be zero or maxentry index. |
696 | */ | 707 | */ |
708 | if (base < p->header.nextindex) | ||
709 | next = offsetXAD(&p->xad[base]); | ||
697 | /* | 710 | /* |
698 | * search miss - leaf page: | 711 | * search miss - leaf page: |
699 | * | 712 | * |
@@ -727,6 +740,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
727 | jfs_ip->btorder = BT_RANDOM; | 740 | jfs_ip->btorder = BT_RANDOM; |
728 | jfs_ip->btindex = base; | 741 | jfs_ip->btindex = base; |
729 | 742 | ||
743 | if (nextp) | ||
744 | *nextp = next; | ||
745 | |||
730 | return 0; | 746 | return 0; |
731 | } | 747 | } |
732 | 748 | ||
@@ -793,6 +809,7 @@ int xtInsert(tid_t tid, /* transaction id */ | |||
793 | struct xtsplit split; /* split information */ | 809 | struct xtsplit split; /* split information */ |
794 | xad_t *xad; | 810 | xad_t *xad; |
795 | int cmp; | 811 | int cmp; |
812 | s64 next; | ||
796 | struct tlock *tlck; | 813 | struct tlock *tlck; |
797 | struct xtlock *xtlck; | 814 | struct xtlock *xtlck; |
798 | 815 | ||
@@ -806,7 +823,7 @@ int xtInsert(tid_t tid, /* transaction id */ | |||
806 | * n.b. xtSearch() may return index of maxentry of | 823 | * n.b. xtSearch() may return index of maxentry of |
807 | * the full page. | 824 | * the full page. |
808 | */ | 825 | */ |
809 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) | 826 | if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT))) |
810 | return rc; | 827 | return rc; |
811 | 828 | ||
812 | /* retrieve search result */ | 829 | /* retrieve search result */ |
@@ -814,7 +831,7 @@ int xtInsert(tid_t tid, /* transaction id */ | |||
814 | 831 | ||
815 | /* This test must follow XT_GETSEARCH since mp must be valid if | 832 | /* This test must follow XT_GETSEARCH since mp must be valid if |
816 | * we branch to out: */ | 833 | * we branch to out: */ |
817 | if (cmp == 0) { | 834 | if ((cmp == 0) || (next && (xlen > next - xoff))) { |
818 | rc = -EEXIST; | 835 | rc = -EEXIST; |
819 | goto out; | 836 | goto out; |
820 | } | 837 | } |
@@ -1626,7 +1643,7 @@ int xtExtend(tid_t tid, /* transaction id */ | |||
1626 | jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); | 1643 | jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); |
1627 | 1644 | ||
1628 | /* there must exist extent to be extended */ | 1645 | /* there must exist extent to be extended */ |
1629 | if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT))) | 1646 | if ((rc = xtSearch(ip, xoff - 1, NULL, &cmp, &btstack, XT_INSERT))) |
1630 | return rc; | 1647 | return rc; |
1631 | 1648 | ||
1632 | /* retrieve search result */ | 1649 | /* retrieve search result */ |
@@ -1794,7 +1811,7 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", | |||
1794 | */ | 1811 | */ |
1795 | 1812 | ||
1796 | /* there must exist extent to be tailgated */ | 1813 | /* there must exist extent to be tailgated */ |
1797 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) | 1814 | if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT))) |
1798 | return rc; | 1815 | return rc; |
1799 | 1816 | ||
1800 | /* retrieve search result */ | 1817 | /* retrieve search result */ |
@@ -1977,7 +1994,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) | |||
1977 | nxlen = lengthXAD(nxad); | 1994 | nxlen = lengthXAD(nxad); |
1978 | nxaddr = addressXAD(nxad); | 1995 | nxaddr = addressXAD(nxad); |
1979 | 1996 | ||
1980 | if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) | 1997 | if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT))) |
1981 | return rc; | 1998 | return rc; |
1982 | 1999 | ||
1983 | /* retrieve search result */ | 2000 | /* retrieve search result */ |
@@ -2291,7 +2308,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) | |||
2291 | if (nextindex == le16_to_cpu(p->header.maxentry)) { | 2308 | if (nextindex == le16_to_cpu(p->header.maxentry)) { |
2292 | XT_PUTPAGE(mp); | 2309 | XT_PUTPAGE(mp); |
2293 | 2310 | ||
2294 | if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) | 2311 | if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT))) |
2295 | return rc; | 2312 | return rc; |
2296 | 2313 | ||
2297 | /* retrieve search result */ | 2314 | /* retrieve search result */ |
@@ -2438,6 +2455,7 @@ int xtAppend(tid_t tid, /* transaction id */ | |||
2438 | int nsplit, nblocks, xlen; | 2455 | int nsplit, nblocks, xlen; |
2439 | struct pxdlist pxdlist; | 2456 | struct pxdlist pxdlist; |
2440 | pxd_t *pxd; | 2457 | pxd_t *pxd; |
2458 | s64 next; | ||
2441 | 2459 | ||
2442 | xaddr = *xaddrp; | 2460 | xaddr = *xaddrp; |
2443 | xlen = *xlenp; | 2461 | xlen = *xlenp; |
@@ -2452,7 +2470,7 @@ int xtAppend(tid_t tid, /* transaction id */ | |||
2452 | * n.b. xtSearch() may return index of maxentry of | 2470 | * n.b. xtSearch() may return index of maxentry of |
2453 | * the full page. | 2471 | * the full page. |
2454 | */ | 2472 | */ |
2455 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) | 2473 | if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT))) |
2456 | return rc; | 2474 | return rc; |
2457 | 2475 | ||
2458 | /* retrieve search result */ | 2476 | /* retrieve search result */ |
@@ -2462,6 +2480,9 @@ int xtAppend(tid_t tid, /* transaction id */ | |||
2462 | rc = -EEXIST; | 2480 | rc = -EEXIST; |
2463 | goto out; | 2481 | goto out; |
2464 | } | 2482 | } |
2483 | |||
2484 | if (next) | ||
2485 | xlen = min(xlen, (int)(next - xoff)); | ||
2465 | //insert: | 2486 | //insert: |
2466 | /* | 2487 | /* |
2467 | * insert entry for new extent | 2488 | * insert entry for new extent |
@@ -2600,7 +2621,7 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag) | |||
2600 | /* | 2621 | /* |
2601 | * find the matching entry; xtSearch() pins the page | 2622 | * find the matching entry; xtSearch() pins the page |
2602 | */ | 2623 | */ |
2603 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) | 2624 | if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0))) |
2604 | return rc; | 2625 | return rc; |
2605 | 2626 | ||
2606 | XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); | 2627 | XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); |
@@ -2852,7 +2873,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ | |||
2852 | */ | 2873 | */ |
2853 | if (xtype == DATAEXT) { | 2874 | if (xtype == DATAEXT) { |
2854 | /* search in leaf entry */ | 2875 | /* search in leaf entry */ |
2855 | rc = xtSearch(ip, xoff, &cmp, &btstack, 0); | 2876 | rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0); |
2856 | if (rc) | 2877 | if (rc) |
2857 | return rc; | 2878 | return rc; |
2858 | 2879 | ||
@@ -2958,7 +2979,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ | |||
2958 | } | 2979 | } |
2959 | 2980 | ||
2960 | /* get back parent page */ | 2981 | /* get back parent page */ |
2961 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) | 2982 | if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0))) |
2962 | return rc; | 2983 | return rc; |
2963 | 2984 | ||
2964 | XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); | 2985 | XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); |
@@ -3991,7 +4012,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) | |||
3991 | 4012 | ||
3992 | if (committed_size) { | 4013 | if (committed_size) { |
3993 | xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1; | 4014 | xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1; |
3994 | rc = xtSearch(ip, xoff, &cmp, &btstack, 0); | 4015 | rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0); |
3995 | if (rc) | 4016 | if (rc) |
3996 | return rc; | 4017 | return rc; |
3997 | 4018 | ||
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c index 2eb6869b6e72..c6dc254d3253 100644 --- a/fs/jfs/resize.c +++ b/fs/jfs/resize.c | |||
@@ -209,6 +209,9 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) | |||
209 | */ | 209 | */ |
210 | txQuiesce(sb); | 210 | txQuiesce(sb); |
211 | 211 | ||
212 | /* Reset size of direct inode */ | ||
213 | sbi->direct_inode->i_size = sb->s_bdev->bd_inode->i_size; | ||
214 | |||
212 | if (sbi->mntflag & JFS_INLINELOG) { | 215 | if (sbi->mntflag & JFS_INLINELOG) { |
213 | /* | 216 | /* |
214 | * deactivate old inline log | 217 | * deactivate old inline log |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 5856866e24fc..5e774ed7fb64 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -210,6 +210,10 @@ static void jfs_put_super(struct super_block *sb) | |||
210 | unload_nls(sbi->nls_tab); | 210 | unload_nls(sbi->nls_tab); |
211 | sbi->nls_tab = NULL; | 211 | sbi->nls_tab = NULL; |
212 | 212 | ||
213 | truncate_inode_pages(sbi->direct_inode->i_mapping, 0); | ||
214 | iput(sbi->direct_inode); | ||
215 | sbi->direct_inode = NULL; | ||
216 | |||
213 | kfree(sbi); | 217 | kfree(sbi); |
214 | } | 218 | } |
215 | 219 | ||
@@ -358,6 +362,12 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) | |||
358 | } | 362 | } |
359 | 363 | ||
360 | if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { | 364 | if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { |
365 | /* | ||
366 | * Invalidate any previously read metadata. fsck may have | ||
367 | * changed the on-disk data since we mounted r/o | ||
368 | */ | ||
369 | truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0); | ||
370 | |||
361 | JFS_SBI(sb)->flag = flag; | 371 | JFS_SBI(sb)->flag = flag; |
362 | return jfs_mount_rw(sb, 1); | 372 | return jfs_mount_rw(sb, 1); |
363 | } | 373 | } |
@@ -428,12 +438,26 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
428 | sb->s_op = &jfs_super_operations; | 438 | sb->s_op = &jfs_super_operations; |
429 | sb->s_export_op = &jfs_export_operations; | 439 | sb->s_export_op = &jfs_export_operations; |
430 | 440 | ||
441 | /* | ||
442 | * Initialize direct-mapping inode/address-space | ||
443 | */ | ||
444 | inode = new_inode(sb); | ||
445 | if (inode == NULL) | ||
446 | goto out_kfree; | ||
447 | inode->i_ino = 0; | ||
448 | inode->i_nlink = 1; | ||
449 | inode->i_size = sb->s_bdev->bd_inode->i_size; | ||
450 | inode->i_mapping->a_ops = &jfs_metapage_aops; | ||
451 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); | ||
452 | |||
453 | sbi->direct_inode = inode; | ||
454 | |||
431 | rc = jfs_mount(sb); | 455 | rc = jfs_mount(sb); |
432 | if (rc) { | 456 | if (rc) { |
433 | if (!silent) { | 457 | if (!silent) { |
434 | jfs_err("jfs_mount failed w/return code = %d", rc); | 458 | jfs_err("jfs_mount failed w/return code = %d", rc); |
435 | } | 459 | } |
436 | goto out_kfree; | 460 | goto out_mount_failed; |
437 | } | 461 | } |
438 | if (sb->s_flags & MS_RDONLY) | 462 | if (sb->s_flags & MS_RDONLY) |
439 | sbi->log = NULL; | 463 | sbi->log = NULL; |
@@ -482,6 +506,13 @@ out_no_rw: | |||
482 | if (rc) { | 506 | if (rc) { |
483 | jfs_err("jfs_umount failed with return code %d", rc); | 507 | jfs_err("jfs_umount failed with return code %d", rc); |
484 | } | 508 | } |
509 | out_mount_failed: | ||
510 | filemap_fdatawrite(sbi->direct_inode->i_mapping); | ||
511 | filemap_fdatawait(sbi->direct_inode->i_mapping); | ||
512 | truncate_inode_pages(sbi->direct_inode->i_mapping, 0); | ||
513 | make_bad_inode(sbi->direct_inode); | ||
514 | iput(sbi->direct_inode); | ||
515 | sbi->direct_inode = NULL; | ||
485 | out_kfree: | 516 | out_kfree: |
486 | if (sbi->nls_tab) | 517 | if (sbi->nls_tab) |
487 | unload_nls(sbi->nls_tab); | 518 | unload_nls(sbi->nls_tab); |
@@ -527,8 +558,10 @@ static int jfs_sync_fs(struct super_block *sb, int wait) | |||
527 | struct jfs_log *log = JFS_SBI(sb)->log; | 558 | struct jfs_log *log = JFS_SBI(sb)->log; |
528 | 559 | ||
529 | /* log == NULL indicates read-only mount */ | 560 | /* log == NULL indicates read-only mount */ |
530 | if (log) | 561 | if (log) { |
531 | jfs_flush_journal(log, wait); | 562 | jfs_flush_journal(log, wait); |
563 | jfs_syncpt(log); | ||
564 | } | ||
532 | 565 | ||
533 | return 0; | 566 | return 0; |
534 | } | 567 | } |
diff --git a/fs/mpage.c b/fs/mpage.c index e7d8d1a77606..32c7c8fcfce7 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -160,52 +160,6 @@ map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block) | |||
160 | } while (page_bh != head); | 160 | } while (page_bh != head); |
161 | } | 161 | } |
162 | 162 | ||
163 | /** | ||
164 | * mpage_readpages - populate an address space with some pages, and | ||
165 | * start reads against them. | ||
166 | * | ||
167 | * @mapping: the address_space | ||
168 | * @pages: The address of a list_head which contains the target pages. These | ||
169 | * pages have their ->index populated and are otherwise uninitialised. | ||
170 | * | ||
171 | * The page at @pages->prev has the lowest file offset, and reads should be | ||
172 | * issued in @pages->prev to @pages->next order. | ||
173 | * | ||
174 | * @nr_pages: The number of pages at *@pages | ||
175 | * @get_block: The filesystem's block mapper function. | ||
176 | * | ||
177 | * This function walks the pages and the blocks within each page, building and | ||
178 | * emitting large BIOs. | ||
179 | * | ||
180 | * If anything unusual happens, such as: | ||
181 | * | ||
182 | * - encountering a page which has buffers | ||
183 | * - encountering a page which has a non-hole after a hole | ||
184 | * - encountering a page with non-contiguous blocks | ||
185 | * | ||
186 | * then this code just gives up and calls the buffer_head-based read function. | ||
187 | * It does handle a page which has holes at the end - that is a common case: | ||
188 | * the end-of-file on blocksize < PAGE_CACHE_SIZE setups. | ||
189 | * | ||
190 | * BH_Boundary explanation: | ||
191 | * | ||
192 | * There is a problem. The mpage read code assembles several pages, gets all | ||
193 | * their disk mappings, and then submits them all. That's fine, but obtaining | ||
194 | * the disk mappings may require I/O. Reads of indirect blocks, for example. | ||
195 | * | ||
196 | * So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be | ||
197 | * submitted in the following order: | ||
198 | * 12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 | ||
199 | * because the indirect block has to be read to get the mappings of blocks | ||
200 | * 13,14,15,16. Obviously, this impacts performance. | ||
201 | * | ||
202 | * So what we do it to allow the filesystem's get_block() function to set | ||
203 | * BH_Boundary when it maps block 11. BH_Boundary says: mapping of the block | ||
204 | * after this one will require I/O against a block which is probably close to | ||
205 | * this one. So you should push what I/O you have currently accumulated. | ||
206 | * | ||
207 | * This all causes the disk requests to be issued in the correct order. | ||
208 | */ | ||
209 | static struct bio * | 163 | static struct bio * |
210 | do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages, | 164 | do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages, |
211 | sector_t *last_block_in_bio, get_block_t get_block) | 165 | sector_t *last_block_in_bio, get_block_t get_block) |
@@ -320,6 +274,52 @@ confused: | |||
320 | goto out; | 274 | goto out; |
321 | } | 275 | } |
322 | 276 | ||
277 | /** | ||
278 | * mpage_readpages - populate an address space with some pages, and | ||
279 | * start reads against them. | ||
280 | * | ||
281 | * @mapping: the address_space | ||
282 | * @pages: The address of a list_head which contains the target pages. These | ||
283 | * pages have their ->index populated and are otherwise uninitialised. | ||
284 | * | ||
285 | * The page at @pages->prev has the lowest file offset, and reads should be | ||
286 | * issued in @pages->prev to @pages->next order. | ||
287 | * | ||
288 | * @nr_pages: The number of pages at *@pages | ||
289 | * @get_block: The filesystem's block mapper function. | ||
290 | * | ||
291 | * This function walks the pages and the blocks within each page, building and | ||
292 | * emitting large BIOs. | ||
293 | * | ||
294 | * If anything unusual happens, such as: | ||
295 | * | ||
296 | * - encountering a page which has buffers | ||
297 | * - encountering a page which has a non-hole after a hole | ||
298 | * - encountering a page with non-contiguous blocks | ||
299 | * | ||
300 | * then this code just gives up and calls the buffer_head-based read function. | ||
301 | * It does handle a page which has holes at the end - that is a common case: | ||
302 | * the end-of-file on blocksize < PAGE_CACHE_SIZE setups. | ||
303 | * | ||
304 | * BH_Boundary explanation: | ||
305 | * | ||
306 | * There is a problem. The mpage read code assembles several pages, gets all | ||
307 | * their disk mappings, and then submits them all. That's fine, but obtaining | ||
308 | * the disk mappings may require I/O. Reads of indirect blocks, for example. | ||
309 | * | ||
310 | * So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be | ||
311 | * submitted in the following order: | ||
312 | * 12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 | ||
313 | * because the indirect block has to be read to get the mappings of blocks | ||
314 | * 13,14,15,16. Obviously, this impacts performance. | ||
315 | * | ||
316 | * So what we do it to allow the filesystem's get_block() function to set | ||
317 | * BH_Boundary when it maps block 11. BH_Boundary says: mapping of the block | ||
318 | * after this one will require I/O against a block which is probably close to | ||
319 | * this one. So you should push what I/O you have currently accumulated. | ||
320 | * | ||
321 | * This all causes the disk requests to be issued in the correct order. | ||
322 | */ | ||
323 | int | 323 | int |
324 | mpage_readpages(struct address_space *mapping, struct list_head *pages, | 324 | mpage_readpages(struct address_space *mapping, struct list_head *pages, |
325 | unsigned nr_pages, get_block_t get_block) | 325 | unsigned nr_pages, get_block_t get_block) |
@@ -727,6 +727,8 @@ retry: | |||
727 | &last_block_in_bio, &ret, wbc, | 727 | &last_block_in_bio, &ret, wbc, |
728 | writepage_fn); | 728 | writepage_fn); |
729 | } | 729 | } |
730 | if (unlikely(ret == WRITEPAGE_ACTIVATE)) | ||
731 | unlock_page(page); | ||
730 | if (ret || (--(wbc->nr_to_write) <= 0)) | 732 | if (ret || (--(wbc->nr_to_write) <= 0)) |
731 | done = 1; | 733 | done = 1; |
732 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 734 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 39fd336cfdb9..07cafdf74ef2 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1419,6 +1419,8 @@ static struct file_operations proc_tgid_attr_operations; | |||
1419 | static struct inode_operations proc_tgid_attr_inode_operations; | 1419 | static struct inode_operations proc_tgid_attr_inode_operations; |
1420 | #endif | 1420 | #endif |
1421 | 1421 | ||
1422 | static int get_tid_list(int index, unsigned int *tids, struct inode *dir); | ||
1423 | |||
1422 | /* SMP-safe */ | 1424 | /* SMP-safe */ |
1423 | static struct dentry *proc_pident_lookup(struct inode *dir, | 1425 | static struct dentry *proc_pident_lookup(struct inode *dir, |
1424 | struct dentry *dentry, | 1426 | struct dentry *dentry, |
@@ -1458,7 +1460,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
1458 | */ | 1460 | */ |
1459 | switch(p->type) { | 1461 | switch(p->type) { |
1460 | case PROC_TGID_TASK: | 1462 | case PROC_TGID_TASK: |
1461 | inode->i_nlink = 3; | 1463 | inode->i_nlink = 2 + get_tid_list(2, NULL, dir); |
1462 | inode->i_op = &proc_task_inode_operations; | 1464 | inode->i_op = &proc_task_inode_operations; |
1463 | inode->i_fop = &proc_task_operations; | 1465 | inode->i_fop = &proc_task_operations; |
1464 | break; | 1466 | break; |
@@ -1701,13 +1703,13 @@ static struct inode_operations proc_self_inode_operations = { | |||
1701 | }; | 1703 | }; |
1702 | 1704 | ||
1703 | /** | 1705 | /** |
1704 | * proc_pid_unhash - Unhash /proc/<pid> entry from the dcache. | 1706 | * proc_pid_unhash - Unhash /proc/@pid entry from the dcache. |
1705 | * @p: task that should be flushed. | 1707 | * @p: task that should be flushed. |
1706 | * | 1708 | * |
1707 | * Drops the /proc/<pid> dcache entry from the hash chains. | 1709 | * Drops the /proc/@pid dcache entry from the hash chains. |
1708 | * | 1710 | * |
1709 | * Dropping /proc/<pid> entries and detach_pid must be synchroneous, | 1711 | * Dropping /proc/@pid entries and detach_pid must be synchroneous, |
1710 | * otherwise e.g. /proc/<pid>/exe might point to the wrong executable, | 1712 | * otherwise e.g. /proc/@pid/exe might point to the wrong executable, |
1711 | * if the pid value is immediately reused. This is enforced by | 1713 | * if the pid value is immediately reused. This is enforced by |
1712 | * - caller must acquire spin_lock(p->proc_lock) | 1714 | * - caller must acquire spin_lock(p->proc_lock) |
1713 | * - must be called before detach_pid() | 1715 | * - must be called before detach_pid() |
@@ -1739,8 +1741,8 @@ struct dentry *proc_pid_unhash(struct task_struct *p) | |||
1739 | } | 1741 | } |
1740 | 1742 | ||
1741 | /** | 1743 | /** |
1742 | * proc_pid_flush - recover memory used by stale /proc/<pid>/x entries | 1744 | * proc_pid_flush - recover memory used by stale /proc/@pid/x entries |
1743 | * @proc_entry: directoy to prune. | 1745 | * @proc_dentry: directoy to prune. |
1744 | * | 1746 | * |
1745 | * Shrink the /proc directory that was used by the just killed thread. | 1747 | * Shrink the /proc directory that was used by the just killed thread. |
1746 | */ | 1748 | */ |
@@ -1800,8 +1802,12 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
1800 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; | 1802 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; |
1801 | inode->i_op = &proc_tgid_base_inode_operations; | 1803 | inode->i_op = &proc_tgid_base_inode_operations; |
1802 | inode->i_fop = &proc_tgid_base_operations; | 1804 | inode->i_fop = &proc_tgid_base_operations; |
1803 | inode->i_nlink = 3; | ||
1804 | inode->i_flags|=S_IMMUTABLE; | 1805 | inode->i_flags|=S_IMMUTABLE; |
1806 | #ifdef CONFIG_SECURITY | ||
1807 | inode->i_nlink = 5; | ||
1808 | #else | ||
1809 | inode->i_nlink = 4; | ||
1810 | #endif | ||
1805 | 1811 | ||
1806 | dentry->d_op = &pid_base_dentry_operations; | 1812 | dentry->d_op = &pid_base_dentry_operations; |
1807 | 1813 | ||
@@ -1855,8 +1861,12 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
1855 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; | 1861 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; |
1856 | inode->i_op = &proc_tid_base_inode_operations; | 1862 | inode->i_op = &proc_tid_base_inode_operations; |
1857 | inode->i_fop = &proc_tid_base_operations; | 1863 | inode->i_fop = &proc_tid_base_operations; |
1858 | inode->i_nlink = 3; | ||
1859 | inode->i_flags|=S_IMMUTABLE; | 1864 | inode->i_flags|=S_IMMUTABLE; |
1865 | #ifdef CONFIG_SECURITY | ||
1866 | inode->i_nlink = 4; | ||
1867 | #else | ||
1868 | inode->i_nlink = 3; | ||
1869 | #endif | ||
1860 | 1870 | ||
1861 | dentry->d_op = &pid_base_dentry_operations; | 1871 | dentry->d_op = &pid_base_dentry_operations; |
1862 | 1872 | ||
@@ -1935,7 +1945,8 @@ static int get_tid_list(int index, unsigned int *tids, struct inode *dir) | |||
1935 | 1945 | ||
1936 | if (--index >= 0) | 1946 | if (--index >= 0) |
1937 | continue; | 1947 | continue; |
1938 | tids[nr_tids] = tid; | 1948 | if (tids != NULL) |
1949 | tids[nr_tids] = tid; | ||
1939 | nr_tids++; | 1950 | nr_tids++; |
1940 | if (nr_tids >= PROC_MAXPIDS) | 1951 | if (nr_tids >= PROC_MAXPIDS) |
1941 | break; | 1952 | break; |
@@ -2035,6 +2046,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2035 | } | 2046 | } |
2036 | 2047 | ||
2037 | nr_tids = get_tid_list(pos, tid_array, inode); | 2048 | nr_tids = get_tid_list(pos, tid_array, inode); |
2049 | inode->i_nlink = pos + nr_tids; | ||
2038 | 2050 | ||
2039 | for (i = 0; i < nr_tids; i++) { | 2051 | for (i = 0; i < nr_tids; i++) { |
2040 | unsigned long j = PROC_NUMBUF; | 2052 | unsigned long j = PROC_NUMBUF; |
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index a4e2ed544bbe..49c479c9454a 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -260,8 +260,9 @@ static inline int block_group_used(struct super_block *s, u32 id) { | |||
260 | /* | 260 | /* |
261 | * the packing is returned in disk byte order | 261 | * the packing is returned in disk byte order |
262 | */ | 262 | */ |
263 | u32 reiserfs_choose_packing(struct inode *dir) { | 263 | __le32 reiserfs_choose_packing(struct inode *dir) |
264 | u32 packing; | 264 | { |
265 | __le32 packing; | ||
265 | if (TEST_OPTION(packing_groups, dir->i_sb)) { | 266 | if (TEST_OPTION(packing_groups, dir->i_sb)) { |
266 | u32 parent_dir = le32_to_cpu(INODE_PKEY(dir)->k_dir_id); | 267 | u32 parent_dir = le32_to_cpu(INODE_PKEY(dir)->k_dir_id); |
267 | /* | 268 | /* |
@@ -655,7 +656,7 @@ static int get_left_neighbor(reiserfs_blocknr_hint_t *hint) | |||
655 | struct buffer_head * bh; | 656 | struct buffer_head * bh; |
656 | struct item_head * ih; | 657 | struct item_head * ih; |
657 | int pos_in_item; | 658 | int pos_in_item; |
658 | __u32 * item; | 659 | __le32 * item; |
659 | int ret = 0; | 660 | int ret = 0; |
660 | 661 | ||
661 | if (!hint->path) /* reiserfs code can call this function w/o pointer to path | 662 | if (!hint->path) /* reiserfs code can call this function w/o pointer to path |
@@ -736,7 +737,7 @@ static inline int this_blocknr_allocation_would_make_it_a_large_file(reiserfs_bl | |||
736 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES | 737 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES |
737 | static inline void displace_new_packing_locality (reiserfs_blocknr_hint_t *hint) | 738 | static inline void displace_new_packing_locality (reiserfs_blocknr_hint_t *hint) |
738 | { | 739 | { |
739 | struct reiserfs_key * key = &hint->key; | 740 | struct in_core_key * key = &hint->key; |
740 | 741 | ||
741 | hint->th->displace_new_blocks = 0; | 742 | hint->th->displace_new_blocks = 0; |
742 | hint->search_start = hint->beg + keyed_hash((char*)(&key->k_objectid),4) % (hint->end - hint->beg); | 743 | hint->search_start = hint->beg + keyed_hash((char*)(&key->k_objectid),4) % (hint->end - hint->beg); |
@@ -777,7 +778,7 @@ static inline int old_way (reiserfs_blocknr_hint_t * hint) | |||
777 | 778 | ||
778 | static inline void hundredth_slices (reiserfs_blocknr_hint_t * hint) | 779 | static inline void hundredth_slices (reiserfs_blocknr_hint_t * hint) |
779 | { | 780 | { |
780 | struct reiserfs_key * key = &hint->key; | 781 | struct in_core_key * key = &hint->key; |
781 | b_blocknr_t slice_start; | 782 | b_blocknr_t slice_start; |
782 | 783 | ||
783 | slice_start = (keyed_hash((char*)(&key->k_dir_id),4) % 100) * (hint->end / 100); | 784 | slice_start = (keyed_hash((char*)(&key->k_dir_id),4) % 100) * (hint->end / 100); |
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index d1514a9b0514..fbde4b01a325 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -209,8 +209,8 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi | |||
209 | /* compose directory item containing "." and ".." entries (entries are | 209 | /* compose directory item containing "." and ".." entries (entries are |
210 | not aligned to 4 byte boundary) */ | 210 | not aligned to 4 byte boundary) */ |
211 | /* the last four params are LE */ | 211 | /* the last four params are LE */ |
212 | void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid, | 212 | void make_empty_dir_item_v1 (char * body, __le32 dirid, __le32 objid, |
213 | __u32 par_dirid, __u32 par_objid) | 213 | __le32 par_dirid, __le32 par_objid) |
214 | { | 214 | { |
215 | struct reiserfs_de_head * deh; | 215 | struct reiserfs_de_head * deh; |
216 | 216 | ||
@@ -242,8 +242,8 @@ void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid, | |||
242 | } | 242 | } |
243 | 243 | ||
244 | /* compose directory item containing "." and ".." entries */ | 244 | /* compose directory item containing "." and ".." entries */ |
245 | void make_empty_dir_item (char * body, __u32 dirid, __u32 objid, | 245 | void make_empty_dir_item (char * body, __le32 dirid, __le32 objid, |
246 | __u32 par_dirid, __u32 par_objid) | 246 | __le32 par_dirid, __le32 par_objid) |
247 | { | 247 | { |
248 | struct reiserfs_de_head * deh; | 248 | struct reiserfs_de_head * deh; |
249 | 249 | ||
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 26950113af8c..2230afff1870 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -166,7 +166,7 @@ static int reiserfs_allocate_blocks_for_region( | |||
166 | struct cpu_key key; // cpu key of item that we are going to deal with | 166 | struct cpu_key key; // cpu key of item that we are going to deal with |
167 | struct item_head *ih; // pointer to item head that we are going to deal with | 167 | struct item_head *ih; // pointer to item head that we are going to deal with |
168 | struct buffer_head *bh; // Buffer head that contains items that we are going to deal with | 168 | struct buffer_head *bh; // Buffer head that contains items that we are going to deal with |
169 | __u32 * item; // pointer to item we are going to deal with | 169 | __le32 * item; // pointer to item we are going to deal with |
170 | INITIALIZE_PATH(path); // path to item, that we are going to deal with. | 170 | INITIALIZE_PATH(path); // path to item, that we are going to deal with. |
171 | b_blocknr_t *allocated_blocks; // Pointer to a place where allocated blocknumbers would be stored. | 171 | b_blocknr_t *allocated_blocks; // Pointer to a place where allocated blocknumbers would be stored. |
172 | reiserfs_blocknr_hint_t hint; // hint structure for block allocator. | 172 | reiserfs_blocknr_hint_t hint; // hint structure for block allocator. |
@@ -891,7 +891,7 @@ static int reiserfs_prepare_file_region_for_write( | |||
891 | struct item_head *ih = NULL; // pointer to item head that we are going to deal with | 891 | struct item_head *ih = NULL; // pointer to item head that we are going to deal with |
892 | struct buffer_head *itembuf=NULL; // Buffer head that contains items that we are going to deal with | 892 | struct buffer_head *itembuf=NULL; // Buffer head that contains items that we are going to deal with |
893 | INITIALIZE_PATH(path); // path to item, that we are going to deal with. | 893 | INITIALIZE_PATH(path); // path to item, that we are going to deal with. |
894 | __u32 * item=NULL; // pointer to item we are going to deal with | 894 | __le32 * item=NULL; // pointer to item we are going to deal with |
895 | int item_pos=-1; /* Position in indirect item */ | 895 | int item_pos=-1; /* Position in indirect item */ |
896 | 896 | ||
897 | 897 | ||
@@ -1284,10 +1284,11 @@ static ssize_t reiserfs_file_write( struct file *file, /* the file we are going | |||
1284 | reiserfs_claim_blocks_to_be_allocated(inode->i_sb, num_pages << (PAGE_CACHE_SHIFT - inode->i_blkbits)); | 1284 | reiserfs_claim_blocks_to_be_allocated(inode->i_sb, num_pages << (PAGE_CACHE_SHIFT - inode->i_blkbits)); |
1285 | reiserfs_write_unlock(inode->i_sb); | 1285 | reiserfs_write_unlock(inode->i_sb); |
1286 | 1286 | ||
1287 | if ( !num_pages ) { /* If we do not have enough space even for */ | 1287 | if ( !num_pages ) { /* If we do not have enough space even for a single page... */ |
1288 | res = -ENOSPC; /* single page, return -ENOSPC */ | 1288 | if ( pos > inode->i_size+inode->i_sb->s_blocksize-(pos & (inode->i_sb->s_blocksize-1))) { |
1289 | if ( pos > (inode->i_size & (inode->i_sb->s_blocksize-1))) | 1289 | res = -ENOSPC; |
1290 | break; // In case we are writing past the file end, break. | 1290 | break; // In case we are writing past the end of the last file block, break. |
1291 | } | ||
1291 | // Otherwise we are possibly overwriting the file, so | 1292 | // Otherwise we are possibly overwriting the file, so |
1292 | // let's set write size to be equal or less than blocksize. | 1293 | // let's set write size to be equal or less than blocksize. |
1293 | // This way we get it correctly for file holes. | 1294 | // This way we get it correctly for file holes. |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 7543031396f4..2711dff1b7b4 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -173,7 +173,7 @@ static inline void fix_tail_page_for_writing(struct page *page) { | |||
173 | done already or non-hole position has been found in the indirect item */ | 173 | done already or non-hole position has been found in the indirect item */ |
174 | static inline int allocation_needed (int retval, b_blocknr_t allocated, | 174 | static inline int allocation_needed (int retval, b_blocknr_t allocated, |
175 | struct item_head * ih, | 175 | struct item_head * ih, |
176 | __u32 * item, int pos_in_item) | 176 | __le32 * item, int pos_in_item) |
177 | { | 177 | { |
178 | if (allocated) | 178 | if (allocated) |
179 | return 0; | 179 | return 0; |
@@ -278,7 +278,7 @@ research: | |||
278 | bh = get_last_bh (&path); | 278 | bh = get_last_bh (&path); |
279 | ih = get_ih (&path); | 279 | ih = get_ih (&path); |
280 | if (is_indirect_le_ih (ih)) { | 280 | if (is_indirect_le_ih (ih)) { |
281 | __u32 * ind_item = (__u32 *)B_I_PITEM (bh, ih); | 281 | __le32 * ind_item = (__le32 *)B_I_PITEM (bh, ih); |
282 | 282 | ||
283 | /* FIXME: here we could cache indirect item or part of it in | 283 | /* FIXME: here we could cache indirect item or part of it in |
284 | the inode to avoid search_by_key in case of subsequent | 284 | the inode to avoid search_by_key in case of subsequent |
@@ -581,7 +581,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block, | |||
581 | struct cpu_key key; | 581 | struct cpu_key key; |
582 | struct buffer_head * bh, * unbh = NULL; | 582 | struct buffer_head * bh, * unbh = NULL; |
583 | struct item_head * ih, tmp_ih; | 583 | struct item_head * ih, tmp_ih; |
584 | __u32 * item; | 584 | __le32 * item; |
585 | int done; | 585 | int done; |
586 | int fs_gen; | 586 | int fs_gen; |
587 | struct reiserfs_transaction_handle *th = NULL; | 587 | struct reiserfs_transaction_handle *th = NULL; |
@@ -746,7 +746,7 @@ start_trans: | |||
746 | done = 0; | 746 | done = 0; |
747 | do { | 747 | do { |
748 | if (is_statdata_le_ih (ih)) { | 748 | if (is_statdata_le_ih (ih)) { |
749 | __u32 unp = 0; | 749 | __le32 unp = 0; |
750 | struct cpu_key tmp_key; | 750 | struct cpu_key tmp_key; |
751 | 751 | ||
752 | /* indirect item has to be inserted */ | 752 | /* indirect item has to be inserted */ |
@@ -1341,8 +1341,8 @@ void reiserfs_read_locked_inode (struct inode * inode, struct reiserfs_iget_args | |||
1341 | key.version = KEY_FORMAT_3_5; | 1341 | key.version = KEY_FORMAT_3_5; |
1342 | key.on_disk_key.k_dir_id = dirino; | 1342 | key.on_disk_key.k_dir_id = dirino; |
1343 | key.on_disk_key.k_objectid = inode->i_ino; | 1343 | key.on_disk_key.k_objectid = inode->i_ino; |
1344 | key.on_disk_key.u.k_offset_v1.k_offset = SD_OFFSET; | 1344 | key.on_disk_key.k_offset = 0; |
1345 | key.on_disk_key.u.k_offset_v1.k_uniqueness = SD_UNIQUENESS; | 1345 | key.on_disk_key.k_type = 0; |
1346 | 1346 | ||
1347 | /* look for the object's stat data */ | 1347 | /* look for the object's stat data */ |
1348 | retval = search_item (inode->i_sb, &key, &path_to_sd); | 1348 | retval = search_item (inode->i_sb, &key, &path_to_sd); |
@@ -2067,7 +2067,7 @@ static int map_block_for_writepage(struct inode *inode, | |||
2067 | struct item_head tmp_ih ; | 2067 | struct item_head tmp_ih ; |
2068 | struct item_head *ih ; | 2068 | struct item_head *ih ; |
2069 | struct buffer_head *bh ; | 2069 | struct buffer_head *bh ; |
2070 | __u32 *item ; | 2070 | __le32 *item ; |
2071 | struct cpu_key key ; | 2071 | struct cpu_key key ; |
2072 | INITIALIZE_PATH(path) ; | 2072 | INITIALIZE_PATH(path) ; |
2073 | int pos_in_item ; | 2073 | int pos_in_item ; |
diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c index 9cf7c13b120d..0ce33db1acdf 100644 --- a/fs/reiserfs/item_ops.c +++ b/fs/reiserfs/item_ops.c | |||
@@ -296,10 +296,11 @@ static void print_sequence (__u32 start, int len) | |||
296 | static void indirect_print_item (struct item_head * ih, char * item) | 296 | static void indirect_print_item (struct item_head * ih, char * item) |
297 | { | 297 | { |
298 | int j; | 298 | int j; |
299 | __u32 * unp, prev = INT_MAX; | 299 | __le32 * unp; |
300 | __u32 prev = INT_MAX; | ||
300 | int num; | 301 | int num; |
301 | 302 | ||
302 | unp = (__u32 *)item; | 303 | unp = (__le32 *)item; |
303 | 304 | ||
304 | if (ih_item_len(ih) % UNFM_P_SIZE) | 305 | if (ih_item_len(ih) % UNFM_P_SIZE) |
305 | reiserfs_warning (NULL, "indirect_print_item: invalid item len"); | 306 | reiserfs_warning (NULL, "indirect_print_item: invalid item len"); |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index c9ad3a7849f4..3072cfdee959 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -2306,13 +2306,16 @@ static int journal_init_dev( struct super_block *super, | |||
2306 | if( !IS_ERR( journal -> j_dev_file ) ) { | 2306 | if( !IS_ERR( journal -> j_dev_file ) ) { |
2307 | struct inode *jdev_inode = journal->j_dev_file->f_mapping->host; | 2307 | struct inode *jdev_inode = journal->j_dev_file->f_mapping->host; |
2308 | if( !S_ISBLK( jdev_inode -> i_mode ) ) { | 2308 | if( !S_ISBLK( jdev_inode -> i_mode ) ) { |
2309 | reiserfs_warning (super, "journal_init_dev: '%s' is " | 2309 | reiserfs_warning(super, "journal_init_dev: '%s' is " |
2310 | "not a block device", jdev_name ); | 2310 | "not a block device", jdev_name ); |
2311 | result = -ENOTBLK; | 2311 | result = -ENOTBLK; |
2312 | release_journal_dev( super, journal ); | ||
2312 | } else { | 2313 | } else { |
2313 | /* ok */ | 2314 | /* ok */ |
2314 | journal->j_dev_bd = I_BDEV(jdev_inode); | 2315 | journal->j_dev_bd = I_BDEV(jdev_inode); |
2315 | set_blocksize(journal->j_dev_bd, super->s_blocksize); | 2316 | set_blocksize(journal->j_dev_bd, super->s_blocksize); |
2317 | reiserfs_info(super, "journal_init_dev: journal device: %s\n", | ||
2318 | bdevname(journal->j_dev_bd, b)); | ||
2316 | } | 2319 | } |
2317 | } else { | 2320 | } else { |
2318 | result = PTR_ERR( journal -> j_dev_file ); | 2321 | result = PTR_ERR( journal -> j_dev_file ); |
@@ -2321,11 +2324,6 @@ static int journal_init_dev( struct super_block *super, | |||
2321 | "journal_init_dev: Cannot open '%s': %i", | 2324 | "journal_init_dev: Cannot open '%s': %i", |
2322 | jdev_name, result ); | 2325 | jdev_name, result ); |
2323 | } | 2326 | } |
2324 | if( result != 0 ) { | ||
2325 | release_journal_dev( super, journal ); | ||
2326 | } | ||
2327 | reiserfs_info(super, "journal_init_dev: journal device: %s\n", | ||
2328 | bdevname(journal->j_dev_bd, b)); | ||
2329 | return result; | 2327 | return result; |
2330 | } | 2328 | } |
2331 | 2329 | ||
@@ -2393,7 +2391,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo | |||
2393 | jh = (struct reiserfs_journal_header *)(bhjh->b_data); | 2391 | jh = (struct reiserfs_journal_header *)(bhjh->b_data); |
2394 | 2392 | ||
2395 | /* make sure that journal matches to the super block */ | 2393 | /* make sure that journal matches to the super block */ |
2396 | if (is_reiserfs_jr(rs) && (jh->jh_journal.jp_journal_magic != sb_jp_journal_magic(rs))) { | 2394 | if (is_reiserfs_jr(rs) && (le32_to_cpu(jh->jh_journal.jp_journal_magic) != sb_jp_journal_magic(rs))) { |
2397 | reiserfs_warning (p_s_sb, "sh-460: journal header magic %x " | 2395 | reiserfs_warning (p_s_sb, "sh-460: journal header magic %x " |
2398 | "(device %s) does not match to magic found in super " | 2396 | "(device %s) does not match to magic found in super " |
2399 | "block %x", | 2397 | "block %x", |
diff --git a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c index 0785c43a7486..bfe8e25ef293 100644 --- a/fs/reiserfs/objectid.c +++ b/fs/reiserfs/objectid.c | |||
@@ -11,13 +11,13 @@ | |||
11 | 11 | ||
12 | // find where objectid map starts | 12 | // find where objectid map starts |
13 | #define objectid_map(s,rs) (old_format_only (s) ? \ | 13 | #define objectid_map(s,rs) (old_format_only (s) ? \ |
14 | (__u32 *)((struct reiserfs_super_block_v1 *)(rs) + 1) :\ | 14 | (__le32 *)((struct reiserfs_super_block_v1 *)(rs) + 1) :\ |
15 | (__u32 *)((rs) + 1)) | 15 | (__le32 *)((rs) + 1)) |
16 | 16 | ||
17 | 17 | ||
18 | #ifdef CONFIG_REISERFS_CHECK | 18 | #ifdef CONFIG_REISERFS_CHECK |
19 | 19 | ||
20 | static void check_objectid_map (struct super_block * s, __u32 * map) | 20 | static void check_objectid_map (struct super_block * s, __le32 * map) |
21 | { | 21 | { |
22 | if (le32_to_cpu (map[0]) != 1) | 22 | if (le32_to_cpu (map[0]) != 1) |
23 | reiserfs_panic (s, "vs-15010: check_objectid_map: map corrupted: %lx", | 23 | reiserfs_panic (s, "vs-15010: check_objectid_map: map corrupted: %lx", |
@@ -27,7 +27,7 @@ static void check_objectid_map (struct super_block * s, __u32 * map) | |||
27 | } | 27 | } |
28 | 28 | ||
29 | #else | 29 | #else |
30 | static void check_objectid_map (struct super_block * s, __u32 * map) | 30 | static void check_objectid_map (struct super_block * s, __le32 * map) |
31 | {;} | 31 | {;} |
32 | #endif | 32 | #endif |
33 | 33 | ||
@@ -52,7 +52,7 @@ __u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th) | |||
52 | { | 52 | { |
53 | struct super_block * s = th->t_super; | 53 | struct super_block * s = th->t_super; |
54 | struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); | 54 | struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); |
55 | __u32 * map = objectid_map (s, rs); | 55 | __le32 * map = objectid_map (s, rs); |
56 | __u32 unused_objectid; | 56 | __u32 unused_objectid; |
57 | 57 | ||
58 | BUG_ON (!th->t_trans_id); | 58 | BUG_ON (!th->t_trans_id); |
@@ -97,7 +97,7 @@ void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, | |||
97 | { | 97 | { |
98 | struct super_block * s = th->t_super; | 98 | struct super_block * s = th->t_super; |
99 | struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); | 99 | struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); |
100 | __u32 * map = objectid_map (s, rs); | 100 | __le32 * map = objectid_map (s, rs); |
101 | int i = 0; | 101 | int i = 0; |
102 | 102 | ||
103 | BUG_ON (!th->t_trans_id); | 103 | BUG_ON (!th->t_trans_id); |
@@ -172,12 +172,12 @@ int reiserfs_convert_objectid_map_v1(struct super_block *s) { | |||
172 | int new_size = (s->s_blocksize - SB_SIZE) / sizeof(__u32) / 2 * 2 ; | 172 | int new_size = (s->s_blocksize - SB_SIZE) / sizeof(__u32) / 2 * 2 ; |
173 | int old_max = sb_oid_maxsize(disk_sb); | 173 | int old_max = sb_oid_maxsize(disk_sb); |
174 | struct reiserfs_super_block_v1 *disk_sb_v1 ; | 174 | struct reiserfs_super_block_v1 *disk_sb_v1 ; |
175 | __u32 *objectid_map, *new_objectid_map ; | 175 | __le32 *objectid_map, *new_objectid_map ; |
176 | int i ; | 176 | int i ; |
177 | 177 | ||
178 | disk_sb_v1=(struct reiserfs_super_block_v1 *)(SB_BUFFER_WITH_SB(s)->b_data); | 178 | disk_sb_v1=(struct reiserfs_super_block_v1 *)(SB_BUFFER_WITH_SB(s)->b_data); |
179 | objectid_map = (__u32 *)(disk_sb_v1 + 1) ; | 179 | objectid_map = (__le32 *)(disk_sb_v1 + 1) ; |
180 | new_objectid_map = (__u32 *)(disk_sb + 1) ; | 180 | new_objectid_map = (__le32 *)(disk_sb + 1) ; |
181 | 181 | ||
182 | if (cur_size > new_size) { | 182 | if (cur_size > new_size) { |
183 | /* mark everyone used that was listed as free at the end of the objectid | 183 | /* mark everyone used that was listed as free at the end of the objectid |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index f4ea81ae0e0f..e242ebc7f6f6 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -73,8 +73,8 @@ int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset, | |||
73 | #define DFL( x ) D4C( rs -> s_v1.x ) | 73 | #define DFL( x ) D4C( rs -> s_v1.x ) |
74 | 74 | ||
75 | #define objectid_map( s, rs ) (old_format_only (s) ? \ | 75 | #define objectid_map( s, rs ) (old_format_only (s) ? \ |
76 | (__u32 *)((struct reiserfs_super_block_v1 *)rs + 1) : \ | 76 | (__le32 *)((struct reiserfs_super_block_v1 *)rs + 1) : \ |
77 | (__u32 *)(rs + 1)) | 77 | (__le32 *)(rs + 1)) |
78 | #define MAP( i ) D4C( objectid_map( sb, rs )[ i ] ) | 78 | #define MAP( i ) D4C( objectid_map( sb, rs )[ i ] ) |
79 | 79 | ||
80 | #define DJF( x ) le32_to_cpu( rs -> x ) | 80 | #define DJF( x ) le32_to_cpu( rs -> x ) |
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index 73ec5212178b..da23ba75f3d5 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c | |||
@@ -87,22 +87,20 @@ inline void copy_item_head(struct item_head * p_v_to, | |||
87 | inline int comp_short_keys (const struct reiserfs_key * le_key, | 87 | inline int comp_short_keys (const struct reiserfs_key * le_key, |
88 | const struct cpu_key * cpu_key) | 88 | const struct cpu_key * cpu_key) |
89 | { | 89 | { |
90 | __u32 * p_s_le_u32, * p_s_cpu_u32; | 90 | __u32 n; |
91 | int n_key_length = REISERFS_SHORT_KEY_LEN; | 91 | n = le32_to_cpu(le_key->k_dir_id); |
92 | 92 | if (n < cpu_key->on_disk_key.k_dir_id) | |
93 | p_s_le_u32 = (__u32 *)le_key; | ||
94 | p_s_cpu_u32 = (__u32 *)&cpu_key->on_disk_key; | ||
95 | for( ; n_key_length--; ++p_s_le_u32, ++p_s_cpu_u32 ) { | ||
96 | if ( le32_to_cpu (*p_s_le_u32) < *p_s_cpu_u32 ) | ||
97 | return -1; | 93 | return -1; |
98 | if ( le32_to_cpu (*p_s_le_u32) > *p_s_cpu_u32 ) | 94 | if (n > cpu_key->on_disk_key.k_dir_id) |
95 | return 1; | ||
96 | n = le32_to_cpu(le_key->k_objectid); | ||
97 | if (n < cpu_key->on_disk_key.k_objectid) | ||
98 | return -1; | ||
99 | if (n > cpu_key->on_disk_key.k_objectid) | ||
99 | return 1; | 100 | return 1; |
100 | } | ||
101 | |||
102 | return 0; | 101 | return 0; |
103 | } | 102 | } |
104 | 103 | ||
105 | |||
106 | /* k1 is pointer to on-disk structure which is stored in little-endian | 104 | /* k1 is pointer to on-disk structure which is stored in little-endian |
107 | form. k2 is pointer to cpu variable. | 105 | form. k2 is pointer to cpu variable. |
108 | Compare keys using all 4 key fields. | 106 | Compare keys using all 4 key fields. |
@@ -152,18 +150,15 @@ inline int comp_short_le_keys (const struct reiserfs_key * key1, const struct re | |||
152 | 150 | ||
153 | inline void le_key2cpu_key (struct cpu_key * to, const struct reiserfs_key * from) | 151 | inline void le_key2cpu_key (struct cpu_key * to, const struct reiserfs_key * from) |
154 | { | 152 | { |
153 | int version; | ||
155 | to->on_disk_key.k_dir_id = le32_to_cpu (from->k_dir_id); | 154 | to->on_disk_key.k_dir_id = le32_to_cpu (from->k_dir_id); |
156 | to->on_disk_key.k_objectid = le32_to_cpu (from->k_objectid); | 155 | to->on_disk_key.k_objectid = le32_to_cpu (from->k_objectid); |
157 | 156 | ||
158 | // find out version of the key | 157 | // find out version of the key |
159 | to->version = le_key_version (from); | 158 | version = le_key_version (from); |
160 | if (to->version == KEY_FORMAT_3_5) { | 159 | to->version = version; |
161 | to->on_disk_key.u.k_offset_v1.k_offset = le32_to_cpu (from->u.k_offset_v1.k_offset); | 160 | to->on_disk_key.k_offset = le_key_k_offset(version, from); |
162 | to->on_disk_key.u.k_offset_v1.k_uniqueness = le32_to_cpu (from->u.k_offset_v1.k_uniqueness); | 161 | to->on_disk_key.k_type = le_key_k_type(version, from); |
163 | } else { | ||
164 | to->on_disk_key.u.k_offset_v2.k_offset = offset_v2_k_offset(&from->u.k_offset_v2); | ||
165 | to->on_disk_key.u.k_offset_v2.k_type = offset_v2_k_type(&from->u.k_offset_v2); | ||
166 | } | ||
167 | } | 162 | } |
168 | 163 | ||
169 | 164 | ||
@@ -228,8 +223,14 @@ extern struct tree_balance * cur_tb; | |||
228 | const struct reiserfs_key MIN_KEY = {0, 0, {{0, 0},}}; | 223 | const struct reiserfs_key MIN_KEY = {0, 0, {{0, 0},}}; |
229 | 224 | ||
230 | /* Maximal possible key. It is never in the tree. */ | 225 | /* Maximal possible key. It is never in the tree. */ |
231 | const struct reiserfs_key MAX_KEY = {0xffffffff, 0xffffffff, {{0xffffffff, 0xffffffff},}}; | 226 | const struct reiserfs_key MAX_KEY = { |
227 | __constant_cpu_to_le32(0xffffffff), | ||
228 | __constant_cpu_to_le32(0xffffffff), | ||
229 | {{__constant_cpu_to_le32(0xffffffff), | ||
230 | __constant_cpu_to_le32(0xffffffff)},} | ||
231 | }; | ||
232 | 232 | ||
233 | const struct in_core_key MAX_IN_CORE_KEY = {~0U, ~0U, ~0ULL>>4, 15}; | ||
233 | 234 | ||
234 | /* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom | 235 | /* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom |
235 | of the path, and going upwards. We must check the path's validity at each step. If the key is not in | 236 | of the path, and going upwards. We must check the path's validity at each step. If the key is not in |
@@ -997,7 +998,7 @@ static char prepare_for_delete_or_cut( | |||
997 | int n_unfm_number, /* Number of the item unformatted nodes. */ | 998 | int n_unfm_number, /* Number of the item unformatted nodes. */ |
998 | n_counter, | 999 | n_counter, |
999 | n_blk_size; | 1000 | n_blk_size; |
1000 | __u32 * p_n_unfm_pointer; /* Pointer to the unformatted node number. */ | 1001 | __le32 * p_n_unfm_pointer; /* Pointer to the unformatted node number. */ |
1001 | __u32 tmp; | 1002 | __u32 tmp; |
1002 | struct item_head s_ih; /* Item header. */ | 1003 | struct item_head s_ih; /* Item header. */ |
1003 | char c_mode; /* Returned mode of the balance. */ | 1004 | char c_mode; /* Returned mode of the balance. */ |
@@ -1059,7 +1060,7 @@ static char prepare_for_delete_or_cut( | |||
1059 | /* pointers to be cut */ | 1060 | /* pointers to be cut */ |
1060 | n_unfm_number -= pos_in_item (p_s_path); | 1061 | n_unfm_number -= pos_in_item (p_s_path); |
1061 | /* Set pointer to the last unformatted node pointer that is to be cut. */ | 1062 | /* Set pointer to the last unformatted node pointer that is to be cut. */ |
1062 | p_n_unfm_pointer = (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1 - *p_n_removed; | 1063 | p_n_unfm_pointer = (__le32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1 - *p_n_removed; |
1063 | 1064 | ||
1064 | 1065 | ||
1065 | /* We go through the unformatted nodes pointers of the indirect | 1066 | /* We go through the unformatted nodes pointers of the indirect |
@@ -1081,8 +1082,8 @@ static char prepare_for_delete_or_cut( | |||
1081 | need_research = 1 ; | 1082 | need_research = 1 ; |
1082 | break; | 1083 | break; |
1083 | } | 1084 | } |
1084 | RFALSE( p_n_unfm_pointer < (__u32 *)B_I_PITEM(p_s_bh, &s_ih) || | 1085 | RFALSE( p_n_unfm_pointer < (__le32 *)B_I_PITEM(p_s_bh, &s_ih) || |
1085 | p_n_unfm_pointer > (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1, | 1086 | p_n_unfm_pointer > (__le32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1, |
1086 | "vs-5265: pointer out of range"); | 1087 | "vs-5265: pointer out of range"); |
1087 | 1088 | ||
1088 | /* Hole, nothing to remove. */ | 1089 | /* Hole, nothing to remove. */ |
@@ -1431,7 +1432,7 @@ int reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode | |||
1431 | #if defined( USE_INODE_GENERATION_COUNTER ) | 1432 | #if defined( USE_INODE_GENERATION_COUNTER ) |
1432 | if( !old_format_only ( th -> t_super ) ) | 1433 | if( !old_format_only ( th -> t_super ) ) |
1433 | { | 1434 | { |
1434 | __u32 *inode_generation; | 1435 | __le32 *inode_generation; |
1435 | 1436 | ||
1436 | inode_generation = | 1437 | inode_generation = |
1437 | &REISERFS_SB(th -> t_super) -> s_rs -> s_inode_generation; | 1438 | &REISERFS_SB(th -> t_super) -> s_rs -> s_inode_generation; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index bcdf2438d152..31e75125f48b 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -110,7 +110,7 @@ static void reiserfs_unlockfs(struct super_block *s) { | |||
110 | reiserfs_allow_writes(s) ; | 110 | reiserfs_allow_writes(s) ; |
111 | } | 111 | } |
112 | 112 | ||
113 | extern const struct reiserfs_key MAX_KEY; | 113 | extern const struct in_core_key MAX_IN_CORE_KEY; |
114 | 114 | ||
115 | 115 | ||
116 | /* this is used to delete "save link" when there are no items of a | 116 | /* this is used to delete "save link" when there are no items of a |
@@ -164,7 +164,7 @@ static int finish_unfinished (struct super_block * s) | |||
164 | 164 | ||
165 | /* compose key to look for "save" links */ | 165 | /* compose key to look for "save" links */ |
166 | max_cpu_key.version = KEY_FORMAT_3_5; | 166 | max_cpu_key.version = KEY_FORMAT_3_5; |
167 | max_cpu_key.on_disk_key = MAX_KEY; | 167 | max_cpu_key.on_disk_key = MAX_IN_CORE_KEY; |
168 | max_cpu_key.key_length = 3; | 168 | max_cpu_key.key_length = 3; |
169 | 169 | ||
170 | #ifdef CONFIG_QUOTA | 170 | #ifdef CONFIG_QUOTA |
@@ -216,10 +216,10 @@ static int finish_unfinished (struct super_block * s) | |||
216 | 216 | ||
217 | /* reiserfs_iget needs k_dirid and k_objectid only */ | 217 | /* reiserfs_iget needs k_dirid and k_objectid only */ |
218 | item = B_I_PITEM (bh, ih); | 218 | item = B_I_PITEM (bh, ih); |
219 | obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__u32 *)item); | 219 | obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__le32 *)item); |
220 | obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid); | 220 | obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid); |
221 | obj_key.on_disk_key.u.k_offset_v1.k_offset = 0; | 221 | obj_key.on_disk_key.k_offset = 0; |
222 | obj_key.on_disk_key.u.k_offset_v1.k_uniqueness = 0; | 222 | obj_key.on_disk_key.k_type = 0; |
223 | 223 | ||
224 | pathrelse (&path); | 224 | pathrelse (&path); |
225 | 225 | ||
@@ -304,7 +304,7 @@ void add_save_link (struct reiserfs_transaction_handle * th, | |||
304 | int retval; | 304 | int retval; |
305 | struct cpu_key key; | 305 | struct cpu_key key; |
306 | struct item_head ih; | 306 | struct item_head ih; |
307 | __u32 link; | 307 | __le32 link; |
308 | 308 | ||
309 | BUG_ON (!th->t_trans_id); | 309 | BUG_ON (!th->t_trans_id); |
310 | 310 | ||
@@ -889,12 +889,18 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st | |||
889 | char * p; | 889 | char * p; |
890 | 890 | ||
891 | p = NULL; | 891 | p = NULL; |
892 | /* "resize=NNN" */ | 892 | /* "resize=NNN" or "resize=auto" */ |
893 | *blocks = simple_strtoul (arg, &p, 0); | 893 | |
894 | if (*p != '\0') { | 894 | if (!strcmp(arg, "auto")) { |
895 | /* NNN does not look like a number */ | 895 | /* From JFS code, to auto-get the size.*/ |
896 | reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg); | 896 | *blocks = s->s_bdev->bd_inode->i_size >> s->s_blocksize_bits; |
897 | return 0; | 897 | } else { |
898 | *blocks = simple_strtoul (arg, &p, 0); | ||
899 | if (*p != '\0') { | ||
900 | /* NNN does not look like a number */ | ||
901 | reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg); | ||
902 | return 0; | ||
903 | } | ||
898 | } | 904 | } |
899 | } | 905 | } |
900 | 906 | ||
@@ -903,7 +909,8 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st | |||
903 | unsigned long val = simple_strtoul (arg, &p, 0); | 909 | unsigned long val = simple_strtoul (arg, &p, 0); |
904 | /* commit=NNN (time in seconds) */ | 910 | /* commit=NNN (time in seconds) */ |
905 | if ( *p != '\0' || val >= (unsigned int)-1) { | 911 | if ( *p != '\0' || val >= (unsigned int)-1) { |
906 | reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg); return 0; | 912 | reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg); |
913 | return 0; | ||
907 | } | 914 | } |
908 | *commit_max_age = (unsigned int)val; | 915 | *commit_max_age = (unsigned int)val; |
909 | } | 916 | } |
@@ -1329,7 +1336,7 @@ static int read_super_block (struct super_block * s, int offset) | |||
1329 | return 1; | 1336 | return 1; |
1330 | } | 1337 | } |
1331 | 1338 | ||
1332 | if ( rs->s_v1.s_root_block == -1 ) { | 1339 | if ( rs->s_v1.s_root_block == cpu_to_le32(-1) ) { |
1333 | brelse(bh) ; | 1340 | brelse(bh) ; |
1334 | reiserfs_warning (s, "Unfinished reiserfsck --rebuild-tree run detected. Please run\n" | 1341 | reiserfs_warning (s, "Unfinished reiserfsck --rebuild-tree run detected. Please run\n" |
1335 | "reiserfsck --rebuild-tree and wait for a completion. If that fails\n" | 1342 | "reiserfsck --rebuild-tree and wait for a completion. If that fails\n" |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 650c43ba86c4..38ef913767ff 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -51,7 +51,10 @@ EXPORT_SYMBOL(seq_open); | |||
51 | 51 | ||
52 | /** | 52 | /** |
53 | * seq_read - ->read() method for sequential files. | 53 | * seq_read - ->read() method for sequential files. |
54 | * @file, @buf, @size, @ppos: see file_operations method | 54 | * @file: the file to read from |
55 | * @buf: the buffer to read to | ||
56 | * @size: the maximum number of bytes to read | ||
57 | * @ppos: the current position in the file | ||
55 | * | 58 | * |
56 | * Ready-made ->f_op->read() | 59 | * Ready-made ->f_op->read() |
57 | */ | 60 | */ |
@@ -219,7 +222,9 @@ Eoverflow: | |||
219 | 222 | ||
220 | /** | 223 | /** |
221 | * seq_lseek - ->llseek() method for sequential files. | 224 | * seq_lseek - ->llseek() method for sequential files. |
222 | * @file, @offset, @origin: see file_operations method | 225 | * @file: the file in question |
226 | * @offset: new position | ||
227 | * @origin: 0 for absolute, 1 for relative position | ||
223 | * | 228 | * |
224 | * Ready-made ->f_op->llseek() | 229 | * Ready-made ->f_op->llseek() |
225 | */ | 230 | */ |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index da25aeb0e062..364208071e17 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -96,7 +96,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer | |||
96 | /** | 96 | /** |
97 | * flush_read_buffer - push buffer to userspace. | 97 | * flush_read_buffer - push buffer to userspace. |
98 | * @buffer: data buffer for file. | 98 | * @buffer: data buffer for file. |
99 | * @userbuf: user-passed buffer. | 99 | * @buf: user-passed buffer. |
100 | * @count: number of bytes requested. | 100 | * @count: number of bytes requested. |
101 | * @ppos: file position. | 101 | * @ppos: file position. |
102 | * | 102 | * |
@@ -164,7 +164,7 @@ out: | |||
164 | /** | 164 | /** |
165 | * fill_write_buffer - copy buffer from userspace. | 165 | * fill_write_buffer - copy buffer from userspace. |
166 | * @buffer: data buffer for file. | 166 | * @buffer: data buffer for file. |
167 | * @userbuf: data from user. | 167 | * @buf: data from user. |
168 | * @count: number of bytes in @userbuf. | 168 | * @count: number of bytes in @userbuf. |
169 | * | 169 | * |
170 | * Allocate @buffer->page if it hasn't been already, then | 170 | * Allocate @buffer->page if it hasn't been already, then |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 2faa4172b9f7..bb40d63f328f 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -49,8 +49,7 @@ static int udf_adinicb_readpage(struct file *file, struct page * page) | |||
49 | struct inode *inode = page->mapping->host; | 49 | struct inode *inode = page->mapping->host; |
50 | char *kaddr; | 50 | char *kaddr; |
51 | 51 | ||
52 | if (!PageLocked(page)) | 52 | BUG_ON(!PageLocked(page)); |
53 | PAGE_BUG(page); | ||
54 | 53 | ||
55 | kaddr = kmap(page); | 54 | kaddr = kmap(page); |
56 | memset(kaddr, 0, PAGE_CACHE_SIZE); | 55 | memset(kaddr, 0, PAGE_CACHE_SIZE); |
@@ -67,8 +66,7 @@ static int udf_adinicb_writepage(struct page *page, struct writeback_control *wb | |||
67 | struct inode *inode = page->mapping->host; | 66 | struct inode *inode = page->mapping->host; |
68 | char *kaddr; | 67 | char *kaddr; |
69 | 68 | ||
70 | if (!PageLocked(page)) | 69 | BUG_ON(!PageLocked(page)); |
71 | PAGE_BUG(page); | ||
72 | 70 | ||
73 | kaddr = kmap(page); | 71 | kaddr = kmap(page); |
74 | memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), kaddr, inode->i_size); | 72 | memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), kaddr, inode->i_size); |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 0506e1173784..3d68de39fad6 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -167,8 +167,8 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) | |||
167 | } | 167 | } |
168 | 168 | ||
169 | page = grab_cache_page(inode->i_mapping, 0); | 169 | page = grab_cache_page(inode->i_mapping, 0); |
170 | if (!PageLocked(page)) | 170 | BUG_ON(!PageLocked(page)); |
171 | PAGE_BUG(page); | 171 | |
172 | if (!PageUptodate(page)) | 172 | if (!PageUptodate(page)) |
173 | { | 173 | { |
174 | kaddr = kmap(page); | 174 | kaddr = kmap(page); |
diff --git a/include/asm-alpha/bug.h b/include/asm-alpha/bug.h index ae1e0a5fa492..39a3e2a5017d 100644 --- a/include/asm-alpha/bug.h +++ b/include/asm-alpha/bug.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _ALPHA_BUG_H | 1 | #ifndef _ALPHA_BUG_H |
2 | #define _ALPHA_BUG_H | 2 | #define _ALPHA_BUG_H |
3 | 3 | ||
4 | #ifdef CONFIG_BUG | ||
4 | #include <asm/pal.h> | 5 | #include <asm/pal.h> |
5 | 6 | ||
6 | /* ??? Would be nice to use .gprel32 here, but we can't be sure that the | 7 | /* ??? Would be nice to use .gprel32 here, but we can't be sure that the |
@@ -10,6 +11,8 @@ | |||
10 | : : "i" (PAL_bugchk), "i"(__LINE__), "i"(__FILE__)) | 11 | : : "i" (PAL_bugchk), "i"(__LINE__), "i"(__FILE__)) |
11 | 12 | ||
12 | #define HAVE_ARCH_BUG | 13 | #define HAVE_ARCH_BUG |
14 | #endif | ||
15 | |||
13 | #include <asm-generic/bug.h> | 16 | #include <asm-generic/bug.h> |
14 | 17 | ||
15 | #endif | 18 | #endif |
diff --git a/include/asm-alpha/errno.h b/include/asm-alpha/errno.h index c85ab6b9d6c6..69e2655249d2 100644 --- a/include/asm-alpha/errno.h +++ b/include/asm-alpha/errno.h | |||
@@ -116,4 +116,8 @@ | |||
116 | #define EKEYREVOKED 134 /* Key has been revoked */ | 116 | #define EKEYREVOKED 134 /* Key has been revoked */ |
117 | #define EKEYREJECTED 135 /* Key was rejected by service */ | 117 | #define EKEYREJECTED 135 /* Key was rejected by service */ |
118 | 118 | ||
119 | /* for robust mutexes */ | ||
120 | #define EOWNERDEAD 136 /* Owner died */ | ||
121 | #define ENOTRECOVERABLE 137 /* State not recoverable */ | ||
122 | |||
119 | #endif | 123 | #endif |
diff --git a/include/asm-alpha/siginfo.h b/include/asm-alpha/siginfo.h index 86bcab59c52b..9822362a8424 100644 --- a/include/asm-alpha/siginfo.h +++ b/include/asm-alpha/siginfo.h | |||
@@ -4,8 +4,6 @@ | |||
4 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 4 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
5 | #define __ARCH_SI_TRAPNO | 5 | #define __ARCH_SI_TRAPNO |
6 | 6 | ||
7 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) | ||
8 | |||
9 | #include <asm-generic/siginfo.h> | 7 | #include <asm-generic/siginfo.h> |
10 | 8 | ||
11 | #endif | 9 | #endif |
diff --git a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h index 25f98bc5576f..4e0842b415aa 100644 --- a/include/asm-alpha/signal.h +++ b/include/asm-alpha/signal.h | |||
@@ -109,20 +109,6 @@ typedef unsigned long sigset_t; | |||
109 | #define MINSIGSTKSZ 4096 | 109 | #define MINSIGSTKSZ 4096 |
110 | #define SIGSTKSZ 16384 | 110 | #define SIGSTKSZ 16384 |
111 | 111 | ||
112 | |||
113 | #ifdef __KERNEL__ | ||
114 | /* | ||
115 | * These values of sa_flags are used only by the kernel as part of the | ||
116 | * irq handling routines. | ||
117 | * | ||
118 | * SA_INTERRUPT is also used by the irq handling routines. | ||
119 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
120 | */ | ||
121 | #define SA_PROBE SA_ONESHOT | ||
122 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
123 | #define SA_SHIRQ 0x40000000 | ||
124 | #endif | ||
125 | |||
126 | #define SIG_BLOCK 1 /* for blocking signals */ | 112 | #define SIG_BLOCK 1 /* for blocking signals */ |
127 | #define SIG_UNBLOCK 2 /* for unblocking signals */ | 113 | #define SIG_UNBLOCK 2 /* for unblocking signals */ |
128 | #define SIG_SETMASK 3 /* for setting the signal mask */ | 114 | #define SIG_SETMASK 3 /* for setting the signal mask */ |
diff --git a/include/asm-arm/arch-cl7500/vmalloc.h b/include/asm-arm/arch-cl7500/vmalloc.h index 91883def4889..ba8d7a84456a 100644 --- a/include/asm-arm/arch-cl7500/vmalloc.h +++ b/include/asm-arm/arch-cl7500/vmalloc.h | |||
@@ -1,15 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/include/asm-arm/arch-cl7500/vmalloc.h | 2 | * linux/include/asm-arm/arch-cl7500/vmalloc.h |
3 | */ | 3 | */ |
4 | |||
5 | /* | ||
6 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
7 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
8 | * physical memory until the kernel virtual memory starts. That means that | ||
9 | * any out-of-bounds memory accesses will hopefully be caught. | ||
10 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
11 | * area for the same reason. ;) | ||
12 | */ | ||
13 | #define VMALLOC_OFFSET (8*1024*1024) | ||
14 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
15 | #define VMALLOC_END (PAGE_OFFSET + 0x1c000000) | 4 | #define VMALLOC_END (PAGE_OFFSET + 0x1c000000) |
diff --git a/include/asm-arm/arch-clps711x/vmalloc.h b/include/asm-arm/arch-clps711x/vmalloc.h index 42571ed5e493..a5dfe96abc96 100644 --- a/include/asm-arm/arch-clps711x/vmalloc.h +++ b/include/asm-arm/arch-clps711x/vmalloc.h | |||
@@ -17,15 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | |||
21 | /* | ||
22 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
23 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
24 | * physical memory until the kernel virtual memory starts. That means that | ||
25 | * any out-of-bounds memory accesses will hopefully be caught. | ||
26 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
27 | * area for the same reason. ;) | ||
28 | */ | ||
29 | #define VMALLOC_OFFSET (8*1024*1024) | ||
30 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
31 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 20 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
diff --git a/include/asm-arm/arch-ebsa110/vmalloc.h b/include/asm-arm/arch-ebsa110/vmalloc.h index 759659be109f..26674ba4683c 100644 --- a/include/asm-arm/arch-ebsa110/vmalloc.h +++ b/include/asm-arm/arch-ebsa110/vmalloc.h | |||
@@ -7,15 +7,4 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | |||
11 | /* | ||
12 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
13 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
14 | * physical memory until the kernel virtual memory starts. That means that | ||
15 | * any out-of-bounds memory accesses will hopefully be caught. | ||
16 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
17 | * area for the same reason. ;) | ||
18 | */ | ||
19 | #define VMALLOC_OFFSET (8*1024*1024) | ||
20 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
21 | #define VMALLOC_END (PAGE_OFFSET + 0x1f000000) | 10 | #define VMALLOC_END (PAGE_OFFSET + 0x1f000000) |
diff --git a/include/asm-arm/arch-ebsa285/vmalloc.h b/include/asm-arm/arch-ebsa285/vmalloc.h index def705a3c209..d1ca955ce434 100644 --- a/include/asm-arm/arch-ebsa285/vmalloc.h +++ b/include/asm-arm/arch-ebsa285/vmalloc.h | |||
@@ -8,17 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/config.h> | 9 | #include <linux/config.h> |
10 | 10 | ||
11 | /* | ||
12 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
13 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
14 | * physical memory until the kernel virtual memory starts. That means that | ||
15 | * any out-of-bounds memory accesses will hopefully be caught. | ||
16 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
17 | * area for the same reason. ;) | ||
18 | */ | ||
19 | #define VMALLOC_OFFSET (8*1024*1024) | ||
20 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
21 | |||
22 | #ifdef CONFIG_ARCH_FOOTBRIDGE | 11 | #ifdef CONFIG_ARCH_FOOTBRIDGE |
23 | #define VMALLOC_END (PAGE_OFFSET + 0x30000000) | 12 | #define VMALLOC_END (PAGE_OFFSET + 0x30000000) |
24 | #else | 13 | #else |
diff --git a/include/asm-arm/arch-epxa10db/vmalloc.h b/include/asm-arm/arch-epxa10db/vmalloc.h index d31ef8584760..546fb7d2b6ad 100644 --- a/include/asm-arm/arch-epxa10db/vmalloc.h +++ b/include/asm-arm/arch-epxa10db/vmalloc.h | |||
@@ -17,15 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | |||
21 | /* | ||
22 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
23 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
24 | * physical memory until the kernel virtual memory starts. That means that | ||
25 | * any out-of-bounds memory accesses will hopefully be caught. | ||
26 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
27 | * area for the same reason. ;) | ||
28 | */ | ||
29 | #define VMALLOC_OFFSET (8*1024*1024) | ||
30 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
31 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 20 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
diff --git a/include/asm-arm/arch-h720x/vmalloc.h b/include/asm-arm/arch-h720x/vmalloc.h index 4af523a5e189..b4693cb821ef 100644 --- a/include/asm-arm/arch-h720x/vmalloc.h +++ b/include/asm-arm/arch-h720x/vmalloc.h | |||
@@ -5,17 +5,6 @@ | |||
5 | #ifndef __ARCH_ARM_VMALLOC_H | 5 | #ifndef __ARCH_ARM_VMALLOC_H |
6 | #define __ARCH_ARM_VMALLOC_H | 6 | #define __ARCH_ARM_VMALLOC_H |
7 | 7 | ||
8 | /* | ||
9 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
10 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
11 | * physical memory until the kernel virtual memory starts. That means that | ||
12 | * any out-of-bounds memory accesses will hopefully be caught. | ||
13 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
14 | * area for the same reason. ;) | ||
15 | */ | ||
16 | #define VMALLOC_OFFSET (8*1024*1024) | ||
17 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
18 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
19 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 8 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
20 | 9 | ||
21 | #endif | 10 | #endif |
diff --git a/include/asm-arm/arch-imx/vmalloc.h b/include/asm-arm/arch-imx/vmalloc.h index 252038f48163..cb6169127068 100644 --- a/include/asm-arm/arch-imx/vmalloc.h +++ b/include/asm-arm/arch-imx/vmalloc.h | |||
@@ -17,16 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | |||
21 | /* | ||
22 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
23 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
24 | * physical memory until the kernel virtual memory starts. That means that | ||
25 | * any out-of-bounds memory accesses will hopefully be caught. | ||
26 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
27 | * area for the same reason. ;) | ||
28 | */ | ||
29 | #define VMALLOC_OFFSET (8*1024*1024) | ||
30 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
31 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
32 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 20 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
diff --git a/include/asm-arm/arch-integrator/cm.h b/include/asm-arm/arch-integrator/cm.h index d31c1a71f781..1ab353e23595 100644 --- a/include/asm-arm/arch-integrator/cm.h +++ b/include/asm-arm/arch-integrator/cm.h | |||
@@ -24,9 +24,9 @@ void cm_control(u32, u32); | |||
24 | #define CM_CTRL_LCDBIASDN (1 << 10) | 24 | #define CM_CTRL_LCDBIASDN (1 << 10) |
25 | #define CM_CTRL_LCDMUXSEL_MASK (7 << 11) | 25 | #define CM_CTRL_LCDMUXSEL_MASK (7 << 11) |
26 | #define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11) | 26 | #define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11) |
27 | #define CM_CTRL_LCDMUXSEL_SHARPLCD1 (3 << 11) | 27 | #define CM_CTRL_LCDMUXSEL_VGA_16BPP (2 << 11) |
28 | #define CM_CTRL_LCDMUXSEL_SHARPLCD2 (4 << 11) | 28 | #define CM_CTRL_LCDMUXSEL_SHARPLCD (3 << 11) |
29 | #define CM_CTRL_LCDMUXSEL_VGA (7 << 11) | 29 | #define CM_CTRL_LCDMUXSEL_VGA_8421BPP (4 << 11) |
30 | #define CM_CTRL_LCDEN0 (1 << 14) | 30 | #define CM_CTRL_LCDEN0 (1 << 14) |
31 | #define CM_CTRL_LCDEN1 (1 << 15) | 31 | #define CM_CTRL_LCDEN1 (1 << 15) |
32 | #define CM_CTRL_STATIC1 (1 << 16) | 32 | #define CM_CTRL_STATIC1 (1 << 16) |
diff --git a/include/asm-arm/arch-integrator/platform.h b/include/asm-arm/arch-integrator/platform.h index 6b67e41669f4..bd364f5a99bc 100644 --- a/include/asm-arm/arch-integrator/platform.h +++ b/include/asm-arm/arch-integrator/platform.h | |||
@@ -20,14 +20,14 @@ | |||
20 | * * Copyright © ARM Limited 1998. All rights reserved. | 20 | * * Copyright © ARM Limited 1998. All rights reserved. |
21 | * ***********************************************************************/ | 21 | * ***********************************************************************/ |
22 | /* ************************************************************************ | 22 | /* ************************************************************************ |
23 | * | 23 | * |
24 | * Integrator address map | 24 | * Integrator address map |
25 | * | 25 | * |
26 | * NOTE: This is a multi-hosted header file for use with uHAL and | 26 | * NOTE: This is a multi-hosted header file for use with uHAL and |
27 | * supported debuggers. | 27 | * supported debuggers. |
28 | * | 28 | * |
29 | * $Id: platform.s,v 1.32 2000/02/18 10:51:39 asims Exp $ | 29 | * $Id: platform.s,v 1.32 2000/02/18 10:51:39 asims Exp $ |
30 | * | 30 | * |
31 | * ***********************************************************************/ | 31 | * ***********************************************************************/ |
32 | 32 | ||
33 | #ifndef __address_h | 33 | #ifndef __address_h |
@@ -40,22 +40,22 @@ | |||
40 | * Memory definitions | 40 | * Memory definitions |
41 | * ------------------------------------------------------------------------ | 41 | * ------------------------------------------------------------------------ |
42 | * Integrator memory map | 42 | * Integrator memory map |
43 | * | 43 | * |
44 | */ | 44 | */ |
45 | #define INTEGRATOR_BOOT_ROM_LO 0x00000000 | 45 | #define INTEGRATOR_BOOT_ROM_LO 0x00000000 |
46 | #define INTEGRATOR_BOOT_ROM_HI 0x20000000 | 46 | #define INTEGRATOR_BOOT_ROM_HI 0x20000000 |
47 | #define INTEGRATOR_BOOT_ROM_BASE INTEGRATOR_BOOT_ROM_HI /* Normal position */ | 47 | #define INTEGRATOR_BOOT_ROM_BASE INTEGRATOR_BOOT_ROM_HI /* Normal position */ |
48 | #define INTEGRATOR_BOOT_ROM_SIZE SZ_512K | 48 | #define INTEGRATOR_BOOT_ROM_SIZE SZ_512K |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * New Core Modules have different amounts of SSRAM, the amount of SSRAM | 51 | * New Core Modules have different amounts of SSRAM, the amount of SSRAM |
52 | * fitted can be found in HDR_STAT. | 52 | * fitted can be found in HDR_STAT. |
53 | * | 53 | * |
54 | * The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to | 54 | * The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to |
55 | * the minimum amount of SSRAM fitted on any core module. | 55 | * the minimum amount of SSRAM fitted on any core module. |
56 | * | 56 | * |
57 | * New Core Modules also alias the SSRAM. | 57 | * New Core Modules also alias the SSRAM. |
58 | * | 58 | * |
59 | */ | 59 | */ |
60 | #define INTEGRATOR_SSRAM_BASE 0x00000000 | 60 | #define INTEGRATOR_SSRAM_BASE 0x00000000 |
61 | #define INTEGRATOR_SSRAM_ALIAS_BASE 0x10800000 | 61 | #define INTEGRATOR_SSRAM_ALIAS_BASE 0x10800000 |
@@ -67,9 +67,9 @@ | |||
67 | #define INTEGRATOR_MBRD_SSRAM_BASE 0x28000000 | 67 | #define INTEGRATOR_MBRD_SSRAM_BASE 0x28000000 |
68 | #define INTEGRATOR_MBRD_SSRAM_SIZE SZ_512K | 68 | #define INTEGRATOR_MBRD_SSRAM_SIZE SZ_512K |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * SDRAM is a SIMM therefore the size is not known. | 71 | * SDRAM is a SIMM therefore the size is not known. |
72 | * | 72 | * |
73 | */ | 73 | */ |
74 | #define INTEGRATOR_SDRAM_BASE 0x00040000 | 74 | #define INTEGRATOR_SDRAM_BASE 0x00040000 |
75 | 75 | ||
@@ -79,9 +79,9 @@ | |||
79 | #define INTEGRATOR_HDR2_SDRAM_BASE 0xA0000000 | 79 | #define INTEGRATOR_HDR2_SDRAM_BASE 0xA0000000 |
80 | #define INTEGRATOR_HDR3_SDRAM_BASE 0xB0000000 | 80 | #define INTEGRATOR_HDR3_SDRAM_BASE 0xB0000000 |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * Logic expansion modules | 83 | * Logic expansion modules |
84 | * | 84 | * |
85 | */ | 85 | */ |
86 | #define INTEGRATOR_LOGIC_MODULES_BASE 0xC0000000 | 86 | #define INTEGRATOR_LOGIC_MODULES_BASE 0xC0000000 |
87 | #define INTEGRATOR_LOGIC_MODULE0_BASE 0xC0000000 | 87 | #define INTEGRATOR_LOGIC_MODULE0_BASE 0xC0000000 |
@@ -92,7 +92,7 @@ | |||
92 | /* ------------------------------------------------------------------------ | 92 | /* ------------------------------------------------------------------------ |
93 | * Integrator header card registers | 93 | * Integrator header card registers |
94 | * ------------------------------------------------------------------------ | 94 | * ------------------------------------------------------------------------ |
95 | * | 95 | * |
96 | */ | 96 | */ |
97 | #define INTEGRATOR_HDR_ID_OFFSET 0x00 | 97 | #define INTEGRATOR_HDR_ID_OFFSET 0x00 |
98 | #define INTEGRATOR_HDR_PROC_OFFSET 0x04 | 98 | #define INTEGRATOR_HDR_PROC_OFFSET 0x04 |
@@ -185,12 +185,12 @@ | |||
185 | /* ------------------------------------------------------------------------ | 185 | /* ------------------------------------------------------------------------ |
186 | * Integrator system registers | 186 | * Integrator system registers |
187 | * ------------------------------------------------------------------------ | 187 | * ------------------------------------------------------------------------ |
188 | * | 188 | * |
189 | */ | 189 | */ |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * System Controller | 192 | * System Controller |
193 | * | 193 | * |
194 | */ | 194 | */ |
195 | #define INTEGRATOR_SC_ID_OFFSET 0x00 | 195 | #define INTEGRATOR_SC_ID_OFFSET 0x00 |
196 | #define INTEGRATOR_SC_OSC_OFFSET 0x04 | 196 | #define INTEGRATOR_SC_OSC_OFFSET 0x04 |
@@ -230,11 +230,11 @@ | |||
230 | #define INTEGRATOR_SC_CTRL_URTS1 (1 << 6) | 230 | #define INTEGRATOR_SC_CTRL_URTS1 (1 << 6) |
231 | #define INTEGRATOR_SC_CTRL_UDTR1 (1 << 7) | 231 | #define INTEGRATOR_SC_CTRL_UDTR1 (1 << 7) |
232 | 232 | ||
233 | /* | 233 | /* |
234 | * External Bus Interface | 234 | * External Bus Interface |
235 | * | 235 | * |
236 | */ | 236 | */ |
237 | #define INTEGRATOR_EBI_BASE 0x12000000 | 237 | #define INTEGRATOR_EBI_BASE 0x12000000 |
238 | 238 | ||
239 | #define INTEGRATOR_EBI_CSR0_OFFSET 0x00 | 239 | #define INTEGRATOR_EBI_CSR0_OFFSET 0x00 |
240 | #define INTEGRATOR_EBI_CSR1_OFFSET 0x04 | 240 | #define INTEGRATOR_EBI_CSR1_OFFSET 0x04 |
@@ -279,9 +279,9 @@ | |||
279 | #define INTEGRATOR_KBD_BASE 0x18000000 /* Keyboard */ | 279 | #define INTEGRATOR_KBD_BASE 0x18000000 /* Keyboard */ |
280 | #define INTEGRATOR_MOUSE_BASE 0x19000000 /* Mouse */ | 280 | #define INTEGRATOR_MOUSE_BASE 0x19000000 /* Mouse */ |
281 | 281 | ||
282 | /* | 282 | /* |
283 | * LED's & Switches | 283 | * LED's & Switches |
284 | * | 284 | * |
285 | */ | 285 | */ |
286 | #define INTEGRATOR_DBG_ALPHA_OFFSET 0x00 | 286 | #define INTEGRATOR_DBG_ALPHA_OFFSET 0x00 |
287 | #define INTEGRATOR_DBG_LEDS_OFFSET 0x04 | 287 | #define INTEGRATOR_DBG_LEDS_OFFSET 0x04 |
@@ -300,7 +300,7 @@ | |||
300 | * ------------------------------------------------------------------------ | 300 | * ------------------------------------------------------------------------ |
301 | */ | 301 | */ |
302 | /* PS2 Keyboard interface */ | 302 | /* PS2 Keyboard interface */ |
303 | #define KMI0_BASE INTEGRATOR_KBD_BASE | 303 | #define KMI0_BASE INTEGRATOR_KBD_BASE |
304 | 304 | ||
305 | /* PS2 Mouse interface */ | 305 | /* PS2 Mouse interface */ |
306 | #define KMI1_BASE INTEGRATOR_MOUSE_BASE | 306 | #define KMI1_BASE INTEGRATOR_MOUSE_BASE |
@@ -313,7 +313,7 @@ | |||
313 | * This represents a fairly liberal usage of address space. Even though | 313 | * This represents a fairly liberal usage of address space. Even though |
314 | * the V3 only has two windows (therefore we need to map stuff on the fly), | 314 | * the V3 only has two windows (therefore we need to map stuff on the fly), |
315 | * we maintain the same addresses, even if they're not mapped. | 315 | * we maintain the same addresses, even if they're not mapped. |
316 | * | 316 | * |
317 | */ | 317 | */ |
318 | #define PHYS_PCI_MEM_BASE 0x40000000 /* 512M to xxx */ | 318 | #define PHYS_PCI_MEM_BASE 0x40000000 /* 512M to xxx */ |
319 | /* unused 256M from A0000000-AFFFFFFF might be used for I2O ??? | 319 | /* unused 256M from A0000000-AFFFFFFF might be used for I2O ??? |
@@ -326,7 +326,7 @@ | |||
326 | */ | 326 | */ |
327 | #define PHYS_PCI_V3_BASE 0x62000000 | 327 | #define PHYS_PCI_V3_BASE 0x62000000 |
328 | 328 | ||
329 | #define PCI_DRAMSIZE INTEGRATOR_SSRAM_SIZE | 329 | #define PCI_DRAMSIZE INTEGRATOR_SSRAM_SIZE |
330 | 330 | ||
331 | /* 'export' these to UHAL */ | 331 | /* 'export' these to UHAL */ |
332 | #define UHAL_PCI_IO PCI_IO_BASE | 332 | #define UHAL_PCI_IO PCI_IO_BASE |
@@ -334,7 +334,7 @@ | |||
334 | #define UHAL_PCI_ALLOC_IO_BASE 0x00004000 | 334 | #define UHAL_PCI_ALLOC_IO_BASE 0x00004000 |
335 | #define UHAL_PCI_ALLOC_MEM_BASE PCI_MEM_BASE | 335 | #define UHAL_PCI_ALLOC_MEM_BASE PCI_MEM_BASE |
336 | #define UHAL_PCI_MAX_SLOT 20 | 336 | #define UHAL_PCI_MAX_SLOT 20 |
337 | 337 | ||
338 | /* ======================================================================== | 338 | /* ======================================================================== |
339 | * Start of uHAL definitions | 339 | * Start of uHAL definitions |
340 | * ======================================================================== | 340 | * ======================================================================== |
@@ -343,17 +343,17 @@ | |||
343 | /* ------------------------------------------------------------------------ | 343 | /* ------------------------------------------------------------------------ |
344 | * Integrator Interrupt Controllers | 344 | * Integrator Interrupt Controllers |
345 | * ------------------------------------------------------------------------ | 345 | * ------------------------------------------------------------------------ |
346 | * | 346 | * |
347 | * Offsets from interrupt controller base | 347 | * Offsets from interrupt controller base |
348 | * | 348 | * |
349 | * System Controller interrupt controller base is | 349 | * System Controller interrupt controller base is |
350 | * | 350 | * |
351 | * INTEGRATOR_IC_BASE + (header_number << 6) | 351 | * INTEGRATOR_IC_BASE + (header_number << 6) |
352 | * | 352 | * |
353 | * Core Module interrupt controller base is | 353 | * Core Module interrupt controller base is |
354 | * | 354 | * |
355 | * INTEGRATOR_HDR_IC | 355 | * INTEGRATOR_HDR_IC |
356 | * | 356 | * |
357 | */ | 357 | */ |
358 | #define IRQ_STATUS 0 | 358 | #define IRQ_STATUS 0 |
359 | #define IRQ_RAW_STATUS 0x04 | 359 | #define IRQ_RAW_STATUS 0x04 |
@@ -374,22 +374,22 @@ | |||
374 | /* ------------------------------------------------------------------------ | 374 | /* ------------------------------------------------------------------------ |
375 | * Interrupts | 375 | * Interrupts |
376 | * ------------------------------------------------------------------------ | 376 | * ------------------------------------------------------------------------ |
377 | * | 377 | * |
378 | * | 378 | * |
379 | * Each Core Module has two interrupts controllers, one on the core module | 379 | * Each Core Module has two interrupts controllers, one on the core module |
380 | * itself and one in the system controller on the motherboard. The | 380 | * itself and one in the system controller on the motherboard. The |
381 | * READ_INT macro in target.s reads both interrupt controllers and returns | 381 | * READ_INT macro in target.s reads both interrupt controllers and returns |
382 | * a 32 bit bitmask, bits 0 to 23 are interrupts from the system controller | 382 | * a 32 bit bitmask, bits 0 to 23 are interrupts from the system controller |
383 | * and bits 24 to 31 are from the core module. | 383 | * and bits 24 to 31 are from the core module. |
384 | * | 384 | * |
385 | * The following definitions relate to the bitmask returned by READ_INT. | 385 | * The following definitions relate to the bitmask returned by READ_INT. |
386 | * | 386 | * |
387 | */ | 387 | */ |
388 | 388 | ||
389 | /* ------------------------------------------------------------------------ | 389 | /* ------------------------------------------------------------------------ |
390 | * LED's - The header LED is not accessible via the uHAL API | 390 | * LED's - The header LED is not accessible via the uHAL API |
391 | * ------------------------------------------------------------------------ | 391 | * ------------------------------------------------------------------------ |
392 | * | 392 | * |
393 | */ | 393 | */ |
394 | #define GREEN_LED 0x01 | 394 | #define GREEN_LED 0x01 |
395 | #define YELLOW_LED 0x02 | 395 | #define YELLOW_LED 0x02 |
@@ -399,44 +399,44 @@ | |||
399 | 399 | ||
400 | #define LED_BANK INTEGRATOR_DBG_LEDS | 400 | #define LED_BANK INTEGRATOR_DBG_LEDS |
401 | 401 | ||
402 | /* | 402 | /* |
403 | * Memory definitions - run uHAL out of SSRAM. | 403 | * Memory definitions - run uHAL out of SSRAM. |
404 | * | 404 | * |
405 | */ | 405 | */ |
406 | #define uHAL_MEMORY_SIZE INTEGRATOR_SSRAM_SIZE | 406 | #define uHAL_MEMORY_SIZE INTEGRATOR_SSRAM_SIZE |
407 | 407 | ||
408 | /* | 408 | /* |
409 | * Application Flash | 409 | * Application Flash |
410 | * | 410 | * |
411 | */ | 411 | */ |
412 | #define FLASH_BASE INTEGRATOR_FLASH_BASE | 412 | #define FLASH_BASE INTEGRATOR_FLASH_BASE |
413 | #define FLASH_SIZE INTEGRATOR_FLASH_SIZE | 413 | #define FLASH_SIZE INTEGRATOR_FLASH_SIZE |
414 | #define FLASH_END (FLASH_BASE + FLASH_SIZE - 1) | 414 | #define FLASH_END (FLASH_BASE + FLASH_SIZE - 1) |
415 | #define FLASH_BLOCK_SIZE SZ_128K | 415 | #define FLASH_BLOCK_SIZE SZ_128K |
416 | 416 | ||
417 | /* | 417 | /* |
418 | * Boot Flash | 418 | * Boot Flash |
419 | * | 419 | * |
420 | */ | 420 | */ |
421 | #define EPROM_BASE INTEGRATOR_BOOT_ROM_HI | 421 | #define EPROM_BASE INTEGRATOR_BOOT_ROM_HI |
422 | #define EPROM_SIZE INTEGRATOR_BOOT_ROM_SIZE | 422 | #define EPROM_SIZE INTEGRATOR_BOOT_ROM_SIZE |
423 | #define EPROM_END (EPROM_BASE + EPROM_SIZE - 1) | 423 | #define EPROM_END (EPROM_BASE + EPROM_SIZE - 1) |
424 | 424 | ||
425 | /* | 425 | /* |
426 | * Clean base - dummy | 426 | * Clean base - dummy |
427 | * | 427 | * |
428 | */ | 428 | */ |
429 | #define CLEAN_BASE EPROM_BASE | 429 | #define CLEAN_BASE EPROM_BASE |
430 | 430 | ||
431 | /* | 431 | /* |
432 | * Timer definitions | 432 | * Timer definitions |
433 | * | 433 | * |
434 | * Only use timer 1 & 2 | 434 | * Only use timer 1 & 2 |
435 | * (both run at 24MHz and will need the clock divider set to 16). | 435 | * (both run at 24MHz and will need the clock divider set to 16). |
436 | * | 436 | * |
437 | * Timer 0 runs at bus frequency and therefore could vary and currently | 437 | * Timer 0 runs at bus frequency and therefore could vary and currently |
438 | * uHAL can't handle that. | 438 | * uHAL can't handle that. |
439 | * | 439 | * |
440 | */ | 440 | */ |
441 | 441 | ||
442 | #define INTEGRATOR_TIMER0_BASE INTEGRATOR_CT_BASE | 442 | #define INTEGRATOR_TIMER0_BASE INTEGRATOR_CT_BASE |
@@ -447,9 +447,9 @@ | |||
447 | #define MAX_PERIOD 699050 | 447 | #define MAX_PERIOD 699050 |
448 | #define TICKS_PER_uSEC 24 | 448 | #define TICKS_PER_uSEC 24 |
449 | 449 | ||
450 | /* | 450 | /* |
451 | * These are useconds NOT ticks. | 451 | * These are useconds NOT ticks. |
452 | * | 452 | * |
453 | */ | 453 | */ |
454 | #define mSEC_1 1000 | 454 | #define mSEC_1 1000 |
455 | #define mSEC_5 (mSEC_1 * 5) | 455 | #define mSEC_5 (mSEC_1 * 5) |
diff --git a/include/asm-arm/arch-integrator/vmalloc.h b/include/asm-arm/arch-integrator/vmalloc.h index 50e9aee79486..170cccece523 100644 --- a/include/asm-arm/arch-integrator/vmalloc.h +++ b/include/asm-arm/arch-integrator/vmalloc.h | |||
@@ -17,15 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | |||
21 | /* | ||
22 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
23 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
24 | * physical memory until the kernel virtual memory starts. That means that | ||
25 | * any out-of-bounds memory accesses will hopefully be caught. | ||
26 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
27 | * area for the same reason. ;) | ||
28 | */ | ||
29 | #define VMALLOC_OFFSET (8*1024*1024) | ||
30 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
31 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 20 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
diff --git a/include/asm-arm/arch-iop3xx/vmalloc.h b/include/asm-arm/arch-iop3xx/vmalloc.h index dc1d2a957164..0f2f6847f93c 100644 --- a/include/asm-arm/arch-iop3xx/vmalloc.h +++ b/include/asm-arm/arch-iop3xx/vmalloc.h | |||
@@ -10,9 +10,6 @@ | |||
10 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | 10 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced |
11 | * area for the same reason. ;) | 11 | * area for the same reason. ;) |
12 | */ | 12 | */ |
13 | #define VMALLOC_OFFSET (8*1024*1024) | ||
14 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
15 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
16 | //#define VMALLOC_END (0xe8000000) | 13 | //#define VMALLOC_END (0xe8000000) |
17 | /* increase usable physical RAM to ~992M per RMK */ | 14 | /* increase usable physical RAM to ~992M per RMK */ |
18 | #define VMALLOC_END (0xfe000000) | 15 | #define VMALLOC_END (0xfe000000) |
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h index 509e44d528d8..901bba6d02b4 100644 --- a/include/asm-arm/arch-ixp2000/platform.h +++ b/include/asm-arm/arch-ixp2000/platform.h | |||
@@ -121,6 +121,7 @@ unsigned long ixp2000_gettimeoffset(void); | |||
121 | 121 | ||
122 | struct pci_sys_data; | 122 | struct pci_sys_data; |
123 | 123 | ||
124 | u32 *ixp2000_pci_config_addr(unsigned int bus, unsigned int devfn, int where); | ||
124 | void ixp2000_pci_preinit(void); | 125 | void ixp2000_pci_preinit(void); |
125 | int ixp2000_pci_setup(int, struct pci_sys_data*); | 126 | int ixp2000_pci_setup(int, struct pci_sys_data*); |
126 | struct pci_bus* ixp2000_pci_scan_bus(int, struct pci_sys_data*); | 127 | struct pci_bus* ixp2000_pci_scan_bus(int, struct pci_sys_data*); |
diff --git a/include/asm-arm/arch-ixp2000/vmalloc.h b/include/asm-arm/arch-ixp2000/vmalloc.h index 2e4bcbcf31f0..473dff4ec561 100644 --- a/include/asm-arm/arch-ixp2000/vmalloc.h +++ b/include/asm-arm/arch-ixp2000/vmalloc.h | |||
@@ -17,7 +17,4 @@ | |||
17 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | 17 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced |
18 | * area for the same reason. ;) | 18 | * area for the same reason. ;) |
19 | */ | 19 | */ |
20 | #define VMALLOC_OFFSET (8*1024*1024) | ||
21 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
22 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
23 | #define VMALLOC_END 0xfaffefff | 20 | #define VMALLOC_END 0xfaffefff |
diff --git a/include/asm-arm/arch-ixp4xx/vmalloc.h b/include/asm-arm/arch-ixp4xx/vmalloc.h index da46e560ad6f..050d46e6b126 100644 --- a/include/asm-arm/arch-ixp4xx/vmalloc.h +++ b/include/asm-arm/arch-ixp4xx/vmalloc.h | |||
@@ -1,17 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/include/asm-arm/arch-ixp4xx/vmalloc.h | 2 | * linux/include/asm-arm/arch-ixp4xx/vmalloc.h |
3 | */ | 3 | */ |
4 | |||
5 | /* | ||
6 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
7 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
8 | * physical memory until the kernel virtual memory starts. That means that | ||
9 | * any out-of-bounds memory accesses will hopefully be caught. | ||
10 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
11 | * area for the same reason. ;) | ||
12 | */ | ||
13 | #define VMALLOC_OFFSET (8*1024*1024) | ||
14 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
15 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
16 | #define VMALLOC_END (0xFF000000) | 4 | #define VMALLOC_END (0xFF000000) |
17 | 5 | ||
diff --git a/include/asm-arm/arch-l7200/vmalloc.h b/include/asm-arm/arch-l7200/vmalloc.h index edeaebe1f14a..816231eedaac 100644 --- a/include/asm-arm/arch-l7200/vmalloc.h +++ b/include/asm-arm/arch-l7200/vmalloc.h | |||
@@ -1,15 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/include/asm-arm/arch-l7200/vmalloc.h | 2 | * linux/include/asm-arm/arch-l7200/vmalloc.h |
3 | */ | 3 | */ |
4 | |||
5 | /* | ||
6 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
7 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
8 | * physical memory until the kernel virtual memory starts. That means that | ||
9 | * any out-of-bounds memory accesses will hopefully be caught. | ||
10 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
11 | * area for the same reason. ;) | ||
12 | */ | ||
13 | #define VMALLOC_OFFSET (8*1024*1024) | ||
14 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
15 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 4 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
diff --git a/include/asm-arm/arch-lh7a40x/vmalloc.h b/include/asm-arm/arch-lh7a40x/vmalloc.h index 5ac607925bea..8163e45109b9 100644 --- a/include/asm-arm/arch-lh7a40x/vmalloc.h +++ b/include/asm-arm/arch-lh7a40x/vmalloc.h | |||
@@ -7,15 +7,4 @@ | |||
7 | * version 2 as published by the Free Software Foundation. | 7 | * version 2 as published by the Free Software Foundation. |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | |||
11 | /* | ||
12 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
13 | * current 8MB value just means that there will be a 8MB "hole" after | ||
14 | * the physical memory until the kernel virtual memory starts. That | ||
15 | * means that any out-of-bounds memory accesses will hopefully be | ||
16 | * caught. The vmalloc() routines leaves a hole of 4kB (one page) | ||
17 | * between each vmalloced area for the same reason. ;) | ||
18 | */ | ||
19 | #define VMALLOC_OFFSET (8*1024*1024) | ||
20 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
21 | #define VMALLOC_END (0xe8000000) | 10 | #define VMALLOC_END (0xe8000000) |
diff --git a/include/asm-arm/arch-omap/vmalloc.h b/include/asm-arm/arch-omap/vmalloc.h index c6a83581a2fc..5b8bd8dae8be 100644 --- a/include/asm-arm/arch-omap/vmalloc.h +++ b/include/asm-arm/arch-omap/vmalloc.h | |||
@@ -17,17 +17,5 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | |||
21 | /* | ||
22 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
23 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
24 | * physical memory until the kernel virtual memory starts. That means that | ||
25 | * any out-of-bounds memory accesses will hopefully be caught. | ||
26 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
27 | * area for the same reason. ;) | ||
28 | */ | ||
29 | #define VMALLOC_OFFSET (8*1024*1024) | ||
30 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
31 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
32 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 20 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
33 | 21 | ||
diff --git a/include/asm-arm/arch-pxa/vmalloc.h b/include/asm-arm/arch-pxa/vmalloc.h index 3381af6ddb0d..5bb450c7aa2c 100644 --- a/include/asm-arm/arch-pxa/vmalloc.h +++ b/include/asm-arm/arch-pxa/vmalloc.h | |||
@@ -8,15 +8,4 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | |||
12 | /* | ||
13 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
14 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
15 | * physical memory until the kernel virtual memory starts. That means that | ||
16 | * any out-of-bounds memory accesses will hopefully be caught. | ||
17 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
18 | * area for the same reason. ;) | ||
19 | */ | ||
20 | #define VMALLOC_OFFSET (8*1024*1024) | ||
21 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
22 | #define VMALLOC_END (0xe8000000) | 11 | #define VMALLOC_END (0xe8000000) |
diff --git a/include/asm-arm/arch-rpc/vmalloc.h b/include/asm-arm/arch-rpc/vmalloc.h index a13c27f37d71..077046bb2f36 100644 --- a/include/asm-arm/arch-rpc/vmalloc.h +++ b/include/asm-arm/arch-rpc/vmalloc.h | |||
@@ -7,15 +7,4 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | |||
11 | /* | ||
12 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
13 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
14 | * physical memory until the kernel virtual memory starts. That means that | ||
15 | * any out-of-bounds memory accesses will hopefully be caught. | ||
16 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
17 | * area for the same reason. ;) | ||
18 | */ | ||
19 | #define VMALLOC_OFFSET (8*1024*1024) | ||
20 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
21 | #define VMALLOC_END (PAGE_OFFSET + 0x1c000000) | 10 | #define VMALLOC_END (PAGE_OFFSET + 0x1c000000) |
diff --git a/include/asm-arm/arch-s3c2410/vmalloc.h b/include/asm-arm/arch-s3c2410/vmalloc.h index 5fe72ad70904..33963cd5461b 100644 --- a/include/asm-arm/arch-s3c2410/vmalloc.h +++ b/include/asm-arm/arch-s3c2410/vmalloc.h | |||
@@ -19,18 +19,6 @@ | |||
19 | #ifndef __ASM_ARCH_VMALLOC_H | 19 | #ifndef __ASM_ARCH_VMALLOC_H |
20 | #define __ASM_ARCH_VMALLOC_H | 20 | #define __ASM_ARCH_VMALLOC_H |
21 | 21 | ||
22 | /* | ||
23 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
24 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
25 | * physical memory until the kernel virtual memory starts. That means that | ||
26 | * any out-of-bounds memory accesses will hopefully be caught. | ||
27 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
28 | * area for the same reason. ;) | ||
29 | */ | ||
30 | |||
31 | #define VMALLOC_OFFSET (8*1024*1024) | ||
32 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
33 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
34 | #define VMALLOC_END (0xE0000000) | 22 | #define VMALLOC_END (0xE0000000) |
35 | 23 | ||
36 | #endif /* __ASM_ARCH_VMALLOC_H */ | 24 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/include/asm-arm/arch-sa1100/vmalloc.h b/include/asm-arm/arch-sa1100/vmalloc.h index 135bc9493c06..2fb1c6f3aa1b 100644 --- a/include/asm-arm/arch-sa1100/vmalloc.h +++ b/include/asm-arm/arch-sa1100/vmalloc.h | |||
@@ -1,15 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/include/asm-arm/arch-sa1100/vmalloc.h | 2 | * linux/include/asm-arm/arch-sa1100/vmalloc.h |
3 | */ | 3 | */ |
4 | |||
5 | /* | ||
6 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
7 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
8 | * physical memory until the kernel virtual memory starts. That means that | ||
9 | * any out-of-bounds memory accesses will hopefully be caught. | ||
10 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
11 | * area for the same reason. ;) | ||
12 | */ | ||
13 | #define VMALLOC_OFFSET (8*1024*1024) | ||
14 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
15 | #define VMALLOC_END (0xe8000000) | 4 | #define VMALLOC_END (0xe8000000) |
diff --git a/include/asm-arm/arch-shark/vmalloc.h b/include/asm-arm/arch-shark/vmalloc.h index 1cc20098f690..10db5d188231 100644 --- a/include/asm-arm/arch-shark/vmalloc.h +++ b/include/asm-arm/arch-shark/vmalloc.h | |||
@@ -1,15 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/include/asm-arm/arch-rpc/vmalloc.h | 2 | * linux/include/asm-arm/arch-rpc/vmalloc.h |
3 | */ | 3 | */ |
4 | |||
5 | /* | ||
6 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
7 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
8 | * physical memory until the kernel virtual memory starts. That means that | ||
9 | * any out-of-bounds memory accesses will hopefully be caught. | ||
10 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
11 | * area for the same reason. ;) | ||
12 | */ | ||
13 | #define VMALLOC_OFFSET (8*1024*1024) | ||
14 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
15 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | 4 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) |
diff --git a/include/asm-arm/arch-versatile/vmalloc.h b/include/asm-arm/arch-versatile/vmalloc.h index adfb34829bfc..ac780df62156 100644 --- a/include/asm-arm/arch-versatile/vmalloc.h +++ b/include/asm-arm/arch-versatile/vmalloc.h | |||
@@ -18,16 +18,4 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | |||
22 | /* | ||
23 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
24 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
25 | * physical memory until the kernel virtual memory starts. That means that | ||
26 | * any out-of-bounds memory accesses will hopefully be caught. | ||
27 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
28 | * area for the same reason. ;) | ||
29 | */ | ||
30 | #define VMALLOC_OFFSET (8*1024*1024) | ||
31 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
32 | #define VMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
33 | #define VMALLOC_END (PAGE_OFFSET + 0x18000000) | 21 | #define VMALLOC_END (PAGE_OFFSET + 0x18000000) |
diff --git a/include/asm-arm/bug.h b/include/asm-arm/bug.h index 5e91b90a8181..24d11672eb60 100644 --- a/include/asm-arm/bug.h +++ b/include/asm-arm/bug.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
5 | 5 | ||
6 | #ifdef CONFIG_BUG | ||
6 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 7 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
7 | extern volatile void __bug(const char *file, int line, void *data); | 8 | extern volatile void __bug(const char *file, int line, void *data); |
8 | 9 | ||
@@ -17,6 +18,8 @@ extern volatile void __bug(const char *file, int line, void *data); | |||
17 | #endif | 18 | #endif |
18 | 19 | ||
19 | #define HAVE_ARCH_BUG | 20 | #define HAVE_ARCH_BUG |
21 | #endif | ||
22 | |||
20 | #include <asm-generic/bug.h> | 23 | #include <asm-generic/bug.h> |
21 | 24 | ||
22 | #endif | 25 | #endif |
diff --git a/include/asm-arm/hardware/amba_clcd.h b/include/asm-arm/hardware/amba_clcd.h index 2149be7c7023..ce4cf5c1c05d 100644 --- a/include/asm-arm/hardware/amba_clcd.h +++ b/include/asm-arm/hardware/amba_clcd.h | |||
@@ -153,7 +153,7 @@ struct clcd_fb { | |||
153 | 153 | ||
154 | static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) | 154 | static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) |
155 | { | 155 | { |
156 | u32 val; | 156 | u32 val, cpl; |
157 | 157 | ||
158 | /* | 158 | /* |
159 | * Program the CLCD controller registers and start the CLCD | 159 | * Program the CLCD controller registers and start the CLCD |
@@ -164,7 +164,10 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) | |||
164 | val |= (fb->fb.var.left_margin - 1) << 24; | 164 | val |= (fb->fb.var.left_margin - 1) << 24; |
165 | regs->tim0 = val; | 165 | regs->tim0 = val; |
166 | 166 | ||
167 | val = fb->fb.var.yres - 1; | 167 | val = fb->fb.var.yres; |
168 | if (fb->panel->cntl & CNTL_LCDDUAL) | ||
169 | val /= 2; | ||
170 | val -= 1; | ||
168 | val |= (fb->fb.var.vsync_len - 1) << 10; | 171 | val |= (fb->fb.var.vsync_len - 1) << 10; |
169 | val |= fb->fb.var.lower_margin << 16; | 172 | val |= fb->fb.var.lower_margin << 16; |
170 | val |= fb->fb.var.upper_margin << 24; | 173 | val |= fb->fb.var.upper_margin << 24; |
@@ -174,13 +177,17 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) | |||
174 | val |= fb->fb.var.sync & FB_SYNC_HOR_HIGH_ACT ? 0 : TIM2_IHS; | 177 | val |= fb->fb.var.sync & FB_SYNC_HOR_HIGH_ACT ? 0 : TIM2_IHS; |
175 | val |= fb->fb.var.sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS; | 178 | val |= fb->fb.var.sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS; |
176 | 179 | ||
177 | if (fb->panel->cntl & CNTL_LCDTFT) | 180 | cpl = fb->fb.var.xres_virtual; |
178 | val |= (fb->fb.var.xres_virtual - 1) << 16; | 181 | if (fb->panel->cntl & CNTL_LCDTFT) /* TFT */ |
179 | else if (fb->panel->cntl & CNTL_LCDBW) | 182 | /* / 1 */; |
180 | printk("what value for CPL for stnmono panels?"); | 183 | else if (!fb->fb.var.grayscale) /* STN color */ |
181 | else | 184 | cpl = cpl * 8 / 3; |
182 | val |= ((fb->fb.var.xres_virtual * 8 / 3) - 1) << 16; | 185 | else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */ |
183 | regs->tim2 = val; | 186 | cpl /= 8; |
187 | else /* STN monochrome, 4bit */ | ||
188 | cpl /= 4; | ||
189 | |||
190 | regs->tim2 = val | ((cpl - 1) << 16); | ||
184 | 191 | ||
185 | regs->tim3 = fb->panel->tim3; | 192 | regs->tim3 = fb->panel->tim3; |
186 | 193 | ||
@@ -204,7 +211,7 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) | |||
204 | case 16: | 211 | case 16: |
205 | val |= CNTL_LCDBPP16; | 212 | val |= CNTL_LCDBPP16; |
206 | break; | 213 | break; |
207 | case 24: | 214 | case 32: |
208 | val |= CNTL_LCDBPP24; | 215 | val |= CNTL_LCDBPP24; |
209 | break; | 216 | break; |
210 | } | 217 | } |
@@ -215,8 +222,8 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) | |||
215 | 222 | ||
216 | static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var) | 223 | static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var) |
217 | { | 224 | { |
218 | var->xres_virtual = var->xres = (var->xres + 7) & ~7; | 225 | var->xres_virtual = var->xres = (var->xres + 15) & ~15; |
219 | var->yres_virtual = var->yres; | 226 | var->yres_virtual = var->yres = (var->yres + 1) & ~1; |
220 | 227 | ||
221 | #define CHECK(e,l,h) (var->e < l || var->e > h) | 228 | #define CHECK(e,l,h) (var->e < l || var->e > h) |
222 | if (CHECK(right_margin, (5+1), 256) || /* back porch */ | 229 | if (CHECK(right_margin, (5+1), 256) || /* back porch */ |
diff --git a/include/asm-arm/hardware/clock.h b/include/asm-arm/hardware/clock.h index 4983449ff2c7..19da861e523d 100644 --- a/include/asm-arm/hardware/clock.h +++ b/include/asm-arm/hardware/clock.h | |||
@@ -26,10 +26,13 @@ struct clk; | |||
26 | /** | 26 | /** |
27 | * clk_get - lookup and obtain a reference to a clock producer. | 27 | * clk_get - lookup and obtain a reference to a clock producer. |
28 | * @dev: device for clock "consumer" | 28 | * @dev: device for clock "consumer" |
29 | * @id: device ID | 29 | * @id: clock comsumer ID |
30 | * | 30 | * |
31 | * Returns a struct clk corresponding to the clock producer, or | 31 | * Returns a struct clk corresponding to the clock producer, or |
32 | * valid IS_ERR() condition containing errno. | 32 | * valid IS_ERR() condition containing errno. The implementation |
33 | * uses @dev and @id to determine the clock consumer, and thereby | ||
34 | * the clock producer. (IOW, @id may be identical strings, but | ||
35 | * clk_get may return different clock producers depending on @dev.) | ||
33 | */ | 36 | */ |
34 | struct clk *clk_get(struct device *dev, const char *id); | 37 | struct clk *clk_get(struct device *dev, const char *id); |
35 | 38 | ||
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 69bc7a3e8160..658ffa384fda 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h | |||
@@ -99,12 +99,16 @@ extern void __readwrite_bug(const char *fn); | |||
99 | */ | 99 | */ |
100 | #ifdef __io | 100 | #ifdef __io |
101 | #define outb(v,p) __raw_writeb(v,__io(p)) | 101 | #define outb(v,p) __raw_writeb(v,__io(p)) |
102 | #define outw(v,p) __raw_writew(cpu_to_le16(v),__io(p)) | 102 | #define outw(v,p) __raw_writew((__force __u16) \ |
103 | #define outl(v,p) __raw_writel(cpu_to_le32(v),__io(p)) | 103 | cpu_to_le16(v),__io(p)) |
104 | #define outl(v,p) __raw_writel((__force __u32) \ | ||
105 | cpu_to_le32(v),__io(p)) | ||
104 | 106 | ||
105 | #define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; }) | 107 | #define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; }) |
106 | #define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; }) | 108 | #define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \ |
107 | #define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; }) | 109 | __raw_readw(__io(p))); __v; }) |
110 | #define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \ | ||
111 | __raw_readl(__io(p))); __v; }) | ||
108 | 112 | ||
109 | #define outsb(p,d,l) __raw_writesb(__io(p),d,l) | 113 | #define outsb(p,d,l) __raw_writesb(__io(p),d,l) |
110 | #define outsw(p,d,l) __raw_writesw(__io(p),d,l) | 114 | #define outsw(p,d,l) __raw_writesw(__io(p),d,l) |
@@ -149,9 +153,11 @@ extern void _memset_io(void __iomem *, int, size_t); | |||
149 | * IO port primitives for more information. | 153 | * IO port primitives for more information. |
150 | */ | 154 | */ |
151 | #ifdef __mem_pci | 155 | #ifdef __mem_pci |
152 | #define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; }) | 156 | #define readb(c) ({ __u8 __v = __raw_readb(__mem_pci(c)); __v; }) |
153 | #define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) | 157 | #define readw(c) ({ __u16 __v = le16_to_cpu((__force __le16) \ |
154 | #define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) | 158 | __raw_readw(__mem_pci(c))); __v; }) |
159 | #define readl(c) ({ __u32 __v = le32_to_cpu((__force __le32) \ | ||
160 | __raw_readl(__mem_pci(c))); __v; }) | ||
155 | #define readb_relaxed(addr) readb(addr) | 161 | #define readb_relaxed(addr) readb(addr) |
156 | #define readw_relaxed(addr) readw(addr) | 162 | #define readw_relaxed(addr) readw(addr) |
157 | #define readl_relaxed(addr) readl(addr) | 163 | #define readl_relaxed(addr) readl(addr) |
@@ -161,8 +167,10 @@ extern void _memset_io(void __iomem *, int, size_t); | |||
161 | #define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l) | 167 | #define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l) |
162 | 168 | ||
163 | #define writeb(v,c) __raw_writeb(v,__mem_pci(c)) | 169 | #define writeb(v,c) __raw_writeb(v,__mem_pci(c)) |
164 | #define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c)) | 170 | #define writew(v,c) __raw_writew((__force __u16) \ |
165 | #define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c)) | 171 | cpu_to_le16(v),__mem_pci(c)) |
172 | #define writel(v,c) __raw_writel((__force __u32) \ | ||
173 | cpu_to_le32(v),__mem_pci(c)) | ||
166 | 174 | ||
167 | #define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l) | 175 | #define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l) |
168 | #define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l) | 176 | #define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l) |
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h index 2df4eacf4fa9..a9892eb42a23 100644 --- a/include/asm-arm/pgtable.h +++ b/include/asm-arm/pgtable.h | |||
@@ -17,6 +17,23 @@ | |||
17 | #include <asm/arch/vmalloc.h> | 17 | #include <asm/arch/vmalloc.h> |
18 | 18 | ||
19 | /* | 19 | /* |
20 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
21 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
22 | * physical memory until the kernel virtual memory starts. That means that | ||
23 | * any out-of-bounds memory accesses will hopefully be caught. | ||
24 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
25 | * area for the same reason. ;) | ||
26 | * | ||
27 | * Note that platforms may override VMALLOC_START, but they must provide | ||
28 | * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space, | ||
29 | * which may not overlap IO space. | ||
30 | */ | ||
31 | #ifndef VMALLOC_START | ||
32 | #define VMALLOC_OFFSET (8*1024*1024) | ||
33 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
34 | #endif | ||
35 | |||
36 | /* | ||
20 | * Hardware-wise, we have a two level page table structure, where the first | 37 | * Hardware-wise, we have a two level page table structure, where the first |
21 | * level has 4096 entries, and the second level has 256 entries. Each entry | 38 | * level has 4096 entries, and the second level has 256 entries. Each entry |
22 | * is one 32-bit word. Most of the bits in the second level entry are used | 39 | * is one 32-bit word. Most of the bits in the second level entry are used |
diff --git a/include/asm-arm/rtc.h b/include/asm-arm/rtc.h index aa7e16b2e225..370dfe77589d 100644 --- a/include/asm-arm/rtc.h +++ b/include/asm-arm/rtc.h | |||
@@ -18,9 +18,9 @@ struct rtc_ops { | |||
18 | void (*release)(void); | 18 | void (*release)(void); |
19 | int (*ioctl)(unsigned int, unsigned long); | 19 | int (*ioctl)(unsigned int, unsigned long); |
20 | 20 | ||
21 | void (*read_time)(struct rtc_time *); | 21 | int (*read_time)(struct rtc_time *); |
22 | int (*set_time)(struct rtc_time *); | 22 | int (*set_time)(struct rtc_time *); |
23 | void (*read_alarm)(struct rtc_wkalrm *); | 23 | int (*read_alarm)(struct rtc_wkalrm *); |
24 | int (*set_alarm)(struct rtc_wkalrm *); | 24 | int (*set_alarm)(struct rtc_wkalrm *); |
25 | int (*proc)(char *buf); | 25 | int (*proc)(char *buf); |
26 | }; | 26 | }; |
diff --git a/include/asm-arm/signal.h b/include/asm-arm/signal.h index b033e5fd60fa..b860dc3c5dc7 100644 --- a/include/asm-arm/signal.h +++ b/include/asm-arm/signal.h | |||
@@ -114,18 +114,7 @@ typedef unsigned long sigset_t; | |||
114 | #define SIGSTKSZ 8192 | 114 | #define SIGSTKSZ 8192 |
115 | 115 | ||
116 | #ifdef __KERNEL__ | 116 | #ifdef __KERNEL__ |
117 | |||
118 | /* | ||
119 | * These values of sa_flags are used only by the kernel as part of the | ||
120 | * irq handling routines. | ||
121 | * | ||
122 | * SA_INTERRUPT is also used by the irq handling routines. | ||
123 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
124 | */ | ||
125 | #define SA_PROBE 0x80000000 | ||
126 | #define SA_SAMPLE_RANDOM 0x10000000 | ||
127 | #define SA_IRQNOMASK 0x08000000 | 117 | #define SA_IRQNOMASK 0x08000000 |
128 | #define SA_SHIRQ 0x04000000 | ||
129 | #endif | 118 | #endif |
130 | 119 | ||
131 | #define SIG_BLOCK 0 /* for blocking signals */ | 120 | #define SIG_BLOCK 0 /* for blocking signals */ |
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index a19ec09eaa01..ace27480886e 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h | |||
@@ -359,8 +359,7 @@ | |||
359 | #define __ARM_NR_cacheflush (__ARM_NR_BASE+2) | 359 | #define __ARM_NR_cacheflush (__ARM_NR_BASE+2) |
360 | #define __ARM_NR_usr26 (__ARM_NR_BASE+3) | 360 | #define __ARM_NR_usr26 (__ARM_NR_BASE+3) |
361 | #define __ARM_NR_usr32 (__ARM_NR_BASE+4) | 361 | #define __ARM_NR_usr32 (__ARM_NR_BASE+4) |
362 | 362 | #define __ARM_NR_set_tls (__ARM_NR_BASE+5) | |
363 | #define __ARM_NR_set_tls (__ARM_NR_BASE+0x800) | ||
364 | 363 | ||
365 | #define __sys2(x) #x | 364 | #define __sys2(x) #x |
366 | #define __sys1(x) __sys2(x) | 365 | #define __sys1(x) __sys2(x) |
diff --git a/include/asm-arm26/bug.h b/include/asm-arm26/bug.h index 920b70533368..7177c7399967 100644 --- a/include/asm-arm26/bug.h +++ b/include/asm-arm26/bug.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
5 | 5 | ||
6 | #ifdef CONFIG_BUG | ||
6 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 7 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
7 | extern volatile void __bug(const char *file, int line, void *data); | 8 | extern volatile void __bug(const char *file, int line, void *data); |
8 | /* give file/line information */ | 9 | /* give file/line information */ |
@@ -12,6 +13,8 @@ extern volatile void __bug(const char *file, int line, void *data); | |||
12 | #endif | 13 | #endif |
13 | 14 | ||
14 | #define HAVE_ARCH_BUG | 15 | #define HAVE_ARCH_BUG |
16 | #endif | ||
17 | |||
15 | #include <asm-generic/bug.h> | 18 | #include <asm-generic/bug.h> |
16 | 19 | ||
17 | #endif | 20 | #endif |
diff --git a/include/asm-arm26/signal.h b/include/asm-arm26/signal.h index 6f62e51a2e5a..a1aacefa6562 100644 --- a/include/asm-arm26/signal.h +++ b/include/asm-arm26/signal.h | |||
@@ -114,18 +114,7 @@ typedef unsigned long sigset_t; | |||
114 | #define SIGSTKSZ 8192 | 114 | #define SIGSTKSZ 8192 |
115 | 115 | ||
116 | #ifdef __KERNEL__ | 116 | #ifdef __KERNEL__ |
117 | |||
118 | /* | ||
119 | * These values of sa_flags are used only by the kernel as part of the | ||
120 | * irq handling routines. | ||
121 | * | ||
122 | * SA_INTERRUPT is also used by the irq handling routines. | ||
123 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
124 | */ | ||
125 | #define SA_PROBE 0x80000000 | ||
126 | #define SA_SAMPLE_RANDOM 0x10000000 | ||
127 | #define SA_IRQNOMASK 0x08000000 | 117 | #define SA_IRQNOMASK 0x08000000 |
128 | #define SA_SHIRQ 0x04000000 | ||
129 | #endif | 118 | #endif |
130 | 119 | ||
131 | #define SIG_BLOCK 0 /* for blocking signals */ | 120 | #define SIG_BLOCK 0 /* for blocking signals */ |
diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h index ddd8915e41e6..c767da1ef8f5 100644 --- a/include/asm-cris/page.h +++ b/include/asm-cris/page.h | |||
@@ -77,10 +77,6 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
77 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | 77 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ |
78 | } while (0) | 78 | } while (0) |
79 | 79 | ||
80 | #define PAGE_BUG(page) do { \ | ||
81 | BUG(); \ | ||
82 | } while (0) | ||
83 | |||
84 | /* Pure 2^n version of get_order */ | 80 | /* Pure 2^n version of get_order */ |
85 | static inline int get_order(unsigned long size) | 81 | static inline int get_order(unsigned long size) |
86 | { | 82 | { |
diff --git a/include/asm-cris/signal.h b/include/asm-cris/signal.h index 3f187ec4800a..2330769ba55d 100644 --- a/include/asm-cris/signal.h +++ b/include/asm-cris/signal.h | |||
@@ -108,20 +108,6 @@ typedef unsigned long sigset_t; | |||
108 | #define MINSIGSTKSZ 2048 | 108 | #define MINSIGSTKSZ 2048 |
109 | #define SIGSTKSZ 8192 | 109 | #define SIGSTKSZ 8192 |
110 | 110 | ||
111 | #ifdef __KERNEL__ | ||
112 | |||
113 | /* | ||
114 | * These values of sa_flags are used only by the kernel as part of the | ||
115 | * irq handling routines. | ||
116 | * | ||
117 | * SA_INTERRUPT is also used by the irq handling routines. | ||
118 | * SA_SHIRQ is for shared interrupt support | ||
119 | */ | ||
120 | #define SA_PROBE SA_ONESHOT | ||
121 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
122 | #define SA_SHIRQ 0x04000000 | ||
123 | #endif | ||
124 | |||
125 | #define SIG_BLOCK 0 /* for blocking signals */ | 111 | #define SIG_BLOCK 0 /* for blocking signals */ |
126 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 112 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
127 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 113 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-frv/bug.h b/include/asm-frv/bug.h index 011860b28818..074c0d5770eb 100644 --- a/include/asm-frv/bug.h +++ b/include/asm-frv/bug.h | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/config.h> | 14 | #include <linux/config.h> |
15 | 15 | ||
16 | #ifdef CONFIG_BUG | ||
16 | /* | 17 | /* |
17 | * Tell the user there is some problem. | 18 | * Tell the user there is some problem. |
18 | */ | 19 | */ |
@@ -45,6 +46,7 @@ do { \ | |||
45 | #define HAVE_ARCH_KGDB_BAD_PAGE | 46 | #define HAVE_ARCH_KGDB_BAD_PAGE |
46 | #define kgdb_bad_page(page) do { kgdb_raise(SIGABRT); } while(0) | 47 | #define kgdb_bad_page(page) do { kgdb_raise(SIGABRT); } while(0) |
47 | #endif | 48 | #endif |
49 | #endif | ||
48 | 50 | ||
49 | #include <asm-generic/bug.h> | 51 | #include <asm-generic/bug.h> |
50 | 52 | ||
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h index 3c6d42a22dfe..d0a9c2f9c13e 100644 --- a/include/asm-frv/pgtable.h +++ b/include/asm-frv/pgtable.h | |||
@@ -349,9 +349,9 @@ static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address) | |||
349 | 349 | ||
350 | /* | 350 | /* |
351 | * Define this to warn about kernel memory accesses that are | 351 | * Define this to warn about kernel memory accesses that are |
352 | * done without a 'verify_area(VERIFY_WRITE,..)' | 352 | * done without a 'access_ok(VERIFY_WRITE,..)' |
353 | */ | 353 | */ |
354 | #undef TEST_VERIFY_AREA | 354 | #undef TEST_ACCESS_OK |
355 | 355 | ||
356 | #define pte_present(x) (pte_val(x) & _PAGE_PRESENT) | 356 | #define pte_present(x) (pte_val(x) & _PAGE_PRESENT) |
357 | #define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) | 357 | #define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) |
diff --git a/include/asm-frv/signal.h b/include/asm-frv/signal.h index f18952f86a80..c930bb176875 100644 --- a/include/asm-frv/signal.h +++ b/include/asm-frv/signal.h | |||
@@ -107,20 +107,6 @@ typedef unsigned long sigset_t; | |||
107 | #define MINSIGSTKSZ 2048 | 107 | #define MINSIGSTKSZ 2048 |
108 | #define SIGSTKSZ 8192 | 108 | #define SIGSTKSZ 8192 |
109 | 109 | ||
110 | #ifdef __KERNEL__ | ||
111 | |||
112 | /* | ||
113 | * These values of sa_flags are used only by the kernel as part of the | ||
114 | * irq handling routines. | ||
115 | * | ||
116 | * SA_INTERRUPT is also used by the irq handling routines. | ||
117 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
118 | */ | ||
119 | #define SA_PROBE SA_ONESHOT | ||
120 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
121 | #define SA_SHIRQ 0x04000000 | ||
122 | #endif | ||
123 | |||
124 | #define SIG_BLOCK 0 /* for blocking signals */ | 110 | #define SIG_BLOCK 0 /* for blocking signals */ |
125 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 111 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
126 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 112 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index e5913c3b715a..400c2b41896e 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
6 | 6 | ||
7 | #ifdef CONFIG_BUG | ||
7 | #ifndef HAVE_ARCH_BUG | 8 | #ifndef HAVE_ARCH_BUG |
8 | #define BUG() do { \ | 9 | #define BUG() do { \ |
9 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | 10 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ |
@@ -11,13 +12,6 @@ | |||
11 | } while (0) | 12 | } while (0) |
12 | #endif | 13 | #endif |
13 | 14 | ||
14 | #ifndef HAVE_ARCH_PAGE_BUG | ||
15 | #define PAGE_BUG(page) do { \ | ||
16 | printk("page BUG for page at %p\n", page); \ | ||
17 | BUG(); \ | ||
18 | } while (0) | ||
19 | #endif | ||
20 | |||
21 | #ifndef HAVE_ARCH_BUG_ON | 15 | #ifndef HAVE_ARCH_BUG_ON |
22 | #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) | 16 | #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) |
23 | #endif | 17 | #endif |
@@ -31,4 +25,18 @@ | |||
31 | } while (0) | 25 | } while (0) |
32 | #endif | 26 | #endif |
33 | 27 | ||
28 | #else /* !CONFIG_BUG */ | ||
29 | #ifndef HAVE_ARCH_BUG | ||
30 | #define BUG() | ||
31 | #endif | ||
32 | |||
33 | #ifndef HAVE_ARCH_BUG_ON | ||
34 | #define BUG_ON(condition) do { if (condition) ; } while(0) | ||
35 | #endif | ||
36 | |||
37 | #ifndef HAVE_ARCH_WARN_ON | ||
38 | #define WARN_ON(condition) do { if (condition) ; } while(0) | ||
39 | #endif | ||
40 | #endif | ||
41 | |||
34 | #endif | 42 | #endif |
diff --git a/include/asm-generic/errno.h b/include/asm-generic/errno.h index 4dd2384bc38d..e8852c092fea 100644 --- a/include/asm-generic/errno.h +++ b/include/asm-generic/errno.h | |||
@@ -102,4 +102,8 @@ | |||
102 | #define EKEYREVOKED 128 /* Key has been revoked */ | 102 | #define EKEYREVOKED 128 /* Key has been revoked */ |
103 | #define EKEYREJECTED 129 /* Key was rejected by service */ | 103 | #define EKEYREJECTED 129 /* Key was rejected by service */ |
104 | 104 | ||
105 | /* for robust mutexes */ | ||
106 | #define EOWNERDEAD 130 /* Owner died */ | ||
107 | #define ENOTRECOVERABLE 131 /* State not recoverable */ | ||
108 | |||
105 | #endif | 109 | #endif |
diff --git a/include/asm-generic/resource.h b/include/asm-generic/resource.h index b1fcda9eac23..cfe3692b23e5 100644 --- a/include/asm-generic/resource.h +++ b/include/asm-generic/resource.h | |||
@@ -41,8 +41,11 @@ | |||
41 | #define RLIMIT_LOCKS 10 /* maximum file locks held */ | 41 | #define RLIMIT_LOCKS 10 /* maximum file locks held */ |
42 | #define RLIMIT_SIGPENDING 11 /* max number of pending signals */ | 42 | #define RLIMIT_SIGPENDING 11 /* max number of pending signals */ |
43 | #define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */ | 43 | #define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */ |
44 | #define RLIMIT_NICE 13 /* max nice prio allowed to raise to | ||
45 | 0-39 for nice level 19 .. -20 */ | ||
46 | #define RLIMIT_RTPRIO 14 /* maximum realtime priority */ | ||
44 | 47 | ||
45 | #define RLIM_NLIMITS 13 | 48 | #define RLIM_NLIMITS 15 |
46 | 49 | ||
47 | /* | 50 | /* |
48 | * SuS says limits have to be unsigned. | 51 | * SuS says limits have to be unsigned. |
@@ -81,6 +84,8 @@ | |||
81 | [RLIMIT_LOCKS] = { RLIM_INFINITY, RLIM_INFINITY }, \ | 84 | [RLIMIT_LOCKS] = { RLIM_INFINITY, RLIM_INFINITY }, \ |
82 | [RLIMIT_SIGPENDING] = { 0, 0 }, \ | 85 | [RLIMIT_SIGPENDING] = { 0, 0 }, \ |
83 | [RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX }, \ | 86 | [RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX }, \ |
87 | [RLIMIT_NICE] = { 0, 0 }, \ | ||
88 | [RLIMIT_RTPRIO] = { 0, 0 }, \ | ||
84 | } | 89 | } |
85 | 90 | ||
86 | #endif /* __KERNEL__ */ | 91 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h index 9cac8e8dde51..8786e01e0db8 100644 --- a/include/asm-generic/siginfo.h +++ b/include/asm-generic/siginfo.h | |||
@@ -236,11 +236,18 @@ typedef struct siginfo { | |||
236 | #define SIGEV_THREAD 2 /* deliver via thread creation */ | 236 | #define SIGEV_THREAD 2 /* deliver via thread creation */ |
237 | #define SIGEV_THREAD_ID 4 /* deliver to thread */ | 237 | #define SIGEV_THREAD_ID 4 /* deliver to thread */ |
238 | 238 | ||
239 | #define SIGEV_MAX_SIZE 64 | 239 | /* |
240 | #ifndef SIGEV_PAD_SIZE | 240 | * This works because the alignment is ok on all current architectures |
241 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) | 241 | * but we leave open this being overridden in the future |
242 | */ | ||
243 | #ifndef __ARCH_SIGEV_PREAMBLE_SIZE | ||
244 | #define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(int) * 2 + sizeof(sigval_t)) | ||
242 | #endif | 245 | #endif |
243 | 246 | ||
247 | #define SIGEV_MAX_SIZE 64 | ||
248 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE) \ | ||
249 | / sizeof(int)) | ||
250 | |||
244 | typedef struct sigevent { | 251 | typedef struct sigevent { |
245 | sigval_t sigev_value; | 252 | sigval_t sigev_value; |
246 | int sigev_signo; | 253 | int sigev_signo; |
diff --git a/include/asm-h8300/signal.h b/include/asm-h8300/signal.h index 3a08544a473e..ac3e01bd6396 100644 --- a/include/asm-h8300/signal.h +++ b/include/asm-h8300/signal.h | |||
@@ -107,19 +107,6 @@ typedef unsigned long sigset_t; | |||
107 | #define MINSIGSTKSZ 2048 | 107 | #define MINSIGSTKSZ 2048 |
108 | #define SIGSTKSZ 8192 | 108 | #define SIGSTKSZ 8192 |
109 | 109 | ||
110 | #ifdef __KERNEL__ | ||
111 | /* | ||
112 | * These values of sa_flags are used only by the kernel as part of the | ||
113 | * irq handling routines. | ||
114 | * | ||
115 | * SA_INTERRUPT is also used by the irq handling routines. | ||
116 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
117 | */ | ||
118 | #define SA_PROBE SA_ONESHOT | ||
119 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
120 | #define SA_SHIRQ 0x04000000 | ||
121 | #endif | ||
122 | |||
123 | #define SIG_BLOCK 0 /* for blocking signals */ | 110 | #define SIG_BLOCK 0 /* for blocking signals */ |
124 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 111 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
125 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 112 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index e1de67483f38..a5810cf7b578 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h | |||
@@ -109,7 +109,6 @@ extern int APIC_init_uniprocessor (void); | |||
109 | extern void disable_APIC_timer(void); | 109 | extern void disable_APIC_timer(void); |
110 | extern void enable_APIC_timer(void); | 110 | extern void enable_APIC_timer(void); |
111 | 111 | ||
112 | extern int check_nmi_watchdog (void); | ||
113 | extern void enable_NMI_through_LVT0 (void * dummy); | 112 | extern void enable_NMI_through_LVT0 (void * dummy); |
114 | 113 | ||
115 | extern unsigned int nmi_watchdog; | 114 | extern unsigned int nmi_watchdog; |
diff --git a/include/asm-i386/bug.h b/include/asm-i386/bug.h index 706eb511c330..8f79de19eb94 100644 --- a/include/asm-i386/bug.h +++ b/include/asm-i386/bug.h | |||
@@ -9,6 +9,8 @@ | |||
9 | * undefined" opcode for parsing in the trap handler. | 9 | * undefined" opcode for parsing in the trap handler. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifdef CONFIG_BUG | ||
13 | #define HAVE_ARCH_BUG | ||
12 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 14 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
13 | #define BUG() \ | 15 | #define BUG() \ |
14 | __asm__ __volatile__( "ud2\n" \ | 16 | __asm__ __volatile__( "ud2\n" \ |
@@ -18,8 +20,7 @@ | |||
18 | #else | 20 | #else |
19 | #define BUG() __asm__ __volatile__("ud2\n") | 21 | #define BUG() __asm__ __volatile__("ud2\n") |
20 | #endif | 22 | #endif |
23 | #endif | ||
21 | 24 | ||
22 | #define HAVE_ARCH_BUG | ||
23 | #include <asm-generic/bug.h> | 25 | #include <asm-generic/bug.h> |
24 | |||
25 | #endif | 26 | #endif |
diff --git a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h index d76a5f081c91..641342002bcd 100644 --- a/include/asm-i386/checksum.h +++ b/include/asm-i386/checksum.h | |||
@@ -33,7 +33,7 @@ asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsi | |||
33 | * passed in an incorrect kernel address to one of these functions. | 33 | * passed in an incorrect kernel address to one of these functions. |
34 | * | 34 | * |
35 | * If you use these functions directly please don't forget the | 35 | * If you use these functions directly please don't forget the |
36 | * verify_area(). | 36 | * access_ok(). |
37 | */ | 37 | */ |
38 | static __inline__ | 38 | static __inline__ |
39 | unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, | 39 | unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, |
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index e147cabd3bfe..ff1187e80c32 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h | |||
@@ -87,8 +87,8 @@ | |||
87 | #define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ | 87 | #define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ |
88 | 88 | ||
89 | /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ | 89 | /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ |
90 | #define X86_FEATURE_LAHF_LM (5*32+ 0) /* LAHF/SAHF in long mode */ | 90 | #define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ |
91 | #define X86_FEATURE_CMP_LEGACY (5*32+ 1) /* If yes HyperThreading not valid */ | 91 | #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */ |
92 | 92 | ||
93 | #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) | 93 | #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) |
94 | #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) | 94 | #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) |
diff --git a/include/asm-i386/e820.h b/include/asm-i386/e820.h index 5c285aee7294..edf65be21a92 100644 --- a/include/asm-i386/e820.h +++ b/include/asm-i386/e820.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #define __E820_HEADER | 13 | #define __E820_HEADER |
14 | 14 | ||
15 | #define E820MAP 0x2d0 /* our map */ | 15 | #define E820MAP 0x2d0 /* our map */ |
16 | #define E820MAX 32 /* number of entries in E820MAP */ | 16 | #define E820MAX 128 /* number of entries in E820MAP */ |
17 | #define E820NR 0x1e8 /* # entries in E820MAP */ | 17 | #define E820NR 0x1e8 /* # entries in E820MAP */ |
18 | 18 | ||
19 | #define E820_RAM 1 | 19 | #define E820_RAM 1 |
diff --git a/include/asm-i386/hpet.h b/include/asm-i386/hpet.h index 6e20b079f1d3..16ef9f996e3f 100644 --- a/include/asm-i386/hpet.h +++ b/include/asm-i386/hpet.h | |||
@@ -92,6 +92,7 @@ | |||
92 | 92 | ||
93 | extern unsigned long hpet_tick; /* hpet clks count per tick */ | 93 | extern unsigned long hpet_tick; /* hpet clks count per tick */ |
94 | extern unsigned long hpet_address; /* hpet memory map physical address */ | 94 | extern unsigned long hpet_address; /* hpet memory map physical address */ |
95 | extern int hpet_use_timer; | ||
95 | 96 | ||
96 | extern int hpet_rtc_timer_init(void); | 97 | extern int hpet_rtc_timer_init(void); |
97 | extern int hpet_enable(void); | 98 | extern int hpet_enable(void); |
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 5c725425d863..8d60c2b4b003 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h | |||
@@ -193,9 +193,9 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; | |||
193 | /* | 193 | /* |
194 | * Define this if things work differently on an i386 and an i486: | 194 | * Define this if things work differently on an i386 and an i486: |
195 | * it will (on an i486) warn about kernel memory accesses that are | 195 | * it will (on an i486) warn about kernel memory accesses that are |
196 | * done without a 'verify_area(VERIFY_WRITE,..)' | 196 | * done without a 'access_ok(VERIFY_WRITE,..)' |
197 | */ | 197 | */ |
198 | #undef TEST_VERIFY_AREA | 198 | #undef TEST_ACCESS_OK |
199 | 199 | ||
200 | /* The boot page tables (all created as a single array) */ | 200 | /* The boot page tables (all created as a single array) */ |
201 | extern unsigned long pg0[]; | 201 | extern unsigned long pg0[]; |
diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h index 8814b54c75d4..7a32184d54bf 100644 --- a/include/asm-i386/setup.h +++ b/include/asm-i386/setup.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define MAXMEM_PFN PFN_DOWN(MAXMEM) | 16 | #define MAXMEM_PFN PFN_DOWN(MAXMEM) |
17 | #define MAX_NONPAE_PFN (1 << 20) | 17 | #define MAX_NONPAE_PFN (1 << 20) |
18 | 18 | ||
19 | #define PARAM_SIZE 2048 | 19 | #define PARAM_SIZE 4096 |
20 | #define COMMAND_LINE_SIZE 256 | 20 | #define COMMAND_LINE_SIZE 256 |
21 | 21 | ||
22 | #define OLD_CL_MAGIC_ADDR 0x90020 | 22 | #define OLD_CL_MAGIC_ADDR 0x90020 |
diff --git a/include/asm-i386/signal.h b/include/asm-i386/signal.h index 7ef343b6812d..0f082bd1c455 100644 --- a/include/asm-i386/signal.h +++ b/include/asm-i386/signal.h | |||
@@ -110,20 +110,6 @@ typedef unsigned long sigset_t; | |||
110 | #define MINSIGSTKSZ 2048 | 110 | #define MINSIGSTKSZ 2048 |
111 | #define SIGSTKSZ 8192 | 111 | #define SIGSTKSZ 8192 |
112 | 112 | ||
113 | #ifdef __KERNEL__ | ||
114 | |||
115 | /* | ||
116 | * These values of sa_flags are used only by the kernel as part of the | ||
117 | * irq handling routines. | ||
118 | * | ||
119 | * SA_INTERRUPT is also used by the irq handling routines. | ||
120 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
121 | */ | ||
122 | #define SA_PROBE SA_ONESHOT | ||
123 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
124 | #define SA_SHIRQ 0x04000000 | ||
125 | #endif | ||
126 | |||
127 | #define SIG_BLOCK 0 /* for blocking signals */ | 113 | #define SIG_BLOCK 0 /* for blocking signals */ |
128 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 114 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
129 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 115 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h index 1679983d053f..6a78ac58c194 100644 --- a/include/asm-i386/string.h +++ b/include/asm-i386/string.h | |||
@@ -198,47 +198,80 @@ static inline void * __memcpy(void * to, const void * from, size_t n) | |||
198 | int d0, d1, d2; | 198 | int d0, d1, d2; |
199 | __asm__ __volatile__( | 199 | __asm__ __volatile__( |
200 | "rep ; movsl\n\t" | 200 | "rep ; movsl\n\t" |
201 | "testb $2,%b4\n\t" | 201 | "movl %4,%%ecx\n\t" |
202 | "je 1f\n\t" | 202 | "andl $3,%%ecx\n\t" |
203 | "movsw\n" | 203 | #if 1 /* want to pay 2 byte penalty for a chance to skip microcoded rep? */ |
204 | "1:\ttestb $1,%b4\n\t" | 204 | "jz 1f\n\t" |
205 | "je 2f\n\t" | 205 | #endif |
206 | "movsb\n" | 206 | "rep ; movsb\n\t" |
207 | "2:" | 207 | "1:" |
208 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) | 208 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) |
209 | :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) | 209 | : "0" (n/4), "g" (n), "1" ((long) to), "2" ((long) from) |
210 | : "memory"); | 210 | : "memory"); |
211 | return (to); | 211 | return (to); |
212 | } | 212 | } |
213 | 213 | ||
214 | /* | 214 | /* |
215 | * This looks horribly ugly, but the compiler can optimize it totally, | 215 | * This looks ugly, but the compiler can optimize it totally, |
216 | * as the count is constant. | 216 | * as the count is constant. |
217 | */ | 217 | */ |
218 | static inline void * __constant_memcpy(void * to, const void * from, size_t n) | 218 | static inline void * __constant_memcpy(void * to, const void * from, size_t n) |
219 | { | 219 | { |
220 | if (n <= 128) | 220 | long esi, edi; |
221 | return __builtin_memcpy(to, from, n); | 221 | if (!n) return to; |
222 | 222 | #if 1 /* want to do small copies with non-string ops? */ | |
223 | #define COMMON(x) \ | 223 | switch (n) { |
224 | __asm__ __volatile__( \ | 224 | case 1: *(char*)to = *(char*)from; return to; |
225 | "rep ; movsl" \ | 225 | case 2: *(short*)to = *(short*)from; return to; |
226 | x \ | 226 | case 4: *(int*)to = *(int*)from; return to; |
227 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) \ | 227 | #if 1 /* including those doable with two moves? */ |
228 | : "0" (n/4),"1" ((long) to),"2" ((long) from) \ | 228 | case 3: *(short*)to = *(short*)from; |
229 | : "memory"); | 229 | *((char*)to+2) = *((char*)from+2); return to; |
230 | { | 230 | case 5: *(int*)to = *(int*)from; |
231 | int d0, d1, d2; | 231 | *((char*)to+4) = *((char*)from+4); return to; |
232 | case 6: *(int*)to = *(int*)from; | ||
233 | *((short*)to+2) = *((short*)from+2); return to; | ||
234 | case 8: *(int*)to = *(int*)from; | ||
235 | *((int*)to+1) = *((int*)from+1); return to; | ||
236 | #endif | ||
237 | } | ||
238 | #endif | ||
239 | esi = (long) from; | ||
240 | edi = (long) to; | ||
241 | if (n >= 5*4) { | ||
242 | /* large block: use rep prefix */ | ||
243 | int ecx; | ||
244 | __asm__ __volatile__( | ||
245 | "rep ; movsl" | ||
246 | : "=&c" (ecx), "=&D" (edi), "=&S" (esi) | ||
247 | : "0" (n/4), "1" (edi),"2" (esi) | ||
248 | : "memory" | ||
249 | ); | ||
250 | } else { | ||
251 | /* small block: don't clobber ecx + smaller code */ | ||
252 | if (n >= 4*4) __asm__ __volatile__("movsl" | ||
253 | :"=&D"(edi),"=&S"(esi):"0"(edi),"1"(esi):"memory"); | ||
254 | if (n >= 3*4) __asm__ __volatile__("movsl" | ||
255 | :"=&D"(edi),"=&S"(esi):"0"(edi),"1"(esi):"memory"); | ||
256 | if (n >= 2*4) __asm__ __volatile__("movsl" | ||
257 | :"=&D"(edi),"=&S"(esi):"0"(edi),"1"(esi):"memory"); | ||
258 | if (n >= 1*4) __asm__ __volatile__("movsl" | ||
259 | :"=&D"(edi),"=&S"(esi):"0"(edi),"1"(esi):"memory"); | ||
260 | } | ||
232 | switch (n % 4) { | 261 | switch (n % 4) { |
233 | case 0: COMMON(""); return to; | 262 | /* tail */ |
234 | case 1: COMMON("\n\tmovsb"); return to; | 263 | case 0: return to; |
235 | case 2: COMMON("\n\tmovsw"); return to; | 264 | case 1: __asm__ __volatile__("movsb" |
236 | default: COMMON("\n\tmovsw\n\tmovsb"); return to; | 265 | :"=&D"(edi),"=&S"(esi):"0"(edi),"1"(esi):"memory"); |
266 | return to; | ||
267 | case 2: __asm__ __volatile__("movsw" | ||
268 | :"=&D"(edi),"=&S"(esi):"0"(edi),"1"(esi):"memory"); | ||
269 | return to; | ||
270 | default: __asm__ __volatile__("movsw\n\tmovsb" | ||
271 | :"=&D"(edi),"=&S"(esi):"0"(edi),"1"(esi):"memory"); | ||
272 | return to; | ||
237 | } | 273 | } |
238 | } | 274 | } |
239 | |||
240 | #undef COMMON | ||
241 | } | ||
242 | 275 | ||
243 | #define __HAVE_ARCH_MEMCPY | 276 | #define __HAVE_ARCH_MEMCPY |
244 | 277 | ||
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index 6f74d4c44a0e..3db717a244f0 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h | |||
@@ -81,7 +81,7 @@ static inline unsigned long _get_base(char * addr) | |||
81 | #define loadsegment(seg,value) \ | 81 | #define loadsegment(seg,value) \ |
82 | asm volatile("\n" \ | 82 | asm volatile("\n" \ |
83 | "1:\t" \ | 83 | "1:\t" \ |
84 | "movl %0,%%" #seg "\n" \ | 84 | "mov %0,%%" #seg "\n" \ |
85 | "2:\n" \ | 85 | "2:\n" \ |
86 | ".section .fixup,\"ax\"\n" \ | 86 | ".section .fixup,\"ax\"\n" \ |
87 | "3:\t" \ | 87 | "3:\t" \ |
@@ -93,13 +93,13 @@ static inline unsigned long _get_base(char * addr) | |||
93 | ".align 4\n\t" \ | 93 | ".align 4\n\t" \ |
94 | ".long 1b,3b\n" \ | 94 | ".long 1b,3b\n" \ |
95 | ".previous" \ | 95 | ".previous" \ |
96 | : :"m" (*(unsigned int *)&(value))) | 96 | : :"m" (value)) |
97 | 97 | ||
98 | /* | 98 | /* |
99 | * Save a segment register away | 99 | * Save a segment register away |
100 | */ | 100 | */ |
101 | #define savesegment(seg, value) \ | 101 | #define savesegment(seg, value) \ |
102 | asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value))) | 102 | asm volatile("mov %%" #seg ",%0":"=m" (value)) |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Clear and set 'TS' bit respectively | 105 | * Clear and set 'TS' bit respectively |
diff --git a/include/asm-ia64/bug.h b/include/asm-ia64/bug.h index 2c0cd51e8856..3aa0a0a5474b 100644 --- a/include/asm-ia64/bug.h +++ b/include/asm-ia64/bug.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _ASM_IA64_BUG_H | 1 | #ifndef _ASM_IA64_BUG_H |
2 | #define _ASM_IA64_BUG_H | 2 | #define _ASM_IA64_BUG_H |
3 | 3 | ||
4 | #ifdef CONFIG_BUG | ||
4 | #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) | 5 | #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) |
5 | # define ia64_abort() __builtin_trap() | 6 | # define ia64_abort() __builtin_trap() |
6 | #else | 7 | #else |
@@ -8,8 +9,10 @@ | |||
8 | #endif | 9 | #endif |
9 | #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0) | 10 | #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0) |
10 | 11 | ||
11 | /* should this BUG should be made generic? */ | 12 | /* should this BUG be made generic? */ |
12 | #define HAVE_ARCH_BUG | 13 | #define HAVE_ARCH_BUG |
14 | #endif | ||
15 | |||
13 | #include <asm-generic/bug.h> | 16 | #include <asm-generic/bug.h> |
14 | 17 | ||
15 | #endif | 18 | #endif |
diff --git a/include/asm-ia64/siginfo.h b/include/asm-ia64/siginfo.h index d55f139cbcdc..9294e4b0c8bc 100644 --- a/include/asm-ia64/siginfo.h +++ b/include/asm-ia64/siginfo.h | |||
@@ -8,9 +8,7 @@ | |||
8 | * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co | 8 | * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 4) | 11 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
12 | |||
13 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) | ||
14 | 12 | ||
15 | #define HAVE_ARCH_SIGINFO_T | 13 | #define HAVE_ARCH_SIGINFO_T |
16 | #define HAVE_ARCH_COPY_SIGINFO | 14 | #define HAVE_ARCH_COPY_SIGINFO |
diff --git a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h index 660a759744dd..85a577ae9146 100644 --- a/include/asm-ia64/signal.h +++ b/include/asm-ia64/signal.h | |||
@@ -114,16 +114,6 @@ | |||
114 | #define _NSIG_BPW 64 | 114 | #define _NSIG_BPW 64 |
115 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) | 115 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) |
116 | 116 | ||
117 | /* | ||
118 | * These values of sa_flags are used only by the kernel as part of the | ||
119 | * irq handling routines. | ||
120 | * | ||
121 | * SA_INTERRUPT is also used by the irq handling routines. | ||
122 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
123 | */ | ||
124 | #define SA_PROBE SA_ONESHOT | ||
125 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
126 | #define SA_SHIRQ 0x04000000 | ||
127 | #define SA_PERCPU_IRQ 0x02000000 | 117 | #define SA_PERCPU_IRQ 0x02000000 |
128 | 118 | ||
129 | #endif /* __KERNEL__ */ | 119 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-m32r/signal.h b/include/asm-m32r/signal.h index ce46eaea4494..6e55fd421883 100644 --- a/include/asm-m32r/signal.h +++ b/include/asm-m32r/signal.h | |||
@@ -114,20 +114,6 @@ typedef unsigned long sigset_t; | |||
114 | #define MINSIGSTKSZ 2048 | 114 | #define MINSIGSTKSZ 2048 |
115 | #define SIGSTKSZ 8192 | 115 | #define SIGSTKSZ 8192 |
116 | 116 | ||
117 | #ifdef __KERNEL__ | ||
118 | |||
119 | /* | ||
120 | * These values of sa_flags are used only by the kernel as part of the | ||
121 | * irq handling routines. | ||
122 | * | ||
123 | * SA_INTERRUPT is also used by the irq handling routines. | ||
124 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
125 | */ | ||
126 | #define SA_PROBE SA_ONESHOT | ||
127 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
128 | #define SA_SHIRQ 0x04000000 | ||
129 | #endif | ||
130 | |||
131 | #define SIG_BLOCK 0 /* for blocking signals */ | 117 | #define SIG_BLOCK 0 /* for blocking signals */ |
132 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 118 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
133 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 119 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-m68k/bug.h b/include/asm-m68k/bug.h index 3e1d2266fa69..072ce274d537 100644 --- a/include/asm-m68k/bug.h +++ b/include/asm-m68k/bug.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
5 | 5 | ||
6 | #ifdef CONFIG_BUG | ||
6 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 7 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
7 | #ifndef CONFIG_SUN3 | 8 | #ifndef CONFIG_SUN3 |
8 | #define BUG() do { \ | 9 | #define BUG() do { \ |
@@ -22,6 +23,8 @@ | |||
22 | #endif | 23 | #endif |
23 | 24 | ||
24 | #define HAVE_ARCH_BUG | 25 | #define HAVE_ARCH_BUG |
26 | #endif | ||
27 | |||
25 | #include <asm-generic/bug.h> | 28 | #include <asm-generic/bug.h> |
26 | 29 | ||
27 | #endif | 30 | #endif |
diff --git a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h index 6681bb6a5523..1d016e9f19bf 100644 --- a/include/asm-m68k/signal.h +++ b/include/asm-m68k/signal.h | |||
@@ -105,19 +105,6 @@ typedef unsigned long sigset_t; | |||
105 | #define MINSIGSTKSZ 2048 | 105 | #define MINSIGSTKSZ 2048 |
106 | #define SIGSTKSZ 8192 | 106 | #define SIGSTKSZ 8192 |
107 | 107 | ||
108 | #ifdef __KERNEL__ | ||
109 | /* | ||
110 | * These values of sa_flags are used only by the kernel as part of the | ||
111 | * irq handling routines. | ||
112 | * | ||
113 | * SA_INTERRUPT is also used by the irq handling routines. | ||
114 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
115 | */ | ||
116 | #define SA_PROBE SA_ONESHOT | ||
117 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
118 | #define SA_SHIRQ 0x04000000 | ||
119 | #endif | ||
120 | |||
121 | #define SIG_BLOCK 0 /* for blocking signals */ | 108 | #define SIG_BLOCK 0 /* for blocking signals */ |
122 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 109 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
123 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 110 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-m68knommu/MC68328.h b/include/asm-m68knommu/MC68328.h index 4f5a9845f5be..a337e56d09bf 100644 --- a/include/asm-m68knommu/MC68328.h +++ b/include/asm-m68knommu/MC68328.h | |||
@@ -993,7 +993,7 @@ typedef volatile struct { | |||
993 | volatile unsigned short int pad1; | 993 | volatile unsigned short int pad1; |
994 | volatile unsigned short int pad2; | 994 | volatile unsigned short int pad2; |
995 | volatile unsigned short int pad3; | 995 | volatile unsigned short int pad3; |
996 | } m68328_uart __attribute__((packed)); | 996 | } __attribute__((packed)) m68328_uart; |
997 | 997 | ||
998 | 998 | ||
999 | /********** | 999 | /********** |
diff --git a/include/asm-m68knommu/MC68EZ328.h b/include/asm-m68knommu/MC68EZ328.h index 801933da4c70..69b7f9139e5e 100644 --- a/include/asm-m68knommu/MC68EZ328.h +++ b/include/asm-m68knommu/MC68EZ328.h | |||
@@ -815,7 +815,7 @@ typedef volatile struct { | |||
815 | volatile unsigned short int nipr; | 815 | volatile unsigned short int nipr; |
816 | volatile unsigned short int pad1; | 816 | volatile unsigned short int pad1; |
817 | volatile unsigned short int pad2; | 817 | volatile unsigned short int pad2; |
818 | } m68328_uart __attribute__((packed)); | 818 | } __attribute__((packed)) m68328_uart; |
819 | 819 | ||
820 | 820 | ||
821 | /********** | 821 | /********** |
diff --git a/include/asm-m68knommu/MC68VZ328.h b/include/asm-m68knommu/MC68VZ328.h index df74322f37ed..2b9bf626a0a5 100644 --- a/include/asm-m68knommu/MC68VZ328.h +++ b/include/asm-m68knommu/MC68VZ328.h | |||
@@ -909,7 +909,7 @@ typedef struct { | |||
909 | volatile unsigned short int nipr; | 909 | volatile unsigned short int nipr; |
910 | volatile unsigned short int hmark; | 910 | volatile unsigned short int hmark; |
911 | volatile unsigned short int unused; | 911 | volatile unsigned short int unused; |
912 | } m68328_uart __attribute__((packed)); | 912 | } __attribute__((packed)) m68328_uart; |
913 | 913 | ||
914 | 914 | ||
915 | 915 | ||
diff --git a/include/asm-m68knommu/signal.h b/include/asm-m68knommu/signal.h index 486cbb0dc088..37c9c8a024ba 100644 --- a/include/asm-m68knommu/signal.h +++ b/include/asm-m68knommu/signal.h | |||
@@ -105,19 +105,6 @@ typedef unsigned long sigset_t; | |||
105 | #define MINSIGSTKSZ 2048 | 105 | #define MINSIGSTKSZ 2048 |
106 | #define SIGSTKSZ 8192 | 106 | #define SIGSTKSZ 8192 |
107 | 107 | ||
108 | #ifdef __KERNEL__ | ||
109 | /* | ||
110 | * These values of sa_flags are used only by the kernel as part of the | ||
111 | * irq handling routines. | ||
112 | * | ||
113 | * SA_INTERRUPT is also used by the irq handling routines. | ||
114 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
115 | */ | ||
116 | #define SA_PROBE SA_ONESHOT | ||
117 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
118 | #define SA_SHIRQ 0x04000000 | ||
119 | #endif | ||
120 | |||
121 | #define SIG_BLOCK 0 /* for blocking signals */ | 108 | #define SIG_BLOCK 0 /* for blocking signals */ |
122 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 109 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
123 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 110 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h index eb94bb96cfbc..3f594b440abc 100644 --- a/include/asm-mips/bug.h +++ b/include/asm-mips/bug.h | |||
@@ -3,12 +3,14 @@ | |||
3 | 3 | ||
4 | #include <asm/break.h> | 4 | #include <asm/break.h> |
5 | 5 | ||
6 | #ifdef CONFIG_BUG | ||
7 | #define HAVE_ARCH_BUG | ||
6 | #define BUG() \ | 8 | #define BUG() \ |
7 | do { \ | 9 | do { \ |
8 | __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \ | 10 | __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \ |
9 | } while (0) | 11 | } while (0) |
12 | #endif | ||
10 | 13 | ||
11 | #define HAVE_ARCH_BUG | ||
12 | #include <asm-generic/bug.h> | 14 | #include <asm-generic/bug.h> |
13 | 15 | ||
14 | #endif | 16 | #endif |
diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h index 2b458f9538cd..3c0d840e4577 100644 --- a/include/asm-mips/errno.h +++ b/include/asm-mips/errno.h | |||
@@ -115,6 +115,10 @@ | |||
115 | #define EKEYREVOKED 163 /* Key has been revoked */ | 115 | #define EKEYREVOKED 163 /* Key has been revoked */ |
116 | #define EKEYREJECTED 164 /* Key was rejected by service */ | 116 | #define EKEYREJECTED 164 /* Key was rejected by service */ |
117 | 117 | ||
118 | /* for robust mutexes */ | ||
119 | #define EOWNERDEAD 165 /* Owner died */ | ||
120 | #define ENOTRECOVERABLE 166 /* State not recoverable */ | ||
121 | |||
118 | #define EDQUOT 1133 /* Quota exceeded */ | 122 | #define EDQUOT 1133 /* Quota exceeded */ |
119 | 123 | ||
120 | #ifdef __KERNEL__ | 124 | #ifdef __KERNEL__ |
diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h index 8ddd3c99bcf7..a0e26e6c994d 100644 --- a/include/asm-mips/siginfo.h +++ b/include/asm-mips/siginfo.h | |||
@@ -11,8 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | 13 | ||
14 | #define SIGEV_HEAD_SIZE (sizeof(long) + 2*sizeof(int)) | ||
15 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE-SIGEV_HEAD_SIZE) / sizeof(int)) | ||
16 | #undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */ | 14 | #undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */ |
17 | 15 | ||
18 | #define HAVE_ARCH_SIGINFO_T | 16 | #define HAVE_ARCH_SIGINFO_T |
diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index 994987db61be..d81356731eb6 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h | |||
@@ -98,21 +98,6 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ | |||
98 | #define MINSIGSTKSZ 2048 | 98 | #define MINSIGSTKSZ 2048 |
99 | #define SIGSTKSZ 8192 | 99 | #define SIGSTKSZ 8192 |
100 | 100 | ||
101 | #ifdef __KERNEL__ | ||
102 | |||
103 | /* | ||
104 | * These values of sa_flags are used only by the kernel as part of the | ||
105 | * irq handling routines. | ||
106 | * | ||
107 | * SA_INTERRUPT is also used by the irq handling routines. | ||
108 | * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. | ||
109 | */ | ||
110 | #define SA_PROBE SA_ONESHOT | ||
111 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
112 | #define SA_SHIRQ 0x02000000 | ||
113 | |||
114 | #endif /* __KERNEL__ */ | ||
115 | |||
116 | #define SIG_BLOCK 1 /* for blocking signals */ | 101 | #define SIG_BLOCK 1 /* for blocking signals */ |
117 | #define SIG_UNBLOCK 2 /* for unblocking signals */ | 102 | #define SIG_UNBLOCK 2 /* for unblocking signals */ |
118 | #define SIG_SETMASK 3 /* for setting the signal mask */ | 103 | #define SIG_SETMASK 3 /* for setting the signal mask */ |
diff --git a/include/asm-parisc/bug.h b/include/asm-parisc/bug.h index e72f6e2b4b9f..695588da41f8 100644 --- a/include/asm-parisc/bug.h +++ b/include/asm-parisc/bug.h | |||
@@ -1,12 +1,14 @@ | |||
1 | #ifndef _PARISC_BUG_H | 1 | #ifndef _PARISC_BUG_H |
2 | #define _PARISC_BUG_H | 2 | #define _PARISC_BUG_H |
3 | 3 | ||
4 | #ifdef CONFIG_BUG | ||
4 | #define HAVE_ARCH_BUG | 5 | #define HAVE_ARCH_BUG |
5 | #define BUG() do { \ | 6 | #define BUG() do { \ |
6 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | 7 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ |
7 | dump_stack(); \ | 8 | dump_stack(); \ |
8 | panic("BUG!"); \ | 9 | panic("BUG!"); \ |
9 | } while (0) | 10 | } while (0) |
11 | #endif | ||
10 | 12 | ||
11 | #include <asm-generic/bug.h> | 13 | #include <asm-generic/bug.h> |
12 | #endif | 14 | #endif |
diff --git a/include/asm-parisc/errno.h b/include/asm-parisc/errno.h index a10f109770f1..08464c405471 100644 --- a/include/asm-parisc/errno.h +++ b/include/asm-parisc/errno.h | |||
@@ -115,5 +115,9 @@ | |||
115 | #define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */ | 115 | #define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */ |
116 | #define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ | 116 | #define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ |
117 | 117 | ||
118 | /* for robust mutexes */ | ||
119 | #define EOWNERDEAD 254 /* Owner died */ | ||
120 | #define ENOTRECOVERABLE 255 /* State not recoverable */ | ||
121 | |||
118 | 122 | ||
119 | #endif | 123 | #endif |
diff --git a/include/asm-parisc/signal.h b/include/asm-parisc/signal.h index 358f577c8eb8..25cb23ef7dd1 100644 --- a/include/asm-parisc/signal.h +++ b/include/asm-parisc/signal.h | |||
@@ -89,17 +89,6 @@ | |||
89 | #define _NSIG_BPW BITS_PER_LONG | 89 | #define _NSIG_BPW BITS_PER_LONG |
90 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) | 90 | #define _NSIG_WORDS (_NSIG / _NSIG_BPW) |
91 | 91 | ||
92 | /* | ||
93 | * These values of sa_flags are used only by the kernel as part of the | ||
94 | * irq handling routines. | ||
95 | * | ||
96 | * SA_INTERRUPT is also used by the irq handling routines. | ||
97 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
98 | */ | ||
99 | #define SA_PROBE SA_ONESHOT | ||
100 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
101 | #define SA_SHIRQ 0x04000000 | ||
102 | |||
103 | #endif /* __KERNEL__ */ | 92 | #endif /* __KERNEL__ */ |
104 | 93 | ||
105 | #define SIG_BLOCK 0 /* for blocking signals */ | 94 | #define SIG_BLOCK 0 /* for blocking signals */ |
diff --git a/include/asm-parisc/uaccess.h b/include/asm-parisc/uaccess.h index 8a08423b7570..c1b5bdea53ee 100644 --- a/include/asm-parisc/uaccess.h +++ b/include/asm-parisc/uaccess.h | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Note that since kernel addresses are in a separate address space on | 26 | * Note that since kernel addresses are in a separate address space on |
27 | * parisc, we don't need to do anything for access_ok() or verify_area(). | 27 | * parisc, we don't need to do anything for access_ok(). |
28 | * We just let the page fault handler do the right thing. This also means | 28 | * We just let the page fault handler do the right thing. This also means |
29 | * that put_user is the same as __put_user, etc. | 29 | * that put_user is the same as __put_user, etc. |
30 | */ | 30 | */ |
diff --git a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h index e99c6cb9d618..8b34fd682b0d 100644 --- a/include/asm-ppc/bug.h +++ b/include/asm-ppc/bug.h | |||
@@ -14,6 +14,7 @@ struct bug_entry { | |||
14 | */ | 14 | */ |
15 | #define BUG_WARNING_TRAP 0x1000000 | 15 | #define BUG_WARNING_TRAP 0x1000000 |
16 | 16 | ||
17 | #ifdef CONFIG_BUG | ||
17 | #define BUG() do { \ | 18 | #define BUG() do { \ |
18 | __asm__ __volatile__( \ | 19 | __asm__ __volatile__( \ |
19 | "1: twi 31,0,0\n" \ | 20 | "1: twi 31,0,0\n" \ |
@@ -50,6 +51,8 @@ struct bug_entry { | |||
50 | #define HAVE_ARCH_BUG | 51 | #define HAVE_ARCH_BUG |
51 | #define HAVE_ARCH_BUG_ON | 52 | #define HAVE_ARCH_BUG_ON |
52 | #define HAVE_ARCH_WARN_ON | 53 | #define HAVE_ARCH_WARN_ON |
54 | #endif | ||
55 | |||
53 | #include <asm-generic/bug.h> | 56 | #include <asm-generic/bug.h> |
54 | 57 | ||
55 | #endif | 58 | #endif |
diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h index 639b690ce6f7..8beb162873f4 100644 --- a/include/asm-ppc/pmac_feature.h +++ b/include/asm-ppc/pmac_feature.h | |||
@@ -316,6 +316,9 @@ extern void pmac_register_agp_pm(struct pci_dev *bridge, | |||
316 | extern void pmac_suspend_agp_for_card(struct pci_dev *dev); | 316 | extern void pmac_suspend_agp_for_card(struct pci_dev *dev); |
317 | extern void pmac_resume_agp_for_card(struct pci_dev *dev); | 317 | extern void pmac_resume_agp_for_card(struct pci_dev *dev); |
318 | 318 | ||
319 | /* Used by the via-pmu driver for suspend/resume | ||
320 | */ | ||
321 | extern void pmac_tweak_clock_spreading(int enable); | ||
319 | 322 | ||
320 | /* | 323 | /* |
321 | * The part below is for use by macio_asic.c only, do not rely | 324 | * The part below is for use by macio_asic.c only, do not rely |
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h index e70c25f3c339..45c5e6f2b7ab 100644 --- a/include/asm-ppc/reg_booke.h +++ b/include/asm-ppc/reg_booke.h | |||
@@ -305,6 +305,7 @@ do { \ | |||
305 | #define ESR_PIL 0x08000000 /* Program Exception - Illegal */ | 305 | #define ESR_PIL 0x08000000 /* Program Exception - Illegal */ |
306 | #define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ | 306 | #define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ |
307 | #define ESR_PTR 0x02000000 /* Program Exception - Trap */ | 307 | #define ESR_PTR 0x02000000 /* Program Exception - Trap */ |
308 | #define ESR_FP 0x01000000 /* Floating Point Operation */ | ||
308 | #define ESR_DST 0x00800000 /* Storage Exception - Data miss */ | 309 | #define ESR_DST 0x00800000 /* Storage Exception - Data miss */ |
309 | #define ESR_DIZ 0x00400000 /* Storage Exception - Zone fault */ | 310 | #define ESR_DIZ 0x00400000 /* Storage Exception - Zone fault */ |
310 | #define ESR_ST 0x00800000 /* Store Operation */ | 311 | #define ESR_ST 0x00800000 /* Store Operation */ |
diff --git a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h index 8cc8b88d4edd..d890dabd5a69 100644 --- a/include/asm-ppc/signal.h +++ b/include/asm-ppc/signal.h | |||
@@ -99,19 +99,6 @@ typedef struct { | |||
99 | 99 | ||
100 | #define MINSIGSTKSZ 2048 | 100 | #define MINSIGSTKSZ 2048 |
101 | #define SIGSTKSZ 8192 | 101 | #define SIGSTKSZ 8192 |
102 | #ifdef __KERNEL__ | ||
103 | |||
104 | /* | ||
105 | * These values of sa_flags are used only by the kernel as part of the | ||
106 | * irq handling routines. | ||
107 | * | ||
108 | * SA_INTERRUPT is also used by the irq handling routines. | ||
109 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
110 | */ | ||
111 | #define SA_PROBE SA_ONESHOT | ||
112 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
113 | #define SA_SHIRQ 0x04000000 | ||
114 | #endif /* __KERNEL__ */ | ||
115 | 102 | ||
116 | #define SIG_BLOCK 0 /* for blocking signals */ | 103 | #define SIG_BLOCK 0 /* for blocking signals */ |
117 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 104 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
diff --git a/include/asm-ppc64/a.out.h b/include/asm-ppc64/a.out.h index 802338efcb19..3871e252a6f1 100644 --- a/include/asm-ppc64/a.out.h +++ b/include/asm-ppc64/a.out.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef __PPC64_A_OUT_H__ | 1 | #ifndef __PPC64_A_OUT_H__ |
2 | #define __PPC64_A_OUT_H__ | 2 | #define __PPC64_A_OUT_H__ |
3 | 3 | ||
4 | #include <asm/ppcdebug.h> | ||
5 | |||
6 | /* | 4 | /* |
7 | * c 2001 PPC 64 Team, IBM Corp | 5 | * c 2001 PPC 64 Team, IBM Corp |
8 | * | 6 | * |
diff --git a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h index db31dd22233c..169868fa307d 100644 --- a/include/asm-ppc64/bug.h +++ b/include/asm-ppc64/bug.h | |||
@@ -26,6 +26,8 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
26 | */ | 26 | */ |
27 | #define BUG_WARNING_TRAP 0x1000000 | 27 | #define BUG_WARNING_TRAP 0x1000000 |
28 | 28 | ||
29 | #ifdef CONFIG_BUG | ||
30 | |||
29 | #define BUG() do { \ | 31 | #define BUG() do { \ |
30 | __asm__ __volatile__( \ | 32 | __asm__ __volatile__( \ |
31 | "1: twi 31,0,0\n" \ | 33 | "1: twi 31,0,0\n" \ |
@@ -55,11 +57,12 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
55 | "i" (__FILE__), "i" (__FUNCTION__)); \ | 57 | "i" (__FILE__), "i" (__FUNCTION__)); \ |
56 | } while (0) | 58 | } while (0) |
57 | 59 | ||
58 | #endif | ||
59 | |||
60 | #define HAVE_ARCH_BUG | 60 | #define HAVE_ARCH_BUG |
61 | #define HAVE_ARCH_BUG_ON | 61 | #define HAVE_ARCH_BUG_ON |
62 | #define HAVE_ARCH_WARN_ON | 62 | #define HAVE_ARCH_WARN_ON |
63 | #endif | ||
64 | #endif | ||
65 | |||
63 | #include <asm-generic/bug.h> | 66 | #include <asm-generic/bug.h> |
64 | 67 | ||
65 | #endif | 68 | #endif |
diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h index 8457d90244fb..6c42d61bedd1 100644 --- a/include/asm-ppc64/elf.h +++ b/include/asm-ppc64/elf.h | |||
@@ -229,9 +229,13 @@ do { \ | |||
229 | 229 | ||
230 | /* | 230 | /* |
231 | * An executable for which elf_read_implies_exec() returns TRUE will | 231 | * An executable for which elf_read_implies_exec() returns TRUE will |
232 | * have the READ_IMPLIES_EXEC personality flag set automatically. | 232 | * have the READ_IMPLIES_EXEC personality flag set automatically. This |
233 | * is only required to work around bugs in old 32bit toolchains. Since | ||
234 | * the 64bit ABI has never had these issues dont enable the workaround | ||
235 | * even if we have an executable stack. | ||
233 | */ | 236 | */ |
234 | #define elf_read_implies_exec(ex, exec_stk) (exec_stk != EXSTACK_DISABLE_X) | 237 | #define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \ |
238 | (exec_stk != EXSTACK_DISABLE_X) : 0) | ||
235 | 239 | ||
236 | #endif | 240 | #endif |
237 | 241 | ||
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h index 20e0f19324e8..86219574c1a5 100644 --- a/include/asm-ppc64/page.h +++ b/include/asm-ppc64/page.h | |||
@@ -252,10 +252,19 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */ | |||
252 | 252 | ||
253 | /* | 253 | /* |
254 | * This is the default if a program doesn't have a PT_GNU_STACK | 254 | * This is the default if a program doesn't have a PT_GNU_STACK |
255 | * program header entry. | 255 | * program header entry. The PPC64 ELF ABI has a non executable stack |
256 | * stack by default, so in the absense of a PT_GNU_STACK program header | ||
257 | * we turn execute permission off. | ||
256 | */ | 258 | */ |
257 | #define VM_STACK_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ | 259 | #define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ |
258 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 260 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
261 | |||
262 | #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ | ||
263 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | ||
264 | |||
265 | #define VM_STACK_DEFAULT_FLAGS \ | ||
266 | (test_thread_flag(TIF_32BIT) ? \ | ||
267 | VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64) | ||
259 | 268 | ||
260 | #endif /* __KERNEL__ */ | 269 | #endif /* __KERNEL__ */ |
261 | #endif /* _PPC64_PAGE_H */ | 270 | #endif /* _PPC64_PAGE_H */ |
diff --git a/include/asm-ppc64/pgalloc.h b/include/asm-ppc64/pgalloc.h index 16232d740173..4fc4b739b380 100644 --- a/include/asm-ppc64/pgalloc.h +++ b/include/asm-ppc64/pgalloc.h | |||
@@ -27,7 +27,7 @@ pgd_free(pgd_t *pgd) | |||
27 | kmem_cache_free(zero_cache, pgd); | 27 | kmem_cache_free(zero_cache, pgd); |
28 | } | 28 | } |
29 | 29 | ||
30 | #define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) | 30 | #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) |
31 | 31 | ||
32 | static inline pmd_t * | 32 | static inline pmd_t * |
33 | pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | 33 | pmd_alloc_one(struct mm_struct *mm, unsigned long addr) |
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h index a26120517c54..b984e2747e0c 100644 --- a/include/asm-ppc64/pgtable.h +++ b/include/asm-ppc64/pgtable.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef _PPC64_PGTABLE_H | 1 | #ifndef _PPC64_PGTABLE_H |
2 | #define _PPC64_PGTABLE_H | 2 | #define _PPC64_PGTABLE_H |
3 | 3 | ||
4 | #include <asm-generic/4level-fixup.h> | ||
5 | |||
6 | /* | 4 | /* |
7 | * This file contains the functions and defines necessary to modify and use | 5 | * This file contains the functions and defines necessary to modify and use |
8 | * the ppc64 hashed page table. | 6 | * the ppc64 hashed page table. |
@@ -17,6 +15,8 @@ | |||
17 | #include <asm/tlbflush.h> | 15 | #include <asm/tlbflush.h> |
18 | #endif /* __ASSEMBLY__ */ | 16 | #endif /* __ASSEMBLY__ */ |
19 | 17 | ||
18 | #include <asm-generic/pgtable-nopud.h> | ||
19 | |||
20 | /* PMD_SHIFT determines what a second-level page table entry can map */ | 20 | /* PMD_SHIFT determines what a second-level page table entry can map */ |
21 | #define PMD_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) | 21 | #define PMD_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) |
22 | #define PMD_SIZE (1UL << PMD_SHIFT) | 22 | #define PMD_SIZE (1UL << PMD_SHIFT) |
@@ -228,12 +228,13 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm); | |||
228 | #define pmd_page_kernel(pmd) \ | 228 | #define pmd_page_kernel(pmd) \ |
229 | (__bpn_to_ba(pmd_val(pmd) >> PMD_TO_PTEPAGE_SHIFT)) | 229 | (__bpn_to_ba(pmd_val(pmd) >> PMD_TO_PTEPAGE_SHIFT)) |
230 | #define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd)) | 230 | #define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd)) |
231 | #define pgd_set(pgdp, pmdp) (pgd_val(*(pgdp)) = (__ba_to_bpn(pmdp))) | 231 | |
232 | #define pgd_none(pgd) (!pgd_val(pgd)) | 232 | #define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (__ba_to_bpn(pmdp))) |
233 | #define pgd_bad(pgd) ((pgd_val(pgd)) == 0) | 233 | #define pud_none(pud) (!pud_val(pud)) |
234 | #define pgd_present(pgd) (pgd_val(pgd) != 0UL) | 234 | #define pud_bad(pud) ((pud_val(pud)) == 0UL) |
235 | #define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL) | 235 | #define pud_present(pud) (pud_val(pud) != 0UL) |
236 | #define pgd_page(pgd) (__bpn_to_ba(pgd_val(pgd))) | 236 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) |
237 | #define pud_page(pud) (__bpn_to_ba(pud_val(pud))) | ||
237 | 238 | ||
238 | /* | 239 | /* |
239 | * Find an entry in a page-table-directory. We combine the address region | 240 | * Find an entry in a page-table-directory. We combine the address region |
@@ -245,12 +246,13 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm); | |||
245 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) | 246 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) |
246 | 247 | ||
247 | /* Find an entry in the second-level page table.. */ | 248 | /* Find an entry in the second-level page table.. */ |
248 | #define pmd_offset(dir,addr) \ | 249 | #define pmd_offset(pudp,addr) \ |
249 | ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) | 250 | ((pmd_t *) pud_page(*(pudp)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) |
250 | 251 | ||
251 | /* Find an entry in the third-level page table.. */ | 252 | /* Find an entry in the third-level page table.. */ |
252 | #define pte_offset_kernel(dir,addr) \ | 253 | #define pte_offset_kernel(dir,addr) \ |
253 | ((pte_t *) pmd_page_kernel(*(dir)) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) | 254 | ((pte_t *) pmd_page_kernel(*(dir)) \ |
255 | + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) | ||
254 | 256 | ||
255 | #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) | 257 | #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) |
256 | #define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) | 258 | #define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) |
@@ -582,19 +584,22 @@ extern long native_hpte_insert(unsigned long hpte_group, unsigned long va, | |||
582 | static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea) | 584 | static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea) |
583 | { | 585 | { |
584 | pgd_t *pg; | 586 | pgd_t *pg; |
587 | pud_t *pu; | ||
585 | pmd_t *pm; | 588 | pmd_t *pm; |
586 | pte_t *pt = NULL; | 589 | pte_t *pt = NULL; |
587 | pte_t pte; | 590 | pte_t pte; |
588 | 591 | ||
589 | pg = pgdir + pgd_index(ea); | 592 | pg = pgdir + pgd_index(ea); |
590 | if (!pgd_none(*pg)) { | 593 | if (!pgd_none(*pg)) { |
591 | 594 | pu = pud_offset(pg, ea); | |
592 | pm = pmd_offset(pg, ea); | 595 | if (!pud_none(*pu)) { |
593 | if (pmd_present(*pm)) { | 596 | pm = pmd_offset(pu, ea); |
594 | pt = pte_offset_kernel(pm, ea); | 597 | if (pmd_present(*pm)) { |
595 | pte = *pt; | 598 | pt = pte_offset_kernel(pm, ea); |
596 | if (!pte_present(pte)) | 599 | pte = *pt; |
597 | pt = NULL; | 600 | if (!pte_present(pte)) |
601 | pt = NULL; | ||
602 | } | ||
598 | } | 603 | } |
599 | } | 604 | } |
600 | 605 | ||
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h index fe5401adb41b..a2d7bbb4befd 100644 --- a/include/asm-ppc64/signal.h +++ b/include/asm-ppc64/signal.h | |||
@@ -96,19 +96,6 @@ typedef struct { | |||
96 | 96 | ||
97 | #define MINSIGSTKSZ 2048 | 97 | #define MINSIGSTKSZ 2048 |
98 | #define SIGSTKSZ 8192 | 98 | #define SIGSTKSZ 8192 |
99 | #ifdef __KERNEL__ | ||
100 | |||
101 | /* | ||
102 | * These values of sa_flags are used only by the kernel as part of the | ||
103 | * irq handling routines. | ||
104 | * | ||
105 | * SA_INTERRUPT is also used by the irq handling routines. | ||
106 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
107 | */ | ||
108 | #define SA_PROBE SA_ONESHOT | ||
109 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
110 | #define SA_SHIRQ 0x04000000 | ||
111 | #endif | ||
112 | 99 | ||
113 | #define SIG_BLOCK 0 /* for blocking signals */ | 100 | #define SIG_BLOCK 0 /* for blocking signals */ |
114 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 101 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
diff --git a/include/asm-ppc64/spinlock.h b/include/asm-ppc64/spinlock.h index a9b2a1162cf7..acd11564dd75 100644 --- a/include/asm-ppc64/spinlock.h +++ b/include/asm-ppc64/spinlock.h | |||
@@ -110,7 +110,7 @@ static void __inline__ _raw_spin_lock(spinlock_t *lock) | |||
110 | HMT_low(); | 110 | HMT_low(); |
111 | if (SHARED_PROCESSOR) | 111 | if (SHARED_PROCESSOR) |
112 | __spin_yield(lock); | 112 | __spin_yield(lock); |
113 | } while (likely(lock->lock != 0)); | 113 | } while (unlikely(lock->lock != 0)); |
114 | HMT_medium(); | 114 | HMT_medium(); |
115 | } | 115 | } |
116 | } | 116 | } |
@@ -128,7 +128,7 @@ static void __inline__ _raw_spin_lock_flags(spinlock_t *lock, unsigned long flag | |||
128 | HMT_low(); | 128 | HMT_low(); |
129 | if (SHARED_PROCESSOR) | 129 | if (SHARED_PROCESSOR) |
130 | __spin_yield(lock); | 130 | __spin_yield(lock); |
131 | } while (likely(lock->lock != 0)); | 131 | } while (unlikely(lock->lock != 0)); |
132 | HMT_medium(); | 132 | HMT_medium(); |
133 | local_irq_restore(flags_dis); | 133 | local_irq_restore(flags_dis); |
134 | } | 134 | } |
@@ -194,7 +194,7 @@ static void __inline__ _raw_read_lock(rwlock_t *rw) | |||
194 | HMT_low(); | 194 | HMT_low(); |
195 | if (SHARED_PROCESSOR) | 195 | if (SHARED_PROCESSOR) |
196 | __rw_yield(rw); | 196 | __rw_yield(rw); |
197 | } while (likely(rw->lock < 0)); | 197 | } while (unlikely(rw->lock < 0)); |
198 | HMT_medium(); | 198 | HMT_medium(); |
199 | } | 199 | } |
200 | } | 200 | } |
@@ -251,7 +251,7 @@ static void __inline__ _raw_write_lock(rwlock_t *rw) | |||
251 | HMT_low(); | 251 | HMT_low(); |
252 | if (SHARED_PROCESSOR) | 252 | if (SHARED_PROCESSOR) |
253 | __rw_yield(rw); | 253 | __rw_yield(rw); |
254 | } while (likely(rw->lock != 0)); | 254 | } while (unlikely(rw->lock != 0)); |
255 | HMT_medium(); | 255 | HMT_medium(); |
256 | } | 256 | } |
257 | } | 257 | } |
diff --git a/include/asm-s390/bug.h b/include/asm-s390/bug.h index 2b8d6d4dffcf..a2e7430aafa6 100644 --- a/include/asm-s390/bug.h +++ b/include/asm-s390/bug.h | |||
@@ -3,12 +3,15 @@ | |||
3 | 3 | ||
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | 5 | ||
6 | #ifdef CONFIG_BUG | ||
6 | #define BUG() do { \ | 7 | #define BUG() do { \ |
7 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | 8 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ |
8 | __asm__ __volatile__(".long 0"); \ | 9 | __asm__ __volatile__(".long 0"); \ |
9 | } while (0) | 10 | } while (0) |
10 | 11 | ||
11 | #define HAVE_ARCH_BUG | 12 | #define HAVE_ARCH_BUG |
13 | #endif | ||
14 | |||
12 | #include <asm-generic/bug.h> | 15 | #include <asm-generic/bug.h> |
13 | 16 | ||
14 | #endif | 17 | #endif |
diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h index 1bfe2bd630b5..dae1dd4fb937 100644 --- a/include/asm-s390/cmb.h +++ b/include/asm-s390/cmb.h | |||
@@ -52,7 +52,7 @@ struct cmbdata { | |||
52 | #define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) | 52 | #define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) |
53 | 53 | ||
54 | #ifdef __KERNEL__ | 54 | #ifdef __KERNEL__ |
55 | 55 | struct ccw_device; | |
56 | /** | 56 | /** |
57 | * enable_cmf() - switch on the channel measurement for a specific device | 57 | * enable_cmf() - switch on the channel measurement for a specific device |
58 | * @cdev: The ccw device to be enabled | 58 | * @cdev: The ccw device to be enabled |
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h index 28ef2354b1b2..6bbcdea42a86 100644 --- a/include/asm-s390/debug.h +++ b/include/asm-s390/debug.h | |||
@@ -43,7 +43,7 @@ struct __debug_entry{ | |||
43 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ | 43 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ |
44 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ | 44 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ |
45 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ | 45 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ |
46 | #define DEBUG_MAX_PROCF_LEN 16 /* max length for a proc file name */ | 46 | #define DEBUG_MAX_PROCF_LEN 64 /* max length for a proc file name */ |
47 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ | 47 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ |
48 | 48 | ||
49 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ | 49 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ |
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index 614e2a93c703..2be287b9df88 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #define PAGE_SHIFT 12 | 16 | #define PAGE_SHIFT 12 |
17 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | 17 | #define PAGE_SIZE (1UL << PAGE_SHIFT) |
18 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 18 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
19 | #define PAGE_DEFAULT_ACC 0 | ||
20 | #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) | ||
19 | 21 | ||
20 | #ifdef __KERNEL__ | 22 | #ifdef __KERNEL__ |
21 | #ifndef __ASSEMBLY__ | 23 | #ifndef __ASSEMBLY__ |
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 88c272ca48bf..fb46e9090b50 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
@@ -245,7 +245,7 @@ static inline void enabled_wait(void) | |||
245 | psw_t wait_psw; | 245 | psw_t wait_psw; |
246 | 246 | ||
247 | wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | | 247 | wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | |
248 | PSW_MASK_MCHECK | PSW_MASK_WAIT; | 248 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY; |
249 | #ifndef __s390x__ | 249 | #ifndef __s390x__ |
250 | asm volatile ( | 250 | asm volatile ( |
251 | " basr %0,0\n" | 251 | " basr %0,0\n" |
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 1dc80666e97e..4eff8f2e3bf1 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h | |||
@@ -185,6 +185,7 @@ | |||
185 | #include <linux/stddef.h> | 185 | #include <linux/stddef.h> |
186 | #include <linux/types.h> | 186 | #include <linux/types.h> |
187 | #include <asm/setup.h> | 187 | #include <asm/setup.h> |
188 | #include <asm/page.h> | ||
188 | 189 | ||
189 | typedef union | 190 | typedef union |
190 | { | 191 | { |
@@ -235,6 +236,7 @@ typedef struct | |||
235 | #define PSW_ADDR_INSN 0x7FFFFFFFUL | 236 | #define PSW_ADDR_INSN 0x7FFFFFFFUL |
236 | 237 | ||
237 | #define PSW_BASE_BITS 0x00080000UL | 238 | #define PSW_BASE_BITS 0x00080000UL |
239 | #define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 20) | ||
238 | 240 | ||
239 | #define PSW_ASC_PRIMARY 0x00000000UL | 241 | #define PSW_ASC_PRIMARY 0x00000000UL |
240 | #define PSW_ASC_ACCREG 0x00004000UL | 242 | #define PSW_ASC_ACCREG 0x00004000UL |
@@ -260,6 +262,7 @@ typedef struct | |||
260 | 262 | ||
261 | #define PSW_BASE_BITS 0x0000000180000000UL | 263 | #define PSW_BASE_BITS 0x0000000180000000UL |
262 | #define PSW_BASE32_BITS 0x0000000080000000UL | 264 | #define PSW_BASE32_BITS 0x0000000080000000UL |
265 | #define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 52) | ||
263 | 266 | ||
264 | #define PSW_ASC_PRIMARY 0x0000000000000000UL | 267 | #define PSW_ASC_PRIMARY 0x0000000000000000UL |
265 | #define PSW_ASC_ACCREG 0x0000400000000000UL | 268 | #define PSW_ASC_ACCREG 0x0000400000000000UL |
@@ -268,14 +271,15 @@ typedef struct | |||
268 | 271 | ||
269 | #define PSW_USER32_BITS (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ | 272 | #define PSW_USER32_BITS (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ |
270 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ | 273 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ |
271 | PSW_MASK_PSTATE) | 274 | PSW_MASK_PSTATE | PSW_DEFAULT_KEY) |
272 | 275 | ||
273 | #endif /* __s390x__ */ | 276 | #endif /* __s390x__ */ |
274 | 277 | ||
275 | #define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY) | 278 | #define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \ |
279 | PSW_DEFAULT_KEY) | ||
276 | #define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ | 280 | #define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ |
277 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ | 281 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ |
278 | PSW_MASK_PSTATE) | 282 | PSW_MASK_PSTATE | PSW_DEFAULT_KEY) |
279 | 283 | ||
280 | /* This macro merges a NEW PSW mask specified by the user into | 284 | /* This macro merges a NEW PSW mask specified by the user into |
281 | the currently active PSW mask CURRENT, modifying only those | 285 | the currently active PSW mask CURRENT, modifying only those |
@@ -470,6 +474,12 @@ struct user_regs_struct | |||
470 | extern void show_regs(struct pt_regs * regs); | 474 | extern void show_regs(struct pt_regs * regs); |
471 | #endif | 475 | #endif |
472 | 476 | ||
477 | static inline void | ||
478 | psw_set_key(unsigned int key) | ||
479 | { | ||
480 | asm volatile ( "spka 0(%0)" : : "d" (key) ); | ||
481 | } | ||
482 | |||
473 | #endif /* __ASSEMBLY__ */ | 483 | #endif /* __ASSEMBLY__ */ |
474 | 484 | ||
475 | #endif /* _S390_PTRACE_H */ | 485 | #endif /* _S390_PTRACE_H */ |
diff --git a/include/asm-s390/siginfo.h b/include/asm-s390/siginfo.h index 72303537b732..e0ff1ab054be 100644 --- a/include/asm-s390/siginfo.h +++ b/include/asm-s390/siginfo.h | |||
@@ -13,12 +13,6 @@ | |||
13 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 13 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #ifdef CONFIG_ARCH_S390X | ||
17 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) | ||
18 | #else | ||
19 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) | ||
20 | #endif | ||
21 | |||
22 | #include <asm-generic/siginfo.h> | 16 | #include <asm-generic/siginfo.h> |
23 | 17 | ||
24 | #endif | 18 | #endif |
diff --git a/include/asm-s390/signal.h b/include/asm-s390/signal.h index f273cdcd1cf6..bfed83a818cc 100644 --- a/include/asm-s390/signal.h +++ b/include/asm-s390/signal.h | |||
@@ -117,20 +117,6 @@ typedef unsigned long sigset_t; | |||
117 | #define MINSIGSTKSZ 2048 | 117 | #define MINSIGSTKSZ 2048 |
118 | #define SIGSTKSZ 8192 | 118 | #define SIGSTKSZ 8192 |
119 | 119 | ||
120 | #ifdef __KERNEL__ | ||
121 | |||
122 | /* | ||
123 | * These values of sa_flags are used only by the kernel as part of the | ||
124 | * irq handling routines. | ||
125 | * | ||
126 | * SA_INTERRUPT is also used by the irq handling routines. | ||
127 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
128 | */ | ||
129 | #define SA_PROBE SA_ONESHOT | ||
130 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
131 | #define SA_SHIRQ 0x04000000 | ||
132 | #endif | ||
133 | |||
134 | #define SIG_BLOCK 0 /* for blocking signals */ | 120 | #define SIG_BLOCK 0 /* for blocking signals */ |
135 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 121 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
136 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 122 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-sh/bug.h b/include/asm-sh/bug.h index 70172217140f..70508a360cd6 100644 --- a/include/asm-sh/bug.h +++ b/include/asm-sh/bug.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
5 | 5 | ||
6 | #ifdef CONFIG_BUG | ||
6 | /* | 7 | /* |
7 | * Tell the user there is some problem. | 8 | * Tell the user there is some problem. |
8 | */ | 9 | */ |
@@ -12,6 +13,8 @@ | |||
12 | } while (0) | 13 | } while (0) |
13 | 14 | ||
14 | #define HAVE_ARCH_BUG | 15 | #define HAVE_ARCH_BUG |
16 | #endif | ||
17 | |||
15 | #include <asm-generic/bug.h> | 18 | #include <asm-generic/bug.h> |
16 | 19 | ||
17 | #endif | 20 | #endif |
diff --git a/include/asm-sh/checksum.h b/include/asm-sh/checksum.h index 5113c7f8a739..5ebd0f24299e 100644 --- a/include/asm-sh/checksum.h +++ b/include/asm-sh/checksum.h | |||
@@ -42,7 +42,7 @@ asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsi | |||
42 | * passed in an incorrect kernel address to one of these functions. | 42 | * passed in an incorrect kernel address to one of these functions. |
43 | * | 43 | * |
44 | * If you use these functions directly please don't forget the | 44 | * If you use these functions directly please don't forget the |
45 | * verify_area(). | 45 | * access_ok(). |
46 | */ | 46 | */ |
47 | static __inline__ | 47 | static __inline__ |
48 | unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, | 48 | unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, |
diff --git a/include/asm-sh/signal.h b/include/asm-sh/signal.h index 0a7ff717c245..29f1ac1bf4df 100644 --- a/include/asm-sh/signal.h +++ b/include/asm-sh/signal.h | |||
@@ -108,20 +108,6 @@ typedef unsigned long sigset_t; | |||
108 | #define MINSIGSTKSZ 2048 | 108 | #define MINSIGSTKSZ 2048 |
109 | #define SIGSTKSZ 8192 | 109 | #define SIGSTKSZ 8192 |
110 | 110 | ||
111 | #ifdef __KERNEL__ | ||
112 | |||
113 | /* | ||
114 | * These values of sa_flags are used only by the kernel as part of the | ||
115 | * irq handling routines. | ||
116 | * | ||
117 | * SA_INTERRUPT is also used by the irq handling routines. | ||
118 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
119 | */ | ||
120 | #define SA_PROBE SA_ONESHOT | ||
121 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
122 | #define SA_SHIRQ 0x04000000 | ||
123 | #endif | ||
124 | |||
125 | #define SIG_BLOCK 0 /* for blocking signals */ | 111 | #define SIG_BLOCK 0 /* for blocking signals */ |
126 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 112 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
127 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 113 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-sh64/bug.h b/include/asm-sh64/bug.h index 3acd54d59566..5d659ec28e10 100644 --- a/include/asm-sh64/bug.h +++ b/include/asm-sh64/bug.h | |||
@@ -17,10 +17,6 @@ | |||
17 | BUG(); \ | 17 | BUG(); \ |
18 | } while(0) | 18 | } while(0) |
19 | 19 | ||
20 | #define PAGE_BUG(page) do { \ | ||
21 | BUG(); \ | ||
22 | } while (0) | ||
23 | |||
24 | #define WARN_ON(condition) do { \ | 20 | #define WARN_ON(condition) do { \ |
25 | if (unlikely((condition)!=0)) { \ | 21 | if (unlikely((condition)!=0)) { \ |
26 | printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ | 22 | printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ |
diff --git a/include/asm-sh64/checksum.h b/include/asm-sh64/checksum.h index aa3911a99490..fd034e9ae6e3 100644 --- a/include/asm-sh64/checksum.h +++ b/include/asm-sh64/checksum.h | |||
@@ -34,7 +34,7 @@ asmlinkage unsigned int csum_partial(const unsigned char *buff, int len, | |||
34 | * passed in an incorrect kernel address to one of these functions. | 34 | * passed in an incorrect kernel address to one of these functions. |
35 | * | 35 | * |
36 | * If you use these functions directly please don't forget the | 36 | * If you use these functions directly please don't forget the |
37 | * verify_area(). | 37 | * access_ok(). |
38 | */ | 38 | */ |
39 | 39 | ||
40 | 40 | ||
diff --git a/include/asm-sh64/signal.h b/include/asm-sh64/signal.h index 77957e9b92d9..864c94ecc98c 100644 --- a/include/asm-sh64/signal.h +++ b/include/asm-sh64/signal.h | |||
@@ -107,20 +107,6 @@ typedef struct { | |||
107 | #define MINSIGSTKSZ 2048 | 107 | #define MINSIGSTKSZ 2048 |
108 | #define SIGSTKSZ THREAD_SIZE | 108 | #define SIGSTKSZ THREAD_SIZE |
109 | 109 | ||
110 | #ifdef __KERNEL__ | ||
111 | |||
112 | /* | ||
113 | * These values of sa_flags are used only by the kernel as part of the | ||
114 | * irq handling routines. | ||
115 | * | ||
116 | * SA_INTERRUPT is also used by the irq handling routines. | ||
117 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
118 | */ | ||
119 | #define SA_PROBE SA_ONESHOT | ||
120 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
121 | #define SA_SHIRQ 0x04000000 | ||
122 | #endif | ||
123 | |||
124 | #define SIG_BLOCK 0 /* for blocking signals */ | 110 | #define SIG_BLOCK 0 /* for blocking signals */ |
125 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 111 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
126 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 112 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-sparc/bug.h b/include/asm-sparc/bug.h index 0d30a67d87a3..04151208189f 100644 --- a/include/asm-sparc/bug.h +++ b/include/asm-sparc/bug.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _SPARC_BUG_H | 1 | #ifndef _SPARC_BUG_H |
2 | #define _SPARC_BUG_H | 2 | #define _SPARC_BUG_H |
3 | 3 | ||
4 | #ifdef CONFIG_BUG | ||
4 | /* Only use the inline asm until a gcc release that can handle __builtin_trap | 5 | /* Only use the inline asm until a gcc release that can handle __builtin_trap |
5 | * -rob 2003-06-25 | 6 | * -rob 2003-06-25 |
6 | * | 7 | * |
@@ -26,6 +27,8 @@ extern void do_BUG(const char *file, int line); | |||
26 | #endif | 27 | #endif |
27 | 28 | ||
28 | #define HAVE_ARCH_BUG | 29 | #define HAVE_ARCH_BUG |
30 | #endif | ||
31 | |||
29 | #include <asm-generic/bug.h> | 32 | #include <asm-generic/bug.h> |
30 | 33 | ||
31 | #endif | 34 | #endif |
diff --git a/include/asm-sparc/errno.h b/include/asm-sparc/errno.h index 8c01c5f3b06d..ed41c8bac1fa 100644 --- a/include/asm-sparc/errno.h +++ b/include/asm-sparc/errno.h | |||
@@ -107,4 +107,8 @@ | |||
107 | #define EKEYREVOKED 130 /* Key has been revoked */ | 107 | #define EKEYREVOKED 130 /* Key has been revoked */ |
108 | #define EKEYREJECTED 131 /* Key was rejected by service */ | 108 | #define EKEYREJECTED 131 /* Key was rejected by service */ |
109 | 109 | ||
110 | /* for robust mutexes */ | ||
111 | #define EOWNERDEAD 132 /* Owner died */ | ||
112 | #define ENOTRECOVERABLE 133 /* State not recoverable */ | ||
113 | |||
110 | #endif | 114 | #endif |
diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h index d8211cb6e6b4..f792e10e704f 100644 --- a/include/asm-sparc/signal.h +++ b/include/asm-sparc/signal.h | |||
@@ -143,7 +143,6 @@ struct sigstack { | |||
143 | #define SA_ONESHOT _SV_RESET | 143 | #define SA_ONESHOT _SV_RESET |
144 | #define SA_INTERRUPT 0x10u | 144 | #define SA_INTERRUPT 0x10u |
145 | #define SA_NOMASK 0x20u | 145 | #define SA_NOMASK 0x20u |
146 | #define SA_SHIRQ 0x40u | ||
147 | #define SA_NOCLDWAIT 0x100u | 146 | #define SA_NOCLDWAIT 0x100u |
148 | #define SA_SIGINFO 0x200u | 147 | #define SA_SIGINFO 0x200u |
149 | 148 | ||
@@ -162,11 +161,6 @@ struct sigstack { | |||
162 | 161 | ||
163 | #ifdef __KERNEL__ | 162 | #ifdef __KERNEL__ |
164 | /* | 163 | /* |
165 | * These values of sa_flags are used only by the kernel as part of the | ||
166 | * irq handling routines. | ||
167 | * | ||
168 | * SA_INTERRUPT is also used by the irq handling routines. | ||
169 | * | ||
170 | * DJHR | 164 | * DJHR |
171 | * SA_STATIC_ALLOC is used for the SPARC system to indicate that this | 165 | * SA_STATIC_ALLOC is used for the SPARC system to indicate that this |
172 | * interrupt handler's irq structure should be statically allocated | 166 | * interrupt handler's irq structure should be statically allocated |
@@ -177,8 +171,6 @@ struct sigstack { | |||
177 | * statically allocated data.. which is NOT GOOD. | 171 | * statically allocated data.. which is NOT GOOD. |
178 | * | 172 | * |
179 | */ | 173 | */ |
180 | #define SA_PROBE SA_ONESHOT | ||
181 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
182 | #define SA_STATIC_ALLOC 0x80 | 174 | #define SA_STATIC_ALLOC 0x80 |
183 | #endif | 175 | #endif |
184 | 176 | ||
diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index 3f47889883b7..f461144067ee 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #ifndef __ASSEMBLY__ | 19 | #ifndef __ASSEMBLY__ |
20 | 20 | ||
21 | /* Sparc is not segmented, however we need to be able to fool verify_area() | 21 | /* Sparc is not segmented, however we need to be able to fool access_ok() |
22 | * when doing system calls from kernel mode legitimately. | 22 | * when doing system calls from kernel mode legitimately. |
23 | * | 23 | * |
24 | * "For historical reasons, these macros are grossly misnamed." -Linus | 24 | * "For historical reasons, these macros are grossly misnamed." -Linus |
diff --git a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h index 25c5b1dfe378..516bb27f3fc4 100644 --- a/include/asm-sparc64/bug.h +++ b/include/asm-sparc64/bug.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _SPARC64_BUG_H | 1 | #ifndef _SPARC64_BUG_H |
2 | #define _SPARC64_BUG_H | 2 | #define _SPARC64_BUG_H |
3 | 3 | ||
4 | #ifdef CONFIG_BUG | ||
4 | #include <linux/compiler.h> | 5 | #include <linux/compiler.h> |
5 | 6 | ||
6 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 7 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
@@ -14,6 +15,8 @@ extern void do_BUG(const char *file, int line); | |||
14 | #endif | 15 | #endif |
15 | 16 | ||
16 | #define HAVE_ARCH_BUG | 17 | #define HAVE_ARCH_BUG |
18 | #endif | ||
19 | |||
17 | #include <asm-generic/bug.h> | 20 | #include <asm-generic/bug.h> |
18 | 21 | ||
19 | #endif | 22 | #endif |
diff --git a/include/asm-sparc64/errno.h b/include/asm-sparc64/errno.h index cc98a73b55a7..ea3509ee1b0b 100644 --- a/include/asm-sparc64/errno.h +++ b/include/asm-sparc64/errno.h | |||
@@ -107,4 +107,8 @@ | |||
107 | #define EKEYREVOKED 130 /* Key has been revoked */ | 107 | #define EKEYREVOKED 130 /* Key has been revoked */ |
108 | #define EKEYREJECTED 131 /* Key was rejected by service */ | 108 | #define EKEYREJECTED 131 /* Key was rejected by service */ |
109 | 109 | ||
110 | /* for robust mutexes */ | ||
111 | #define EOWNERDEAD 132 /* Owner died */ | ||
112 | #define ENOTRECOVERABLE 133 /* State not recoverable */ | ||
113 | |||
110 | #endif /* !(_SPARC64_ERRNO_H) */ | 114 | #endif /* !(_SPARC64_ERRNO_H) */ |
diff --git a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h index 7160449e7cab..df17e47abc1c 100644 --- a/include/asm-sparc64/siginfo.h +++ b/include/asm-sparc64/siginfo.h | |||
@@ -3,8 +3,6 @@ | |||
3 | 3 | ||
4 | #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) | 4 | #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) |
5 | 5 | ||
6 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) | ||
7 | |||
8 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 6 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
9 | #define __ARCH_SI_TRAPNO | 7 | #define __ARCH_SI_TRAPNO |
10 | #define __ARCH_SI_BAND_T int | 8 | #define __ARCH_SI_BAND_T int |
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h index 6428e366c38c..466d021d7038 100644 --- a/include/asm-sparc64/signal.h +++ b/include/asm-sparc64/signal.h | |||
@@ -145,7 +145,6 @@ struct sigstack { | |||
145 | #define SA_ONESHOT _SV_RESET | 145 | #define SA_ONESHOT _SV_RESET |
146 | #define SA_INTERRUPT 0x10u | 146 | #define SA_INTERRUPT 0x10u |
147 | #define SA_NOMASK 0x20u | 147 | #define SA_NOMASK 0x20u |
148 | #define SA_SHIRQ 0x40u | ||
149 | #define SA_NOCLDWAIT 0x100u | 148 | #define SA_NOCLDWAIT 0x100u |
150 | #define SA_SIGINFO 0x200u | 149 | #define SA_SIGINFO 0x200u |
151 | 150 | ||
@@ -165,11 +164,6 @@ struct sigstack { | |||
165 | 164 | ||
166 | #ifdef __KERNEL__ | 165 | #ifdef __KERNEL__ |
167 | /* | 166 | /* |
168 | * These values of sa_flags are used only by the kernel as part of the | ||
169 | * irq handling routines. | ||
170 | * | ||
171 | * SA_INTERRUPT is also used by the irq handling routines. | ||
172 | * | ||
173 | * DJHR | 167 | * DJHR |
174 | * SA_STATIC_ALLOC is used for the SPARC system to indicate that this | 168 | * SA_STATIC_ALLOC is used for the SPARC system to indicate that this |
175 | * interrupt handler's irq structure should be statically allocated | 169 | * interrupt handler's irq structure should be statically allocated |
@@ -180,8 +174,6 @@ struct sigstack { | |||
180 | * statically allocated data.. which is NOT GOOD. | 174 | * statically allocated data.. which is NOT GOOD. |
181 | * | 175 | * |
182 | */ | 176 | */ |
183 | #define SA_PROBE SA_ONESHOT | ||
184 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
185 | #define SA_STATIC_ALLOC 0x80 | 177 | #define SA_STATIC_ALLOC 0x80 |
186 | #endif | 178 | #endif |
187 | 179 | ||
diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S index a3d6aab0e74d..1010153faaf9 100644 --- a/include/asm-um/common.lds.S +++ b/include/asm-um/common.lds.S | |||
@@ -8,11 +8,6 @@ | |||
8 | _sdata = .; | 8 | _sdata = .; |
9 | PROVIDE (sdata = .); | 9 | PROVIDE (sdata = .); |
10 | 10 | ||
11 | . = ALIGN(16); /* Exception table */ | ||
12 | __start___ex_table = .; | ||
13 | __ex_table : { *(__ex_table) } | ||
14 | __stop___ex_table = .; | ||
15 | |||
16 | RODATA | 11 | RODATA |
17 | 12 | ||
18 | .unprotected : { *(.unprotected) } | 13 | .unprotected : { *(.unprotected) } |
@@ -20,6 +15,10 @@ | |||
20 | PROVIDE (_unprotected_end = .); | 15 | PROVIDE (_unprotected_end = .); |
21 | 16 | ||
22 | . = ALIGN(4096); | 17 | . = ALIGN(4096); |
18 | __start___ex_table = .; | ||
19 | __ex_table : { *(__ex_table) } | ||
20 | __stop___ex_table = .; | ||
21 | |||
23 | __uml_setup_start = .; | 22 | __uml_setup_start = .; |
24 | .uml.setup.init : { *(.uml.setup.init) } | 23 | .uml.setup.init : { *(.uml.setup.init) } |
25 | __uml_setup_end = .; | 24 | __uml_setup_end = .; |
diff --git a/include/asm-um/elf.h b/include/asm-um/elf.h index b3a7258f9971..7908f8fe8231 100644 --- a/include/asm-um/elf.h +++ b/include/asm-um/elf.h | |||
@@ -13,7 +13,7 @@ extern long elf_aux_hwcap; | |||
13 | 13 | ||
14 | #define elf_check_arch(x) (1) | 14 | #define elf_check_arch(x) (1) |
15 | 15 | ||
16 | #ifdef CONFIG_64_BIT | 16 | #ifdef CONFIG_64BIT |
17 | #define ELF_CLASS ELFCLASS64 | 17 | #define ELF_CLASS ELFCLASS64 |
18 | #else | 18 | #else |
19 | #define ELF_CLASS ELFCLASS32 | 19 | #define ELF_CLASS ELFCLASS32 |
diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 3620a08dc9f3..102eb3df1aaf 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h | |||
@@ -27,7 +27,7 @@ struct page; | |||
27 | #define clear_user_page(page, vaddr, pg) clear_page(page) | 27 | #define clear_user_page(page, vaddr, pg) clear_page(page) |
28 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 28 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
29 | 29 | ||
30 | #if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64_BIT) | 30 | #if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT) |
31 | 31 | ||
32 | typedef struct { unsigned long pte_low, pte_high; } pte_t; | 32 | typedef struct { unsigned long pte_low, pte_high; } pte_t; |
33 | typedef struct { unsigned long long pmd; } pmd_t; | 33 | typedef struct { unsigned long long pmd; } pmd_t; |
diff --git a/include/asm-um/pgtable-3level.h b/include/asm-um/pgtable-3level.h index bdbc3f97e20b..d309f3a9e6f6 100644 --- a/include/asm-um/pgtable-3level.h +++ b/include/asm-um/pgtable-3level.h | |||
@@ -145,7 +145,7 @@ static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot) | |||
145 | */ | 145 | */ |
146 | #define PTE_FILE_MAX_BITS 32 | 146 | #define PTE_FILE_MAX_BITS 32 |
147 | 147 | ||
148 | #ifdef CONFIG_64_BIT | 148 | #ifdef CONFIG_64BIT |
149 | 149 | ||
150 | #define pte_to_pgoff(p) ((p).pte >> 32) | 150 | #define pte_to_pgoff(p) ((p).pte >> 32) |
151 | 151 | ||
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h index 038ba6fc88b8..b953b1ad3b02 100644 --- a/include/asm-um/processor-generic.h +++ b/include/asm-um/processor-generic.h | |||
@@ -17,6 +17,10 @@ struct task_struct; | |||
17 | struct mm_struct; | 17 | struct mm_struct; |
18 | 18 | ||
19 | struct thread_struct { | 19 | struct thread_struct { |
20 | /* This flag is set to 1 before calling do_fork (and analyzed in | ||
21 | * copy_thread) to mark that we are begin called from userspace (fork / | ||
22 | * vfork / clone), and reset to 0 after. It is left to 0 when called | ||
23 | * from kernelspace (i.e. kernel_thread() or fork_idle(), as of 2.6.11). */ | ||
20 | int forking; | 24 | int forking; |
21 | int nsyscalls; | 25 | int nsyscalls; |
22 | struct pt_regs regs; | 26 | struct pt_regs regs; |
@@ -89,7 +93,11 @@ extern struct task_struct *alloc_task_struct(void); | |||
89 | extern void release_thread(struct task_struct *); | 93 | extern void release_thread(struct task_struct *); |
90 | extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | 94 | extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); |
91 | extern void dump_thread(struct pt_regs *regs, struct user *u); | 95 | extern void dump_thread(struct pt_regs *regs, struct user *u); |
92 | extern void prepare_to_copy(struct task_struct *tsk); | 96 | |
97 | static inline void prepare_to_copy(struct task_struct *tsk) | ||
98 | { | ||
99 | } | ||
100 | |||
93 | 101 | ||
94 | extern unsigned long thread_saved_pc(struct task_struct *t); | 102 | extern unsigned long thread_saved_pc(struct task_struct *t); |
95 | 103 | ||
diff --git a/include/asm-v850/bug.h b/include/asm-v850/bug.h index c778916bf7f2..b0ed2d35f3e8 100644 --- a/include/asm-v850/bug.h +++ b/include/asm-v850/bug.h | |||
@@ -14,9 +14,12 @@ | |||
14 | #ifndef __V850_BUG_H__ | 14 | #ifndef __V850_BUG_H__ |
15 | #define __V850_BUG_H__ | 15 | #define __V850_BUG_H__ |
16 | 16 | ||
17 | #ifdef CONFIG_BUG | ||
17 | extern void __bug (void) __attribute__ ((noreturn)); | 18 | extern void __bug (void) __attribute__ ((noreturn)); |
18 | #define BUG() __bug() | 19 | #define BUG() __bug() |
19 | #define HAVE_ARCH_BUG | 20 | #define HAVE_ARCH_BUG |
21 | #endif | ||
22 | |||
20 | #include <asm-generic/bug.h> | 23 | #include <asm-generic/bug.h> |
21 | 24 | ||
22 | #endif /* __V850_BUG_H__ */ | 25 | #endif /* __V850_BUG_H__ */ |
diff --git a/include/asm-v850/signal.h b/include/asm-v850/signal.h index 407db875899c..ec3566c875d9 100644 --- a/include/asm-v850/signal.h +++ b/include/asm-v850/signal.h | |||
@@ -110,21 +110,6 @@ typedef unsigned long sigset_t; | |||
110 | #define MINSIGSTKSZ 2048 | 110 | #define MINSIGSTKSZ 2048 |
111 | #define SIGSTKSZ 8192 | 111 | #define SIGSTKSZ 8192 |
112 | 112 | ||
113 | |||
114 | #ifdef __KERNEL__ | ||
115 | /* | ||
116 | * These values of sa_flags are used only by the kernel as part of the | ||
117 | * irq handling routines. | ||
118 | * | ||
119 | * SA_INTERRUPT is also used by the irq handling routines. | ||
120 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
121 | */ | ||
122 | #define SA_PROBE SA_ONESHOT | ||
123 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
124 | #define SA_SHIRQ 0x04000000 | ||
125 | #endif /* __KERNEL__ */ | ||
126 | |||
127 | |||
128 | #define SIG_BLOCK 0 /* for blocking signals */ | 113 | #define SIG_BLOCK 0 /* for blocking signals */ |
129 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 114 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
130 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 115 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h index c025cc3ef789..e4b1017b8b2b 100644 --- a/include/asm-x86_64/apic.h +++ b/include/asm-x86_64/apic.h | |||
@@ -99,7 +99,6 @@ extern void disable_APIC_timer(void); | |||
99 | extern void enable_APIC_timer(void); | 99 | extern void enable_APIC_timer(void); |
100 | extern void clustered_apic_check(void); | 100 | extern void clustered_apic_check(void); |
101 | 101 | ||
102 | extern int check_nmi_watchdog(void); | ||
103 | extern void nmi_watchdog_default(void); | 102 | extern void nmi_watchdog_default(void); |
104 | extern int setup_nmi_watchdog(char *); | 103 | extern int setup_nmi_watchdog(char *); |
105 | 104 | ||
diff --git a/include/asm-x86_64/bootsetup.h b/include/asm-x86_64/bootsetup.h index b570a484dc50..b829f7b534be 100644 --- a/include/asm-x86_64/bootsetup.h +++ b/include/asm-x86_64/bootsetup.h | |||
@@ -2,7 +2,8 @@ | |||
2 | #ifndef _X86_64_BOOTSETUP_H | 2 | #ifndef _X86_64_BOOTSETUP_H |
3 | #define _X86_64_BOOTSETUP_H 1 | 3 | #define _X86_64_BOOTSETUP_H 1 |
4 | 4 | ||
5 | extern char x86_boot_params[2048]; | 5 | #define BOOT_PARAM_SIZE 4096 |
6 | extern char x86_boot_params[BOOT_PARAM_SIZE]; | ||
6 | 7 | ||
7 | /* | 8 | /* |
8 | * This is set up by the setup-routine at boot-time | 9 | * This is set up by the setup-routine at boot-time |
diff --git a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h index 19aed6e78fec..bdbf66eab6ee 100644 --- a/include/asm-x86_64/bug.h +++ b/include/asm-x86_64/bug.h | |||
@@ -15,11 +15,13 @@ struct bug_frame { | |||
15 | unsigned short line; | 15 | unsigned short line; |
16 | } __attribute__((packed)); | 16 | } __attribute__((packed)); |
17 | 17 | ||
18 | #ifdef CONFIG_BUG | ||
18 | #define HAVE_ARCH_BUG | 19 | #define HAVE_ARCH_BUG |
19 | #define BUG() \ | 20 | #define BUG() \ |
20 | asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \ | 21 | asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \ |
21 | "i"(__LINE__), "i" (__stringify(__FILE__))) | 22 | "i"(__LINE__), "i" (__stringify(__FILE__))) |
22 | void out_of_line_bug(void); | 23 | void out_of_line_bug(void); |
23 | #include <asm-generic/bug.h> | 24 | #endif |
24 | 25 | ||
26 | #include <asm-generic/bug.h> | ||
25 | #endif | 27 | #endif |
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index e68ad97a6319..aea308c65709 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h | |||
@@ -7,7 +7,7 @@ | |||
7 | #ifndef __ASM_X8664_CPUFEATURE_H | 7 | #ifndef __ASM_X8664_CPUFEATURE_H |
8 | #define __ASM_X8664_CPUFEATURE_H | 8 | #define __ASM_X8664_CPUFEATURE_H |
9 | 9 | ||
10 | #define NCAPINTS 6 | 10 | #define NCAPINTS 7 /* N 32-bit words worth of info */ |
11 | 11 | ||
12 | /* Intel-defined CPU features, CPUID level 0x00000001, word 0 */ | 12 | /* Intel-defined CPU features, CPUID level 0x00000001, word 0 */ |
13 | #define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ | 13 | #define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ |
@@ -74,9 +74,15 @@ | |||
74 | #define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ | 74 | #define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ |
75 | #define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ | 75 | #define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ |
76 | 76 | ||
77 | /* More extended AMD flags: CPUID level 0x80000001, ecx, word 5 */ | 77 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ |
78 | #define X86_FEATURE_LAHF_LM (5*32+ 0) /* LAHF/SAHF in long mode */ | 78 | #define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ |
79 | #define X86_FEATURE_CMP_LEGACY (5*32+ 1) /* If yes HyperThreading not valid */ | 79 | #define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */ |
80 | #define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */ | ||
81 | #define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ | ||
82 | |||
83 | /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ | ||
84 | #define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ | ||
85 | #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */ | ||
80 | 86 | ||
81 | #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) | 87 | #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) |
82 | #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) | 88 | #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) |
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h index 08f83a4b4f4a..8e94edf0b984 100644 --- a/include/asm-x86_64/e820.h +++ b/include/asm-x86_64/e820.h | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/mmzone.h> | 14 | #include <linux/mmzone.h> |
15 | 15 | ||
16 | #define E820MAP 0x2d0 /* our map */ | 16 | #define E820MAP 0x2d0 /* our map */ |
17 | #define E820MAX 32 /* number of entries in E820MAP */ | 17 | #define E820MAX 128 /* number of entries in E820MAP */ |
18 | #define E820NR 0x1e8 /* # entries in E820MAP */ | 18 | #define E820NR 0x1e8 /* # entries in E820MAP */ |
19 | 19 | ||
20 | #define E820_RAM 1 | 20 | #define E820_RAM 1 |
diff --git a/include/asm-x86_64/siginfo.h b/include/asm-x86_64/siginfo.h index 7bc15985f124..d09a1e6e7246 100644 --- a/include/asm-x86_64/siginfo.h +++ b/include/asm-x86_64/siginfo.h | |||
@@ -3,8 +3,6 @@ | |||
3 | 3 | ||
4 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 4 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
5 | 5 | ||
6 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) | ||
7 | |||
8 | #include <asm-generic/siginfo.h> | 6 | #include <asm-generic/siginfo.h> |
9 | 7 | ||
10 | #endif | 8 | #endif |
diff --git a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h index 643a20d73765..4987ad8082ba 100644 --- a/include/asm-x86_64/signal.h +++ b/include/asm-x86_64/signal.h | |||
@@ -116,20 +116,6 @@ typedef unsigned long sigset_t; | |||
116 | #define MINSIGSTKSZ 2048 | 116 | #define MINSIGSTKSZ 2048 |
117 | #define SIGSTKSZ 8192 | 117 | #define SIGSTKSZ 8192 |
118 | 118 | ||
119 | #ifdef __KERNEL__ | ||
120 | |||
121 | /* | ||
122 | * These values of sa_flags are used only by the kernel as part of the | ||
123 | * irq handling routines. | ||
124 | * | ||
125 | * SA_INTERRUPT is also used by the irq handling routines. | ||
126 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
127 | */ | ||
128 | #define SA_PROBE SA_ONESHOT | ||
129 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
130 | #define SA_SHIRQ 0x04000000 | ||
131 | #endif | ||
132 | |||
133 | #define SIG_BLOCK 0 /* for blocking signals */ | 119 | #define SIG_BLOCK 0 /* for blocking signals */ |
134 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | 120 | #define SIG_UNBLOCK 1 /* for unblocking signals */ |
135 | #define SIG_SETMASK 2 /* for setting the signal mask */ | 121 | #define SIG_SETMASK 2 /* for setting the signal mask */ |
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 3d65d240dc95..3c9af6fd4332 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h | |||
@@ -76,7 +76,7 @@ __SYSCALL(__NR_madvise, sys_madvise) | |||
76 | #define __NR_shmget 29 | 76 | #define __NR_shmget 29 |
77 | __SYSCALL(__NR_shmget, sys_shmget) | 77 | __SYSCALL(__NR_shmget, sys_shmget) |
78 | #define __NR_shmat 30 | 78 | #define __NR_shmat 30 |
79 | __SYSCALL(__NR_shmat, wrap_sys_shmat) | 79 | __SYSCALL(__NR_shmat, sys_shmat) |
80 | #define __NR_shmctl 31 | 80 | #define __NR_shmctl 31 |
81 | __SYSCALL(__NR_shmctl, sys_shmctl) | 81 | __SYSCALL(__NR_shmctl, sys_shmctl) |
82 | 82 | ||
diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h index d1c7b0ec7c22..a1657fb99516 100644 --- a/include/linux/auto_fs4.h +++ b/include/linux/auto_fs4.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #define AUTOFS_MIN_PROTO_VERSION 3 | 23 | #define AUTOFS_MIN_PROTO_VERSION 3 |
24 | #define AUTOFS_MAX_PROTO_VERSION 4 | 24 | #define AUTOFS_MAX_PROTO_VERSION 4 |
25 | 25 | ||
26 | #define AUTOFS_PROTO_SUBVERSION 5 | 26 | #define AUTOFS_PROTO_SUBVERSION 6 |
27 | 27 | ||
28 | /* Mask for expire behaviour */ | 28 | /* Mask for expire behaviour */ |
29 | #define AUTOFS_EXP_IMMEDIATE 1 | 29 | #define AUTOFS_EXP_IMMEDIATE 1 |
diff --git a/include/linux/compiler-gcc2.h b/include/linux/compiler-gcc2.h index 5a359153ffd9..ebed17660c5f 100644 --- a/include/linux/compiler-gcc2.h +++ b/include/linux/compiler-gcc2.h | |||
@@ -22,3 +22,8 @@ | |||
22 | # define __attribute_pure__ __attribute__((pure)) | 22 | # define __attribute_pure__ __attribute__((pure)) |
23 | # define __attribute_const__ __attribute__((__const__)) | 23 | # define __attribute_const__ __attribute__((__const__)) |
24 | #endif | 24 | #endif |
25 | |||
26 | /* GCC 2.95.x/2.96 recognize __va_copy, but not va_copy. Actually later GCC's | ||
27 | * define both va_copy and __va_copy, but the latter may go away, so limit this | ||
28 | * to this header */ | ||
29 | #define va_copy __va_copy | ||
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 487725cf0d0d..d7378215b851 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -90,6 +90,12 @@ extern void __chk_io_ptr(void __iomem *); | |||
90 | # define __deprecated /* unimplemented */ | 90 | # define __deprecated /* unimplemented */ |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #ifdef MODULE | ||
94 | #define __deprecated_for_modules __deprecated | ||
95 | #else | ||
96 | #define __deprecated_for_modules | ||
97 | #endif | ||
98 | |||
93 | #ifndef __must_check | 99 | #ifndef __must_check |
94 | #define __must_check | 100 | #define __must_check |
95 | #endif | 101 | #endif |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 910eca35583d..f21af067d015 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -103,6 +103,7 @@ struct cpufreq_policy { | |||
103 | #define CPUFREQ_PRECHANGE (0) | 103 | #define CPUFREQ_PRECHANGE (0) |
104 | #define CPUFREQ_POSTCHANGE (1) | 104 | #define CPUFREQ_POSTCHANGE (1) |
105 | #define CPUFREQ_RESUMECHANGE (8) | 105 | #define CPUFREQ_RESUMECHANGE (8) |
106 | #define CPUFREQ_SUSPENDCHANGE (9) | ||
106 | 107 | ||
107 | struct cpufreq_freqs { | 108 | struct cpufreq_freqs { |
108 | unsigned int cpu; /* cpu nr */ | 109 | unsigned int cpu; /* cpu nr */ |
@@ -200,6 +201,7 @@ struct cpufreq_driver { | |||
200 | 201 | ||
201 | /* optional */ | 202 | /* optional */ |
202 | int (*exit) (struct cpufreq_policy *policy); | 203 | int (*exit) (struct cpufreq_policy *policy); |
204 | int (*suspend) (struct cpufreq_policy *policy, u32 state); | ||
203 | int (*resume) (struct cpufreq_policy *policy); | 205 | int (*resume) (struct cpufreq_policy *policy); |
204 | struct freq_attr **attr; | 206 | struct freq_attr **attr; |
205 | }; | 207 | }; |
@@ -211,7 +213,8 @@ struct cpufreq_driver { | |||
211 | #define CPUFREQ_CONST_LOOPS 0x02 /* loops_per_jiffy or other kernel | 213 | #define CPUFREQ_CONST_LOOPS 0x02 /* loops_per_jiffy or other kernel |
212 | * "constants" aren't affected by | 214 | * "constants" aren't affected by |
213 | * frequency transitions */ | 215 | * frequency transitions */ |
214 | 216 | #define CPUFREQ_PM_NO_WARN 0x04 /* don't warn on suspend/resume speed | |
217 | * mismatches */ | ||
215 | 218 | ||
216 | int cpufreq_register_driver(struct cpufreq_driver *driver_data); | 219 | int cpufreq_register_driver(struct cpufreq_driver *driver_data); |
217 | int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); | 220 | int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); |
diff --git a/include/linux/edd.h b/include/linux/edd.h index c6e6747a401d..162512b886f7 100644 --- a/include/linux/edd.h +++ b/include/linux/edd.h | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #define EDDNR 0x1e9 /* addr of number of edd_info structs at EDDBUF | 33 | #define EDDNR 0x1e9 /* addr of number of edd_info structs at EDDBUF |
34 | in boot_params - treat this as 1 byte */ | 34 | in boot_params - treat this as 1 byte */ |
35 | #define EDDBUF 0x600 /* addr of edd_info structs in boot_params */ | 35 | #define EDDBUF 0xd00 /* addr of edd_info structs in boot_params */ |
36 | #define EDDMAXNR 6 /* number of edd_info structs starting at EDDBUF */ | 36 | #define EDDMAXNR 6 /* number of edd_info structs starting at EDDBUF */ |
37 | #define EDDEXTSIZE 8 /* change these if you muck with the structures */ | 37 | #define EDDEXTSIZE 8 /* change these if you muck with the structures */ |
38 | #define EDDPARMSIZE 74 | 38 | #define EDDPARMSIZE 74 |
diff --git a/include/linux/fb.h b/include/linux/fb.h index b45d3e2d711a..b468bf496547 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -563,6 +563,9 @@ struct fb_ops { | |||
563 | int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, | 563 | int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, |
564 | unsigned blue, unsigned transp, struct fb_info *info); | 564 | unsigned blue, unsigned transp, struct fb_info *info); |
565 | 565 | ||
566 | /* set color registers in batch */ | ||
567 | int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info); | ||
568 | |||
566 | /* blank display */ | 569 | /* blank display */ |
567 | int (*fb_blank)(int blank, struct fb_info *info); | 570 | int (*fb_blank)(int blank, struct fb_info *info); |
568 | 571 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 5df687d940fa..4edba067a717 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1053,83 +1053,87 @@ static inline void file_accessed(struct file *file) | |||
1053 | int sync_inode(struct inode *inode, struct writeback_control *wbc); | 1053 | int sync_inode(struct inode *inode, struct writeback_control *wbc); |
1054 | 1054 | ||
1055 | /** | 1055 | /** |
1056 | * &export_operations - for nfsd to communicate with file systems | 1056 | * struct export_operations - for nfsd to communicate with file systems |
1057 | * decode_fh: decode a file handle fragment and return a &struct dentry | 1057 | * @decode_fh: decode a file handle fragment and return a &struct dentry |
1058 | * encode_fh: encode a file handle fragment from a dentry | 1058 | * @encode_fh: encode a file handle fragment from a dentry |
1059 | * get_name: find the name for a given inode in a given directory | 1059 | * @get_name: find the name for a given inode in a given directory |
1060 | * get_parent: find the parent of a given directory | 1060 | * @get_parent: find the parent of a given directory |
1061 | * get_dentry: find a dentry for the inode given a file handle sub-fragment | 1061 | * @get_dentry: find a dentry for the inode given a file handle sub-fragment |
1062 | * | 1062 | * |
1063 | * Description: | 1063 | * Description: |
1064 | * The export_operations structure provides a means for nfsd to communicate | 1064 | * The export_operations structure provides a means for nfsd to communicate |
1065 | * with a particular exported file system - particularly enabling nfsd and | 1065 | * with a particular exported file system - particularly enabling nfsd and |
1066 | * the filesystem to co-operate when dealing with file handles. | 1066 | * the filesystem to co-operate when dealing with file handles. |
1067 | * | 1067 | * |
1068 | * export_operations contains two basic operation for dealing with file handles, | 1068 | * export_operations contains two basic operation for dealing with file |
1069 | * decode_fh() and encode_fh(), and allows for some other operations to be defined | 1069 | * handles, decode_fh() and encode_fh(), and allows for some other |
1070 | * which standard helper routines use to get specific information from the | 1070 | * operations to be defined which standard helper routines use to get |
1071 | * filesystem. | 1071 | * specific information from the filesystem. |
1072 | * | 1072 | * |
1073 | * nfsd encodes information use to determine which filesystem a filehandle | 1073 | * nfsd encodes information use to determine which filesystem a filehandle |
1074 | * applies to in the initial part of the file handle. The remainder, termed a | 1074 | * applies to in the initial part of the file handle. The remainder, termed |
1075 | * file handle fragment, is controlled completely by the filesystem. | 1075 | * a file handle fragment, is controlled completely by the filesystem. The |
1076 | * The standard helper routines assume that this fragment will contain one or two | 1076 | * standard helper routines assume that this fragment will contain one or |
1077 | * sub-fragments, one which identifies the file, and one which may be used to | 1077 | * two sub-fragments, one which identifies the file, and one which may be |
1078 | * identify the (a) directory containing the file. | 1078 | * used to identify the (a) directory containing the file. |
1079 | * | 1079 | * |
1080 | * In some situations, nfsd needs to get a dentry which is connected into a | 1080 | * In some situations, nfsd needs to get a dentry which is connected into a |
1081 | * specific part of the file tree. To allow for this, it passes the function | 1081 | * specific part of the file tree. To allow for this, it passes the |
1082 | * acceptable() together with a @context which can be used to see if the dentry | 1082 | * function acceptable() together with a @context which can be used to see |
1083 | * is acceptable. As there can be multiple dentrys for a given file, the filesystem | 1083 | * if the dentry is acceptable. As there can be multiple dentrys for a |
1084 | * should check each one for acceptability before looking for the next. As soon | 1084 | * given file, the filesystem should check each one for acceptability before |
1085 | * as an acceptable one is found, it should be returned. | 1085 | * looking for the next. As soon as an acceptable one is found, it should |
1086 | * be returned. | ||
1086 | * | 1087 | * |
1087 | * decode_fh: | 1088 | * decode_fh: |
1088 | * @decode_fh is given a &struct super_block (@sb), a file handle fragment (@fh, @fh_len) | 1089 | * @decode_fh is given a &struct super_block (@sb), a file handle fragment |
1089 | * and an acceptability testing function (@acceptable, @context). It should return | 1090 | * (@fh, @fh_len) and an acceptability testing function (@acceptable, |
1090 | * a &struct dentry which refers to the same file that the file handle fragment refers | 1091 | * @context). It should return a &struct dentry which refers to the same |
1091 | * to, and which passes the acceptability test. If it cannot, it should return | 1092 | * file that the file handle fragment refers to, and which passes the |
1092 | * a %NULL pointer if the file was found but no acceptable &dentries were available, or | 1093 | * acceptability test. If it cannot, it should return a %NULL pointer if |
1093 | * a %ERR_PTR error code indicating why it couldn't be found (e.g. %ENOENT or %ENOMEM). | 1094 | * the file was found but no acceptable &dentries were available, or a |
1095 | * %ERR_PTR error code indicating why it couldn't be found (e.g. %ENOENT or | ||
1096 | * %ENOMEM). | ||
1094 | * | 1097 | * |
1095 | * encode_fh: | 1098 | * encode_fh: |
1096 | * @encode_fh should store in the file handle fragment @fh (using at most @max_len bytes) | 1099 | * @encode_fh should store in the file handle fragment @fh (using at most |
1097 | * information that can be used by @decode_fh to recover the file refered to by the | 1100 | * @max_len bytes) information that can be used by @decode_fh to recover the |
1098 | * &struct dentry @de. If the @connectable flag is set, the encode_fh() should store | 1101 | * file refered to by the &struct dentry @de. If the @connectable flag is |
1099 | * sufficient information so that a good attempt can be made to find not only | 1102 | * set, the encode_fh() should store sufficient information so that a good |
1100 | * the file but also it's place in the filesystem. This typically means storing | 1103 | * attempt can be made to find not only the file but also it's place in the |
1101 | * a reference to de->d_parent in the filehandle fragment. | 1104 | * filesystem. This typically means storing a reference to de->d_parent in |
1102 | * encode_fh() should return the number of bytes stored or a negative error code | 1105 | * the filehandle fragment. encode_fh() should return the number of bytes |
1103 | * such as %-ENOSPC | 1106 | * stored or a negative error code such as %-ENOSPC |
1104 | * | 1107 | * |
1105 | * get_name: | 1108 | * get_name: |
1106 | * @get_name should find a name for the given @child in the given @parent directory. | 1109 | * @get_name should find a name for the given @child in the given @parent |
1107 | * The name should be stored in the @name (with the understanding that it is already | 1110 | * directory. The name should be stored in the @name (with the |
1108 | * pointing to a a %NAME_MAX+1 sized buffer. get_name() should return %0 on success, | 1111 | * understanding that it is already pointing to a a %NAME_MAX+1 sized |
1109 | * a negative error code or error. | 1112 | * buffer. get_name() should return %0 on success, a negative error code |
1110 | * @get_name will be called without @parent->i_sem held. | 1113 | * or error. @get_name will be called without @parent->i_sem held. |
1111 | * | 1114 | * |
1112 | * get_parent: | 1115 | * get_parent: |
1113 | * @get_parent should find the parent directory for the given @child which is also | 1116 | * @get_parent should find the parent directory for the given @child which |
1114 | * a directory. In the event that it cannot be found, or storage space cannot be | 1117 | * is also a directory. In the event that it cannot be found, or storage |
1115 | * allocated, a %ERR_PTR should be returned. | 1118 | * space cannot be allocated, a %ERR_PTR should be returned. |
1116 | * | 1119 | * |
1117 | * get_dentry: | 1120 | * get_dentry: |
1118 | * Given a &super_block (@sb) and a pointer to a file-system specific inode identifier, | 1121 | * Given a &super_block (@sb) and a pointer to a file-system specific inode |
1119 | * possibly an inode number, (@inump) get_dentry() should find the identified inode and | 1122 | * identifier, possibly an inode number, (@inump) get_dentry() should find |
1120 | * return a dentry for that inode. | 1123 | * the identified inode and return a dentry for that inode. Any suitable |
1121 | * Any suitable dentry can be returned including, if necessary, a new dentry created | 1124 | * dentry can be returned including, if necessary, a new dentry created with |
1122 | * with d_alloc_root. The caller can then find any other extant dentrys by following the | 1125 | * d_alloc_root. The caller can then find any other extant dentrys by |
1123 | * d_alias links. If a new dentry was created using d_alloc_root, DCACHE_NFSD_DISCONNECTED | 1126 | * following the d_alias links. If a new dentry was created using |
1124 | * should be set, and the dentry should be d_rehash()ed. | 1127 | * d_alloc_root, DCACHE_NFSD_DISCONNECTED should be set, and the dentry |
1128 | * should be d_rehash()ed. | ||
1125 | * | 1129 | * |
1126 | * If the inode cannot be found, either a %NULL pointer or an %ERR_PTR code can be returned. | 1130 | * If the inode cannot be found, either a %NULL pointer or an %ERR_PTR code |
1127 | * The @inump will be whatever was passed to nfsd_find_fh_dentry() in either the | 1131 | * can be returned. The @inump will be whatever was passed to |
1128 | * @obj or @parent parameters. | 1132 | * nfsd_find_fh_dentry() in either the @obj or @parent parameters. |
1129 | * | 1133 | * |
1130 | * Locking rules: | 1134 | * Locking rules: |
1131 | * get_parent is called with child->d_inode->i_sem down | 1135 | * get_parent is called with child->d_inode->i_sem down |
1132 | * get_name is not (which is possibly inconsistent) | 1136 | * get_name is not (which is possibly inconsistent) |
1133 | */ | 1137 | */ |
1134 | 1138 | ||
1135 | struct export_operations { | 1139 | struct export_operations { |
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 848a1baac079..af7407e8cfc5 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -38,14 +38,16 @@ struct vm_area_struct; | |||
38 | #define __GFP_NO_GROW 0x2000u /* Slab internal usage */ | 38 | #define __GFP_NO_GROW 0x2000u /* Slab internal usage */ |
39 | #define __GFP_COMP 0x4000u /* Add compound page metadata */ | 39 | #define __GFP_COMP 0x4000u /* Add compound page metadata */ |
40 | #define __GFP_ZERO 0x8000u /* Return zeroed page on success */ | 40 | #define __GFP_ZERO 0x8000u /* Return zeroed page on success */ |
41 | #define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */ | ||
41 | 42 | ||
42 | #define __GFP_BITS_SHIFT 16 /* Room for 16 __GFP_FOO bits */ | 43 | #define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */ |
43 | #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1) | 44 | #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1) |
44 | 45 | ||
45 | /* if you forget to add the bitmask here kernel will crash, period */ | 46 | /* if you forget to add the bitmask here kernel will crash, period */ |
46 | #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \ | 47 | #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \ |
47 | __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \ | 48 | __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \ |
48 | __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP) | 49 | __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \ |
50 | __GFP_NOMEMALLOC) | ||
49 | 51 | ||
50 | #define GFP_ATOMIC (__GFP_HIGH) | 52 | #define GFP_ATOMIC (__GFP_HIGH) |
51 | #define GFP_NOIO (__GFP_WAIT) | 53 | #define GFP_NOIO (__GFP_WAIT) |
diff --git a/include/linux/input.h b/include/linux/input.h index b70df8fe60e6..72731d7d189e 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -328,6 +328,11 @@ struct input_absinfo { | |||
328 | #define KEY_BRIGHTNESSUP 225 | 328 | #define KEY_BRIGHTNESSUP 225 |
329 | #define KEY_MEDIA 226 | 329 | #define KEY_MEDIA 226 |
330 | 330 | ||
331 | #define KEY_SWITCHVIDEOMODE 227 | ||
332 | #define KEY_KBDILLUMTOGGLE 228 | ||
333 | #define KEY_KBDILLUMDOWN 229 | ||
334 | #define KEY_KBDILLUMUP 230 | ||
335 | |||
331 | #define KEY_UNKNOWN 240 | 336 | #define KEY_UNKNOWN 240 |
332 | 337 | ||
333 | #define BTN_MISC 0x100 | 338 | #define BTN_MISC 0x100 |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 7c1cba4a5278..e25b97062ce1 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -115,10 +115,19 @@ extern int __kernel_text_address(unsigned long addr); | |||
115 | extern int kernel_text_address(unsigned long addr); | 115 | extern int kernel_text_address(unsigned long addr); |
116 | extern int session_of_pgrp(int pgrp); | 116 | extern int session_of_pgrp(int pgrp); |
117 | 117 | ||
118 | #ifdef CONFIG_PRINTK | ||
118 | asmlinkage int vprintk(const char *fmt, va_list args) | 119 | asmlinkage int vprintk(const char *fmt, va_list args) |
119 | __attribute__ ((format (printf, 1, 0))); | 120 | __attribute__ ((format (printf, 1, 0))); |
120 | asmlinkage int printk(const char * fmt, ...) | 121 | asmlinkage int printk(const char * fmt, ...) |
121 | __attribute__ ((format (printf, 1, 2))); | 122 | __attribute__ ((format (printf, 1, 2))); |
123 | #else | ||
124 | static inline int vprintk(const char *s, va_list args) | ||
125 | __attribute__ ((format (printf, 1, 0))); | ||
126 | static inline int vprintk(const char *s, va_list args) { return 0; } | ||
127 | static inline int printk(const char *s, ...) | ||
128 | __attribute__ ((format (printf, 1, 2))); | ||
129 | static inline int printk(const char *s, ...) { return 0; } | ||
130 | #endif | ||
122 | 131 | ||
123 | unsigned long int_sqrt(unsigned long); | 132 | unsigned long int_sqrt(unsigned long); |
124 | 133 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index c74a74ca401d..8b007ad2d450 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -726,6 +726,7 @@ extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *, | |||
726 | extern struct vm_area_struct *copy_vma(struct vm_area_struct **, | 726 | extern struct vm_area_struct *copy_vma(struct vm_area_struct **, |
727 | unsigned long addr, unsigned long len, pgoff_t pgoff); | 727 | unsigned long addr, unsigned long len, pgoff_t pgoff); |
728 | extern void exit_mmap(struct mm_struct *); | 728 | extern void exit_mmap(struct mm_struct *); |
729 | extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); | ||
729 | 730 | ||
730 | extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); | 731 | extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); |
731 | 732 | ||
diff --git a/include/linux/net.h b/include/linux/net.h index 7823b3482506..e5914c1f0c4d 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -64,19 +64,19 @@ typedef enum { | |||
64 | #define SOCK_PASSCRED 3 | 64 | #define SOCK_PASSCRED 3 |
65 | 65 | ||
66 | #ifndef ARCH_HAS_SOCKET_TYPES | 66 | #ifndef ARCH_HAS_SOCKET_TYPES |
67 | /** sock_type - Socket types | 67 | /** |
68 | * | 68 | * enum sock_type - Socket types |
69 | * @SOCK_STREAM: stream (connection) socket | ||
70 | * @SOCK_DGRAM: datagram (conn.less) socket | ||
71 | * @SOCK_RAW: raw socket | ||
72 | * @SOCK_RDM: reliably-delivered message | ||
73 | * @SOCK_SEQPACKET: sequential packet socket | ||
74 | * @SOCK_PACKET: linux specific way of getting packets at the dev level. | ||
75 | * For writing rarp and other similar things on the user level. | ||
76 | * | ||
69 | * When adding some new socket type please | 77 | * When adding some new socket type please |
70 | * grep ARCH_HAS_SOCKET_TYPE include/asm-* /socket.h, at least MIPS | 78 | * grep ARCH_HAS_SOCKET_TYPE include/asm-* /socket.h, at least MIPS |
71 | * overrides this enum for binary compat reasons. | 79 | * overrides this enum for binary compat reasons. |
72 | * | ||
73 | * @SOCK_STREAM - stream (connection) socket | ||
74 | * @SOCK_DGRAM - datagram (conn.less) socket | ||
75 | * @SOCK_RAW - raw socket | ||
76 | * @SOCK_RDM - reliably-delivered message | ||
77 | * @SOCK_SEQPACKET - sequential packet socket | ||
78 | * @SOCK_PACKET - linux specific way of getting packets at the dev level. | ||
79 | * For writing rarp and other similar things on the user level. | ||
80 | */ | 80 | */ |
81 | enum sock_type { | 81 | enum sock_type { |
82 | SOCK_STREAM = 1, | 82 | SOCK_STREAM = 1, |
@@ -93,15 +93,15 @@ enum sock_type { | |||
93 | 93 | ||
94 | /** | 94 | /** |
95 | * struct socket - general BSD socket | 95 | * struct socket - general BSD socket |
96 | * @state - socket state (%SS_CONNECTED, etc) | 96 | * @state: socket state (%SS_CONNECTED, etc) |
97 | * @flags - socket flags (%SOCK_ASYNC_NOSPACE, etc) | 97 | * @flags: socket flags (%SOCK_ASYNC_NOSPACE, etc) |
98 | * @ops - protocol specific socket operations | 98 | * @ops: protocol specific socket operations |
99 | * @fasync_list - Asynchronous wake up list | 99 | * @fasync_list: Asynchronous wake up list |
100 | * @file - File back pointer for gc | 100 | * @file: File back pointer for gc |
101 | * @sk - internal networking protocol agnostic socket representation | 101 | * @sk: internal networking protocol agnostic socket representation |
102 | * @wait - wait queue for several uses | 102 | * @wait: wait queue for several uses |
103 | * @type - socket type (%SOCK_STREAM, etc) | 103 | * @type: socket type (%SOCK_STREAM, etc) |
104 | * @passcred - credentials (used only in Unix Sockets (aka PF_LOCAL)) | 104 | * @passcred: credentials (used only in Unix Sockets (aka PF_LOCAL)) |
105 | */ | 105 | */ |
106 | struct socket { | 106 | struct socket { |
107 | socket_state state; | 107 | socket_state state; |
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 6b74fcf5bb63..39ab8c6b5652 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -131,6 +131,7 @@ struct page_state { | |||
131 | unsigned long allocstall; /* direct reclaim calls */ | 131 | unsigned long allocstall; /* direct reclaim calls */ |
132 | 132 | ||
133 | unsigned long pgrotated; /* pages rotated to tail of the LRU */ | 133 | unsigned long pgrotated; /* pages rotated to tail of the LRU */ |
134 | unsigned long nr_bounce; /* pages for bounce buffers */ | ||
134 | }; | 135 | }; |
135 | 136 | ||
136 | extern void get_page_state(struct page_state *ret); | 137 | extern void get_page_state(struct page_state *ret); |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6a1897481942..5d5820a4cf10 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2415,6 +2415,8 @@ | |||
2415 | #define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 | 2415 | #define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 |
2416 | #define PCI_DEVICE_ID_INTEL_ICH7_2 0x27c0 | 2416 | #define PCI_DEVICE_ID_INTEL_ICH7_2 0x27c0 |
2417 | #define PCI_DEVICE_ID_INTEL_ICH7_3 0x27c1 | 2417 | #define PCI_DEVICE_ID_INTEL_ICH7_3 0x27c1 |
2418 | #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 | ||
2419 | #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd | ||
2418 | #define PCI_DEVICE_ID_INTEL_ICH7_5 0x27c4 | 2420 | #define PCI_DEVICE_ID_INTEL_ICH7_5 0x27c4 |
2419 | #define PCI_DEVICE_ID_INTEL_ICH7_6 0x27c5 | 2421 | #define PCI_DEVICE_ID_INTEL_ICH7_6 0x27c5 |
2420 | #define PCI_DEVICE_ID_INTEL_ICH7_7 0x27c8 | 2422 | #define PCI_DEVICE_ID_INTEL_ICH7_7 0x27c8 |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 4d747433916b..fd276adf0fd5 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -157,9 +157,9 @@ static inline int rcu_pending(int cpu) | |||
157 | /** | 157 | /** |
158 | * rcu_read_lock - mark the beginning of an RCU read-side critical section. | 158 | * rcu_read_lock - mark the beginning of an RCU read-side critical section. |
159 | * | 159 | * |
160 | * When synchronize_kernel() is invoked on one CPU while other CPUs | 160 | * When synchronize_rcu() is invoked on one CPU while other CPUs |
161 | * are within RCU read-side critical sections, then the | 161 | * are within RCU read-side critical sections, then the |
162 | * synchronize_kernel() is guaranteed to block until after all the other | 162 | * synchronize_rcu() is guaranteed to block until after all the other |
163 | * CPUs exit their critical sections. Similarly, if call_rcu() is invoked | 163 | * CPUs exit their critical sections. Similarly, if call_rcu() is invoked |
164 | * on one CPU while other CPUs are within RCU read-side critical | 164 | * on one CPU while other CPUs are within RCU read-side critical |
165 | * sections, invocation of the corresponding RCU callback is deferred | 165 | * sections, invocation of the corresponding RCU callback is deferred |
@@ -256,6 +256,21 @@ static inline int rcu_pending(int cpu) | |||
256 | (p) = (v); \ | 256 | (p) = (v); \ |
257 | }) | 257 | }) |
258 | 258 | ||
259 | /** | ||
260 | * synchronize_sched - block until all CPUs have exited any non-preemptive | ||
261 | * kernel code sequences. | ||
262 | * | ||
263 | * This means that all preempt_disable code sequences, including NMI and | ||
264 | * hardware-interrupt handlers, in progress on entry will have completed | ||
265 | * before this primitive returns. However, this does not guarantee that | ||
266 | * softirq handlers will have completed, since in some kernels | ||
267 | * | ||
268 | * This primitive provides the guarantees made by the (deprecated) | ||
269 | * synchronize_kernel() API. In contrast, synchronize_rcu() only | ||
270 | * guarantees that rcu_read_lock() sections will have completed. | ||
271 | */ | ||
272 | #define synchronize_sched() synchronize_rcu() | ||
273 | |||
259 | extern void rcu_init(void); | 274 | extern void rcu_init(void); |
260 | extern void rcu_check_callbacks(int cpu, int user); | 275 | extern void rcu_check_callbacks(int cpu, int user); |
261 | extern void rcu_restart_cpu(int cpu); | 276 | extern void rcu_restart_cpu(int cpu); |
@@ -265,7 +280,9 @@ extern void FASTCALL(call_rcu(struct rcu_head *head, | |||
265 | void (*func)(struct rcu_head *head))); | 280 | void (*func)(struct rcu_head *head))); |
266 | extern void FASTCALL(call_rcu_bh(struct rcu_head *head, | 281 | extern void FASTCALL(call_rcu_bh(struct rcu_head *head, |
267 | void (*func)(struct rcu_head *head))); | 282 | void (*func)(struct rcu_head *head))); |
268 | extern void synchronize_kernel(void); | 283 | extern __deprecated_for_modules void synchronize_kernel(void); |
284 | extern void synchronize_rcu(void); | ||
285 | void synchronize_idle(void); | ||
269 | 286 | ||
270 | #endif /* __KERNEL__ */ | 287 | #endif /* __KERNEL__ */ |
271 | #endif /* __LINUX_RCUPDATE_H */ | 288 | #endif /* __LINUX_RCUPDATE_H */ |
diff --git a/include/linux/reboot_fixups.h b/include/linux/reboot_fixups.h new file mode 100644 index 000000000000..480ea2d489d8 --- /dev/null +++ b/include/linux/reboot_fixups.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef _LINUX_REBOOT_FIXUPS_H | ||
2 | #define _LINUX_REBOOT_FIXUPS_H | ||
3 | |||
4 | #ifdef CONFIG_X86_REBOOTFIXUPS | ||
5 | extern void mach_reboot_fixups(void); | ||
6 | #else | ||
7 | #define mach_reboot_fixups() ((void)(0)) | ||
8 | #endif | ||
9 | |||
10 | #endif /* _LINUX_REBOOT_FIXUPS_H */ | ||
diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index a57e973af0bd..2aef9c3f5ce8 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h | |||
@@ -5,18 +5,18 @@ | |||
5 | #define REISERFS_ACL_VERSION 0x0001 | 5 | #define REISERFS_ACL_VERSION 0x0001 |
6 | 6 | ||
7 | typedef struct { | 7 | typedef struct { |
8 | __u16 e_tag; | 8 | __le16 e_tag; |
9 | __u16 e_perm; | 9 | __le16 e_perm; |
10 | __u32 e_id; | 10 | __le32 e_id; |
11 | } reiserfs_acl_entry; | 11 | } reiserfs_acl_entry; |
12 | 12 | ||
13 | typedef struct { | 13 | typedef struct { |
14 | __u16 e_tag; | 14 | __le16 e_tag; |
15 | __u16 e_perm; | 15 | __le16 e_perm; |
16 | } reiserfs_acl_entry_short; | 16 | } reiserfs_acl_entry_short; |
17 | 17 | ||
18 | typedef struct { | 18 | typedef struct { |
19 | __u32 a_version; | 19 | __le32 a_version; |
20 | } reiserfs_acl_header; | 20 | } reiserfs_acl_header; |
21 | 21 | ||
22 | static inline size_t reiserfs_acl_size(int count) | 22 | static inline size_t reiserfs_acl_size(int count) |
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index bccff8b17dc4..32148625fc2f 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h | |||
@@ -114,47 +114,47 @@ if( !( cond ) ) \ | |||
114 | 114 | ||
115 | 115 | ||
116 | struct journal_params { | 116 | struct journal_params { |
117 | __u32 jp_journal_1st_block; /* where does journal start from on its | 117 | __le32 jp_journal_1st_block; /* where does journal start from on its |
118 | * device */ | 118 | * device */ |
119 | __u32 jp_journal_dev; /* journal device st_rdev */ | 119 | __le32 jp_journal_dev; /* journal device st_rdev */ |
120 | __u32 jp_journal_size; /* size of the journal */ | 120 | __le32 jp_journal_size; /* size of the journal */ |
121 | __u32 jp_journal_trans_max; /* max number of blocks in a transaction. */ | 121 | __le32 jp_journal_trans_max; /* max number of blocks in a transaction. */ |
122 | __u32 jp_journal_magic; /* random value made on fs creation (this | 122 | __le32 jp_journal_magic; /* random value made on fs creation (this |
123 | * was sb_journal_block_count) */ | 123 | * was sb_journal_block_count) */ |
124 | __u32 jp_journal_max_batch; /* max number of blocks to batch into a | 124 | __le32 jp_journal_max_batch; /* max number of blocks to batch into a |
125 | * trans */ | 125 | * trans */ |
126 | __u32 jp_journal_max_commit_age; /* in seconds, how old can an async | 126 | __le32 jp_journal_max_commit_age; /* in seconds, how old can an async |
127 | * commit be */ | 127 | * commit be */ |
128 | __u32 jp_journal_max_trans_age; /* in seconds, how old can a transaction | 128 | __le32 jp_journal_max_trans_age; /* in seconds, how old can a transaction |
129 | * be */ | 129 | * be */ |
130 | }; | 130 | }; |
131 | 131 | ||
132 | /* this is the super from 3.5.X, where X >= 10 */ | 132 | /* this is the super from 3.5.X, where X >= 10 */ |
133 | struct reiserfs_super_block_v1 | 133 | struct reiserfs_super_block_v1 |
134 | { | 134 | { |
135 | __u32 s_block_count; /* blocks count */ | 135 | __le32 s_block_count; /* blocks count */ |
136 | __u32 s_free_blocks; /* free blocks count */ | 136 | __le32 s_free_blocks; /* free blocks count */ |
137 | __u32 s_root_block; /* root block number */ | 137 | __le32 s_root_block; /* root block number */ |
138 | struct journal_params s_journal; | 138 | struct journal_params s_journal; |
139 | __u16 s_blocksize; /* block size */ | 139 | __le16 s_blocksize; /* block size */ |
140 | __u16 s_oid_maxsize; /* max size of object id array, see | 140 | __le16 s_oid_maxsize; /* max size of object id array, see |
141 | * get_objectid() commentary */ | 141 | * get_objectid() commentary */ |
142 | __u16 s_oid_cursize; /* current size of object id array */ | 142 | __le16 s_oid_cursize; /* current size of object id array */ |
143 | __u16 s_umount_state; /* this is set to 1 when filesystem was | 143 | __le16 s_umount_state; /* this is set to 1 when filesystem was |
144 | * umounted, to 2 - when not */ | 144 | * umounted, to 2 - when not */ |
145 | char s_magic[10]; /* reiserfs magic string indicates that | 145 | char s_magic[10]; /* reiserfs magic string indicates that |
146 | * file system is reiserfs: | 146 | * file system is reiserfs: |
147 | * "ReIsErFs" or "ReIsEr2Fs" or "ReIsEr3Fs" */ | 147 | * "ReIsErFs" or "ReIsEr2Fs" or "ReIsEr3Fs" */ |
148 | __u16 s_fs_state; /* it is set to used by fsck to mark which | 148 | __le16 s_fs_state; /* it is set to used by fsck to mark which |
149 | * phase of rebuilding is done */ | 149 | * phase of rebuilding is done */ |
150 | __u32 s_hash_function_code; /* indicate, what hash function is being use | 150 | __le32 s_hash_function_code; /* indicate, what hash function is being use |
151 | * to sort names in a directory*/ | 151 | * to sort names in a directory*/ |
152 | __u16 s_tree_height; /* height of disk tree */ | 152 | __le16 s_tree_height; /* height of disk tree */ |
153 | __u16 s_bmap_nr; /* amount of bitmap blocks needed to address | 153 | __le16 s_bmap_nr; /* amount of bitmap blocks needed to address |
154 | * each block of file system */ | 154 | * each block of file system */ |
155 | __u16 s_version; /* this field is only reliable on filesystem | 155 | __le16 s_version; /* this field is only reliable on filesystem |
156 | * with non-standard journal */ | 156 | * with non-standard journal */ |
157 | __u16 s_reserved_for_journal; /* size in blocks of journal area on main | 157 | __le16 s_reserved_for_journal; /* size in blocks of journal area on main |
158 | * device, we need to keep after | 158 | * device, we need to keep after |
159 | * making fs with non-standard journal */ | 159 | * making fs with non-standard journal */ |
160 | } __attribute__ ((__packed__)); | 160 | } __attribute__ ((__packed__)); |
@@ -165,8 +165,8 @@ struct reiserfs_super_block_v1 | |||
165 | struct reiserfs_super_block | 165 | struct reiserfs_super_block |
166 | { | 166 | { |
167 | struct reiserfs_super_block_v1 s_v1; | 167 | struct reiserfs_super_block_v1 s_v1; |
168 | __u32 s_inode_generation; | 168 | __le32 s_inode_generation; |
169 | __u32 s_flags; /* Right now used only by inode-attributes, if enabled */ | 169 | __le32 s_flags; /* Right now used only by inode-attributes, if enabled */ |
170 | unsigned char s_uuid[16]; /* filesystem unique identifier */ | 170 | unsigned char s_uuid[16]; /* filesystem unique identifier */ |
171 | unsigned char s_label[16]; /* filesystem volume label */ | 171 | unsigned char s_label[16]; /* filesystem volume label */ |
172 | char s_unused[88] ; /* zero filled by mkreiserfs and | 172 | char s_unused[88] ; /* zero filled by mkreiserfs and |
@@ -225,7 +225,7 @@ struct reiserfs_super_block | |||
225 | #define SB_ONDISK_JOURNAL_DEVICE(s) \ | 225 | #define SB_ONDISK_JOURNAL_DEVICE(s) \ |
226 | le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_dev)) | 226 | le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_dev)) |
227 | #define SB_ONDISK_RESERVED_FOR_JOURNAL(s) \ | 227 | #define SB_ONDISK_RESERVED_FOR_JOURNAL(s) \ |
228 | le32_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_reserved_for_journal)) | 228 | le16_to_cpu ((SB_V1_DISK_SUPER_BLOCK(s)->s_reserved_for_journal)) |
229 | 229 | ||
230 | #define is_block_in_log_or_reserved_area(s, block) \ | 230 | #define is_block_in_log_or_reserved_area(s, block) \ |
231 | block >= SB_JOURNAL_1st_RESERVED_BLOCK(s) \ | 231 | block >= SB_JOURNAL_1st_RESERVED_BLOCK(s) \ |
@@ -269,7 +269,7 @@ int is_reiserfs_jr (struct reiserfs_super_block * rs); | |||
269 | #define QUOTA_EXCEEDED -6 | 269 | #define QUOTA_EXCEEDED -6 |
270 | 270 | ||
271 | typedef __u32 b_blocknr_t; | 271 | typedef __u32 b_blocknr_t; |
272 | typedef __u32 unp_t; | 272 | typedef __le32 unp_t; |
273 | 273 | ||
274 | struct unfm_nodeinfo { | 274 | struct unfm_nodeinfo { |
275 | unp_t unfm_nodenum; | 275 | unp_t unfm_nodenum; |
@@ -376,78 +376,57 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb) | |||
376 | // directories use this key as well as old files | 376 | // directories use this key as well as old files |
377 | // | 377 | // |
378 | struct offset_v1 { | 378 | struct offset_v1 { |
379 | __u32 k_offset; | 379 | __le32 k_offset; |
380 | __u32 k_uniqueness; | 380 | __le32 k_uniqueness; |
381 | } __attribute__ ((__packed__)); | 381 | } __attribute__ ((__packed__)); |
382 | 382 | ||
383 | struct offset_v2 { | 383 | struct offset_v2 { |
384 | #ifdef __LITTLE_ENDIAN | 384 | __le64 v; |
385 | /* little endian version */ | ||
386 | __u64 k_offset:60; | ||
387 | __u64 k_type: 4; | ||
388 | #else | ||
389 | /* big endian version */ | ||
390 | __u64 k_type: 4; | ||
391 | __u64 k_offset:60; | ||
392 | #endif | ||
393 | } __attribute__ ((__packed__)); | 385 | } __attribute__ ((__packed__)); |
394 | 386 | ||
395 | #ifndef __LITTLE_ENDIAN | ||
396 | typedef union { | ||
397 | struct offset_v2 offset_v2; | ||
398 | __u64 linear; | ||
399 | } __attribute__ ((__packed__)) offset_v2_esafe_overlay; | ||
400 | |||
401 | static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 ) | 387 | static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 ) |
402 | { | 388 | { |
403 | offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; | 389 | __u8 type = le64_to_cpu(v2->v) >> 60; |
404 | tmp.linear = le64_to_cpu( tmp.linear ); | 390 | return (type <= TYPE_MAXTYPE)?type:TYPE_ANY; |
405 | return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY; | ||
406 | } | 391 | } |
407 | 392 | ||
408 | static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type ) | 393 | static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type ) |
409 | { | 394 | { |
410 | offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2; | 395 | v2->v = (v2->v & cpu_to_le64(~0ULL>>4)) | cpu_to_le64((__u64)type<<60); |
411 | tmp->linear = le64_to_cpu(tmp->linear); | ||
412 | tmp->offset_v2.k_type = type; | ||
413 | tmp->linear = cpu_to_le64(tmp->linear); | ||
414 | } | 396 | } |
415 | 397 | ||
416 | static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 ) | 398 | static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 ) |
417 | { | 399 | { |
418 | offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; | 400 | return le64_to_cpu(v2->v) & (~0ULL>>4); |
419 | tmp.linear = le64_to_cpu( tmp.linear ); | ||
420 | return tmp.offset_v2.k_offset; | ||
421 | } | 401 | } |
422 | 402 | ||
423 | static inline void set_offset_v2_k_offset( struct offset_v2 *v2, loff_t offset ){ | 403 | static inline void set_offset_v2_k_offset( struct offset_v2 *v2, loff_t offset ){ |
424 | offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2; | 404 | offset &= (~0ULL>>4); |
425 | tmp->linear = le64_to_cpu(tmp->linear); | 405 | v2->v = (v2->v & cpu_to_le64(15ULL<<60)) | cpu_to_le64(offset); |
426 | tmp->offset_v2.k_offset = offset; | ||
427 | tmp->linear = cpu_to_le64(tmp->linear); | ||
428 | } | 406 | } |
429 | #else | ||
430 | # define offset_v2_k_type(v2) ((v2)->k_type) | ||
431 | # define set_offset_v2_k_type(v2,val) (offset_v2_k_type(v2) = (val)) | ||
432 | # define offset_v2_k_offset(v2) ((v2)->k_offset) | ||
433 | # define set_offset_v2_k_offset(v2,val) (offset_v2_k_offset(v2) = (val)) | ||
434 | #endif | ||
435 | 407 | ||
436 | /* Key of an item determines its location in the S+tree, and | 408 | /* Key of an item determines its location in the S+tree, and |
437 | is composed of 4 components */ | 409 | is composed of 4 components */ |
438 | struct reiserfs_key { | 410 | struct reiserfs_key { |
439 | __u32 k_dir_id; /* packing locality: by default parent | 411 | __le32 k_dir_id; /* packing locality: by default parent |
440 | directory object id */ | 412 | directory object id */ |
441 | __u32 k_objectid; /* object identifier */ | 413 | __le32 k_objectid; /* object identifier */ |
442 | union { | 414 | union { |
443 | struct offset_v1 k_offset_v1; | 415 | struct offset_v1 k_offset_v1; |
444 | struct offset_v2 k_offset_v2; | 416 | struct offset_v2 k_offset_v2; |
445 | } __attribute__ ((__packed__)) u; | 417 | } __attribute__ ((__packed__)) u; |
446 | } __attribute__ ((__packed__)); | 418 | } __attribute__ ((__packed__)); |
447 | 419 | ||
420 | struct in_core_key { | ||
421 | __u32 k_dir_id; /* packing locality: by default parent | ||
422 | directory object id */ | ||
423 | __u32 k_objectid; /* object identifier */ | ||
424 | __u64 k_offset; | ||
425 | __u8 k_type; | ||
426 | }; | ||
448 | 427 | ||
449 | struct cpu_key { | 428 | struct cpu_key { |
450 | struct reiserfs_key on_disk_key; | 429 | struct in_core_key on_disk_key; |
451 | int version; | 430 | int version; |
452 | int key_length; /* 3 in all cases but direct2indirect and | 431 | int key_length; /* 3 in all cases but direct2indirect and |
453 | indirect2direct conversion */ | 432 | indirect2direct conversion */ |
@@ -508,15 +487,15 @@ struct item_head | |||
508 | item. Note that the key, not this field, is used to | 487 | item. Note that the key, not this field, is used to |
509 | determine the item type, and thus which field this | 488 | determine the item type, and thus which field this |
510 | union contains. */ | 489 | union contains. */ |
511 | __u16 ih_free_space_reserved; | 490 | __le16 ih_free_space_reserved; |
512 | /* Iff this is a directory item, this field equals the | 491 | /* Iff this is a directory item, this field equals the |
513 | number of directory entries in the directory item. */ | 492 | number of directory entries in the directory item. */ |
514 | __u16 ih_entry_count; | 493 | __le16 ih_entry_count; |
515 | } __attribute__ ((__packed__)) u; | 494 | } __attribute__ ((__packed__)) u; |
516 | __u16 ih_item_len; /* total size of the item body */ | 495 | __le16 ih_item_len; /* total size of the item body */ |
517 | __u16 ih_item_location; /* an offset to the item body | 496 | __le16 ih_item_location; /* an offset to the item body |
518 | * within the block */ | 497 | * within the block */ |
519 | __u16 ih_version; /* 0 for all old items, 2 for new | 498 | __le16 ih_version; /* 0 for all old items, 2 for new |
520 | ones. Highest bit is set by fsck | 499 | ones. Highest bit is set by fsck |
521 | temporary, cleaned after all | 500 | temporary, cleaned after all |
522 | done */ | 501 | done */ |
@@ -670,43 +649,29 @@ static inline void set_le_ih_k_type (struct item_head * ih, int type) | |||
670 | // | 649 | // |
671 | static inline loff_t cpu_key_k_offset (const struct cpu_key * key) | 650 | static inline loff_t cpu_key_k_offset (const struct cpu_key * key) |
672 | { | 651 | { |
673 | return (key->version == KEY_FORMAT_3_5) ? | 652 | return key->on_disk_key.k_offset; |
674 | key->on_disk_key.u.k_offset_v1.k_offset : | ||
675 | key->on_disk_key.u.k_offset_v2.k_offset; | ||
676 | } | 653 | } |
677 | 654 | ||
678 | static inline loff_t cpu_key_k_type (const struct cpu_key * key) | 655 | static inline loff_t cpu_key_k_type (const struct cpu_key * key) |
679 | { | 656 | { |
680 | return (key->version == KEY_FORMAT_3_5) ? | 657 | return key->on_disk_key.k_type; |
681 | uniqueness2type (key->on_disk_key.u.k_offset_v1.k_uniqueness) : | ||
682 | key->on_disk_key.u.k_offset_v2.k_type; | ||
683 | } | 658 | } |
684 | 659 | ||
685 | static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset) | 660 | static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset) |
686 | { | 661 | { |
687 | (key->version == KEY_FORMAT_3_5) ? | 662 | key->on_disk_key.k_offset = offset; |
688 | (key->on_disk_key.u.k_offset_v1.k_offset = offset) : | ||
689 | (key->on_disk_key.u.k_offset_v2.k_offset = offset); | ||
690 | } | 663 | } |
691 | 664 | ||
692 | |||
693 | static inline void set_cpu_key_k_type (struct cpu_key * key, int type) | 665 | static inline void set_cpu_key_k_type (struct cpu_key * key, int type) |
694 | { | 666 | { |
695 | (key->version == KEY_FORMAT_3_5) ? | 667 | key->on_disk_key.k_type = type; |
696 | (key->on_disk_key.u.k_offset_v1.k_uniqueness = type2uniqueness (type)): | ||
697 | (key->on_disk_key.u.k_offset_v2.k_type = type); | ||
698 | } | 668 | } |
699 | 669 | ||
700 | |||
701 | static inline void cpu_key_k_offset_dec (struct cpu_key * key) | 670 | static inline void cpu_key_k_offset_dec (struct cpu_key * key) |
702 | { | 671 | { |
703 | if (key->version == KEY_FORMAT_3_5) | 672 | key->on_disk_key.k_offset --; |
704 | key->on_disk_key.u.k_offset_v1.k_offset --; | ||
705 | else | ||
706 | key->on_disk_key.u.k_offset_v2.k_offset --; | ||
707 | } | 673 | } |
708 | 674 | ||
709 | |||
710 | #define is_direntry_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRENTRY) | 675 | #define is_direntry_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRENTRY) |
711 | #define is_direct_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRECT) | 676 | #define is_direct_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRECT) |
712 | #define is_indirect_cpu_key(key) (cpu_key_k_type (key) == TYPE_INDIRECT) | 677 | #define is_indirect_cpu_key(key) (cpu_key_k_type (key) == TYPE_INDIRECT) |
@@ -752,10 +717,10 @@ extern struct reiserfs_key root_key; | |||
752 | /* Header of a disk block. More precisely, header of a formatted leaf | 717 | /* Header of a disk block. More precisely, header of a formatted leaf |
753 | or internal node, and not the header of an unformatted node. */ | 718 | or internal node, and not the header of an unformatted node. */ |
754 | struct block_head { | 719 | struct block_head { |
755 | __u16 blk_level; /* Level of a block in the tree. */ | 720 | __le16 blk_level; /* Level of a block in the tree. */ |
756 | __u16 blk_nr_item; /* Number of keys/items in a block. */ | 721 | __le16 blk_nr_item; /* Number of keys/items in a block. */ |
757 | __u16 blk_free_space; /* Block free space in bytes. */ | 722 | __le16 blk_free_space; /* Block free space in bytes. */ |
758 | __u16 blk_reserved; | 723 | __le16 blk_reserved; |
759 | /* dump this in v4/planA */ | 724 | /* dump this in v4/planA */ |
760 | struct reiserfs_key blk_right_delim_key; /* kept only for compatibility */ | 725 | struct reiserfs_key blk_right_delim_key; /* kept only for compatibility */ |
761 | }; | 726 | }; |
@@ -819,19 +784,19 @@ struct block_head { | |||
819 | // | 784 | // |
820 | struct stat_data_v1 | 785 | struct stat_data_v1 |
821 | { | 786 | { |
822 | __u16 sd_mode; /* file type, permissions */ | 787 | __le16 sd_mode; /* file type, permissions */ |
823 | __u16 sd_nlink; /* number of hard links */ | 788 | __le16 sd_nlink; /* number of hard links */ |
824 | __u16 sd_uid; /* owner */ | 789 | __le16 sd_uid; /* owner */ |
825 | __u16 sd_gid; /* group */ | 790 | __le16 sd_gid; /* group */ |
826 | __u32 sd_size; /* file size */ | 791 | __le32 sd_size; /* file size */ |
827 | __u32 sd_atime; /* time of last access */ | 792 | __le32 sd_atime; /* time of last access */ |
828 | __u32 sd_mtime; /* time file was last modified */ | 793 | __le32 sd_mtime; /* time file was last modified */ |
829 | __u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ | 794 | __le32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ |
830 | union { | 795 | union { |
831 | __u32 sd_rdev; | 796 | __le32 sd_rdev; |
832 | __u32 sd_blocks; /* number of blocks file uses */ | 797 | __le32 sd_blocks; /* number of blocks file uses */ |
833 | } __attribute__ ((__packed__)) u; | 798 | } __attribute__ ((__packed__)) u; |
834 | __u32 sd_first_direct_byte; /* first byte of file which is stored | 799 | __le32 sd_first_direct_byte; /* first byte of file which is stored |
835 | in a direct item: except that if it | 800 | in a direct item: except that if it |
836 | equals 1 it is a symlink and if it | 801 | equals 1 it is a symlink and if it |
837 | equals ~(__u32)0 there is no | 802 | equals ~(__u32)0 there is no |
@@ -897,20 +862,20 @@ struct stat_data_v1 | |||
897 | /* Stat Data on disk (reiserfs version of UFS disk inode minus the | 862 | /* Stat Data on disk (reiserfs version of UFS disk inode minus the |
898 | address blocks) */ | 863 | address blocks) */ |
899 | struct stat_data { | 864 | struct stat_data { |
900 | __u16 sd_mode; /* file type, permissions */ | 865 | __le16 sd_mode; /* file type, permissions */ |
901 | __u16 sd_attrs; /* persistent inode flags */ | 866 | __le16 sd_attrs; /* persistent inode flags */ |
902 | __u32 sd_nlink; /* number of hard links */ | 867 | __le32 sd_nlink; /* number of hard links */ |
903 | __u64 sd_size; /* file size */ | 868 | __le64 sd_size; /* file size */ |
904 | __u32 sd_uid; /* owner */ | 869 | __le32 sd_uid; /* owner */ |
905 | __u32 sd_gid; /* group */ | 870 | __le32 sd_gid; /* group */ |
906 | __u32 sd_atime; /* time of last access */ | 871 | __le32 sd_atime; /* time of last access */ |
907 | __u32 sd_mtime; /* time file was last modified */ | 872 | __le32 sd_mtime; /* time file was last modified */ |
908 | __u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ | 873 | __le32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */ |
909 | __u32 sd_blocks; | 874 | __le32 sd_blocks; |
910 | union { | 875 | union { |
911 | __u32 sd_rdev; | 876 | __le32 sd_rdev; |
912 | __u32 sd_generation; | 877 | __le32 sd_generation; |
913 | //__u32 sd_first_direct_byte; | 878 | //__le32 sd_first_direct_byte; |
914 | /* first byte of file which is stored in a | 879 | /* first byte of file which is stored in a |
915 | direct item: except that if it equals 1 | 880 | direct item: except that if it equals 1 |
916 | it is a symlink and if it equals | 881 | it is a symlink and if it equals |
@@ -993,12 +958,12 @@ struct stat_data { | |||
993 | 958 | ||
994 | struct reiserfs_de_head | 959 | struct reiserfs_de_head |
995 | { | 960 | { |
996 | __u32 deh_offset; /* third component of the directory entry key */ | 961 | __le32 deh_offset; /* third component of the directory entry key */ |
997 | __u32 deh_dir_id; /* objectid of the parent directory of the object, that is referenced | 962 | __le32 deh_dir_id; /* objectid of the parent directory of the object, that is referenced |
998 | by directory entry */ | 963 | by directory entry */ |
999 | __u32 deh_objectid; /* objectid of the object, that is referenced by directory entry */ | 964 | __le32 deh_objectid; /* objectid of the object, that is referenced by directory entry */ |
1000 | __u16 deh_location; /* offset of name in the whole item */ | 965 | __le16 deh_location; /* offset of name in the whole item */ |
1001 | __u16 deh_state; /* whether 1) entry contains stat data (for future), and 2) whether | 966 | __le16 deh_state; /* whether 1) entry contains stat data (for future), and 2) whether |
1002 | entry is hidden (unlinked) */ | 967 | entry is hidden (unlinked) */ |
1003 | } __attribute__ ((__packed__)); | 968 | } __attribute__ ((__packed__)); |
1004 | #define DEH_SIZE sizeof(struct reiserfs_de_head) | 969 | #define DEH_SIZE sizeof(struct reiserfs_de_head) |
@@ -1058,10 +1023,10 @@ struct reiserfs_de_head | |||
1058 | #define de_visible(deh) test_bit_unaligned (DEH_Visible, &((deh)->deh_state)) | 1023 | #define de_visible(deh) test_bit_unaligned (DEH_Visible, &((deh)->deh_state)) |
1059 | #define de_hidden(deh) !test_bit_unaligned (DEH_Visible, &((deh)->deh_state)) | 1024 | #define de_hidden(deh) !test_bit_unaligned (DEH_Visible, &((deh)->deh_state)) |
1060 | 1025 | ||
1061 | extern void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid, | 1026 | extern void make_empty_dir_item_v1 (char * body, __le32 dirid, __le32 objid, |
1062 | __u32 par_dirid, __u32 par_objid); | 1027 | __le32 par_dirid, __le32 par_objid); |
1063 | extern void make_empty_dir_item (char * body, __u32 dirid, __u32 objid, | 1028 | extern void make_empty_dir_item (char * body, __le32 dirid, __le32 objid, |
1064 | __u32 par_dirid, __u32 par_objid); | 1029 | __le32 par_dirid, __le32 par_objid); |
1065 | 1030 | ||
1066 | /* array of the entry headers */ | 1031 | /* array of the entry headers */ |
1067 | /* get item body */ | 1032 | /* get item body */ |
@@ -1160,9 +1125,9 @@ struct reiserfs_dir_entry | |||
1160 | /* Disk child pointer: The pointer from an internal node of the tree | 1125 | /* Disk child pointer: The pointer from an internal node of the tree |
1161 | to a node that is on disk. */ | 1126 | to a node that is on disk. */ |
1162 | struct disk_child { | 1127 | struct disk_child { |
1163 | __u32 dc_block_number; /* Disk child's block number. */ | 1128 | __le32 dc_block_number; /* Disk child's block number. */ |
1164 | __u16 dc_size; /* Disk child's used space. */ | 1129 | __le16 dc_size; /* Disk child's used space. */ |
1165 | __u16 dc_reserved; | 1130 | __le16 dc_reserved; |
1166 | }; | 1131 | }; |
1167 | 1132 | ||
1168 | #define DC_SIZE (sizeof(struct disk_child)) | 1133 | #define DC_SIZE (sizeof(struct disk_child)) |
@@ -1476,7 +1441,7 @@ struct tree_balance | |||
1476 | int fs_gen; /* saved value of `reiserfs_generation' counter | 1441 | int fs_gen; /* saved value of `reiserfs_generation' counter |
1477 | see FILESYSTEM_CHANGED() macro in reiserfs_fs.h */ | 1442 | see FILESYSTEM_CHANGED() macro in reiserfs_fs.h */ |
1478 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES | 1443 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES |
1479 | struct reiserfs_key key; /* key pointer, to pass to block allocator or | 1444 | struct in_core_key key; /* key pointer, to pass to block allocator or |
1480 | another low-level subsystem */ | 1445 | another low-level subsystem */ |
1481 | #endif | 1446 | #endif |
1482 | } ; | 1447 | } ; |
@@ -1630,10 +1595,10 @@ struct reiserfs_iget_args { | |||
1630 | 1595 | ||
1631 | /* first block written in a commit. */ | 1596 | /* first block written in a commit. */ |
1632 | struct reiserfs_journal_desc { | 1597 | struct reiserfs_journal_desc { |
1633 | __u32 j_trans_id ; /* id of commit */ | 1598 | __le32 j_trans_id ; /* id of commit */ |
1634 | __u32 j_len ; /* length of commit. len +1 is the commit block */ | 1599 | __le32 j_len ; /* length of commit. len +1 is the commit block */ |
1635 | __u32 j_mount_id ; /* mount id of this trans*/ | 1600 | __le32 j_mount_id ; /* mount id of this trans*/ |
1636 | __u32 j_realblock[1] ; /* real locations for each block */ | 1601 | __le32 j_realblock[1] ; /* real locations for each block */ |
1637 | } ; | 1602 | } ; |
1638 | 1603 | ||
1639 | #define get_desc_trans_id(d) le32_to_cpu((d)->j_trans_id) | 1604 | #define get_desc_trans_id(d) le32_to_cpu((d)->j_trans_id) |
@@ -1646,9 +1611,9 @@ struct reiserfs_journal_desc { | |||
1646 | 1611 | ||
1647 | /* last block written in a commit */ | 1612 | /* last block written in a commit */ |
1648 | struct reiserfs_journal_commit { | 1613 | struct reiserfs_journal_commit { |
1649 | __u32 j_trans_id ; /* must match j_trans_id from the desc block */ | 1614 | __le32 j_trans_id ; /* must match j_trans_id from the desc block */ |
1650 | __u32 j_len ; /* ditto */ | 1615 | __le32 j_len ; /* ditto */ |
1651 | __u32 j_realblock[1] ; /* real locations for each block */ | 1616 | __le32 j_realblock[1] ; /* real locations for each block */ |
1652 | } ; | 1617 | } ; |
1653 | 1618 | ||
1654 | #define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id) | 1619 | #define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id) |
@@ -1663,9 +1628,9 @@ struct reiserfs_journal_commit { | |||
1663 | ** and this transaction does not need to be replayed. | 1628 | ** and this transaction does not need to be replayed. |
1664 | */ | 1629 | */ |
1665 | struct reiserfs_journal_header { | 1630 | struct reiserfs_journal_header { |
1666 | __u32 j_last_flush_trans_id ; /* id of last fully flushed transaction */ | 1631 | __le32 j_last_flush_trans_id ; /* id of last fully flushed transaction */ |
1667 | __u32 j_first_unflushed_offset ; /* offset in the log of where to start replay after a crash */ | 1632 | __le32 j_first_unflushed_offset ; /* offset in the log of where to start replay after a crash */ |
1668 | __u32 j_mount_id ; | 1633 | __le32 j_mount_id ; |
1669 | /* 12 */ struct journal_params jh_journal; | 1634 | /* 12 */ struct journal_params jh_journal; |
1670 | } ; | 1635 | } ; |
1671 | 1636 | ||
@@ -2117,7 +2082,7 @@ struct buffer_head * get_FEB (struct tree_balance *); | |||
2117 | struct __reiserfs_blocknr_hint { | 2082 | struct __reiserfs_blocknr_hint { |
2118 | struct inode * inode; /* inode passed to allocator, if we allocate unf. nodes */ | 2083 | struct inode * inode; /* inode passed to allocator, if we allocate unf. nodes */ |
2119 | long block; /* file offset, in blocks */ | 2084 | long block; /* file offset, in blocks */ |
2120 | struct reiserfs_key key; | 2085 | struct in_core_key key; |
2121 | struct path * path; /* search path, used by allocator to deternine search_start by | 2086 | struct path * path; /* search path, used by allocator to deternine search_start by |
2122 | * various ways */ | 2087 | * various ways */ |
2123 | struct reiserfs_transaction_handle * th; /* transaction handle is needed to log super blocks and | 2088 | struct reiserfs_transaction_handle * th; /* transaction handle is needed to log super blocks and |
@@ -2144,7 +2109,7 @@ void reiserfs_init_alloc_options (struct super_block *s); | |||
2144 | * to use for a new object underneat it. The locality is returned | 2109 | * to use for a new object underneat it. The locality is returned |
2145 | * in disk byte order (le). | 2110 | * in disk byte order (le). |
2146 | */ | 2111 | */ |
2147 | u32 reiserfs_choose_packing(struct inode *dir); | 2112 | __le32 reiserfs_choose_packing(struct inode *dir); |
2148 | 2113 | ||
2149 | int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value); | 2114 | int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value); |
2150 | void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted); | 2115 | void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted); |
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 1eaa48eca811..9244c5748820 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h | |||
@@ -10,8 +10,8 @@ | |||
10 | #define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */ | 10 | #define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */ |
11 | 11 | ||
12 | struct reiserfs_xattr_header { | 12 | struct reiserfs_xattr_header { |
13 | __u32 h_magic; /* magic number for identification */ | 13 | __le32 h_magic; /* magic number for identification */ |
14 | __u32 h_hash; /* hash of the value */ | 14 | __le32 h_hash; /* hash of the value */ |
15 | }; | 15 | }; |
16 | 16 | ||
17 | #ifdef __KERNEL__ | 17 | #ifdef __KERNEL__ |
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 32e52769a00b..91ac97c20777 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -89,10 +89,14 @@ enum { | |||
89 | RTM_GETANYCAST = 62, | 89 | RTM_GETANYCAST = 62, |
90 | #define RTM_GETANYCAST RTM_GETANYCAST | 90 | #define RTM_GETANYCAST RTM_GETANYCAST |
91 | 91 | ||
92 | RTM_MAX, | 92 | __RTM_MAX, |
93 | #define RTM_MAX RTM_MAX | 93 | #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) |
94 | }; | 94 | }; |
95 | 95 | ||
96 | #define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE) | ||
97 | #define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2) | ||
98 | #define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2) | ||
99 | |||
96 | /* | 100 | /* |
97 | Generic structure for encapsulation of optional route information. | 101 | Generic structure for encapsulation of optional route information. |
98 | It is reminiscent of sockaddr, but with sa_family replaced | 102 | It is reminiscent of sockaddr, but with sa_family replaced |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 1cced971232c..5f868a588581 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -845,6 +845,7 @@ extern void sched_idle_next(void); | |||
845 | extern void set_user_nice(task_t *p, long nice); | 845 | extern void set_user_nice(task_t *p, long nice); |
846 | extern int task_prio(const task_t *p); | 846 | extern int task_prio(const task_t *p); |
847 | extern int task_nice(const task_t *p); | 847 | extern int task_nice(const task_t *p); |
848 | extern int can_nice(const task_t *p, const int nice); | ||
848 | extern int task_curr(const task_t *p); | 849 | extern int task_curr(const task_t *p); |
849 | extern int idle_cpu(int cpu); | 850 | extern int idle_cpu(int cpu); |
850 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); | 851 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); |
@@ -1011,7 +1012,6 @@ extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct | |||
1011 | extern void flush_thread(void); | 1012 | extern void flush_thread(void); |
1012 | extern void exit_thread(void); | 1013 | extern void exit_thread(void); |
1013 | 1014 | ||
1014 | extern void exit_mm(struct task_struct *); | ||
1015 | extern void exit_files(struct task_struct *); | 1015 | extern void exit_files(struct task_struct *); |
1016 | extern void exit_signal(struct task_struct *); | 1016 | extern void exit_signal(struct task_struct *); |
1017 | extern void __exit_signal(struct task_struct *); | 1017 | extern void __exit_signal(struct task_struct *); |
diff --git a/include/linux/signal.h b/include/linux/signal.h index 99c97ad026c8..0a98f5ec5cae 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -9,6 +9,17 @@ | |||
9 | #ifdef __KERNEL__ | 9 | #ifdef __KERNEL__ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * These values of sa_flags are used only by the kernel as part of the | ||
13 | * irq handling routines. | ||
14 | * | ||
15 | * SA_INTERRUPT is also used by the irq handling routines. | ||
16 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
17 | */ | ||
18 | #define SA_PROBE SA_ONESHOT | ||
19 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
20 | #define SA_SHIRQ 0x04000000 | ||
21 | |||
22 | /* | ||
12 | * Real Time signals may be queued. | 23 | * Real Time signals may be queued. |
13 | */ | 24 | */ |
14 | 25 | ||
@@ -209,6 +220,12 @@ static inline void init_sigpending(struct sigpending *sig) | |||
209 | INIT_LIST_HEAD(&sig->list); | 220 | INIT_LIST_HEAD(&sig->list); |
210 | } | 221 | } |
211 | 222 | ||
223 | /* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */ | ||
224 | static inline int valid_signal(unsigned long sig) | ||
225 | { | ||
226 | return sig <= _NSIG ? 1 : 0; | ||
227 | } | ||
228 | |||
212 | extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p); | 229 | extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p); |
213 | extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); | 230 | extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); |
214 | extern long do_sigpending(void __user *, unsigned long); | 231 | extern long do_sigpending(void __user *, unsigned long); |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 22b701819619..cc04f5cd2286 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -167,13 +167,14 @@ struct skb_shared_info { | |||
167 | * @h: Transport layer header | 167 | * @h: Transport layer header |
168 | * @nh: Network layer header | 168 | * @nh: Network layer header |
169 | * @mac: Link layer header | 169 | * @mac: Link layer header |
170 | * @dst: FIXME: Describe this field | 170 | * @dst: destination entry |
171 | * @sp: the security path, used for xfrm | ||
171 | * @cb: Control buffer. Free for use by every layer. Put private vars here | 172 | * @cb: Control buffer. Free for use by every layer. Put private vars here |
172 | * @len: Length of actual data | 173 | * @len: Length of actual data |
173 | * @data_len: Data length | 174 | * @data_len: Data length |
174 | * @mac_len: Length of link layer header | 175 | * @mac_len: Length of link layer header |
175 | * @csum: Checksum | 176 | * @csum: Checksum |
176 | * @__unused: Dead field, may be reused | 177 | * @local_df: allow local fragmentation |
177 | * @cloned: Head may be cloned (check refcnt to be sure) | 178 | * @cloned: Head may be cloned (check refcnt to be sure) |
178 | * @nohdr: Payload reference only, must not modify header | 179 | * @nohdr: Payload reference only, must not modify header |
179 | * @pkt_type: Packet class | 180 | * @pkt_type: Packet class |
@@ -968,6 +969,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) | |||
968 | kfree_skb(skb); | 969 | kfree_skb(skb); |
969 | } | 970 | } |
970 | 971 | ||
972 | #ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB | ||
971 | /** | 973 | /** |
972 | * __dev_alloc_skb - allocate an skbuff for sending | 974 | * __dev_alloc_skb - allocate an skbuff for sending |
973 | * @length: length to allocate | 975 | * @length: length to allocate |
@@ -980,7 +982,6 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) | |||
980 | * | 982 | * |
981 | * %NULL is returned in there is no free memory. | 983 | * %NULL is returned in there is no free memory. |
982 | */ | 984 | */ |
983 | #ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB | ||
984 | static inline struct sk_buff *__dev_alloc_skb(unsigned int length, | 985 | static inline struct sk_buff *__dev_alloc_skb(unsigned int length, |
985 | int gfp_mask) | 986 | int gfp_mask) |
986 | { | 987 | { |
diff --git a/include/linux/slab.h b/include/linux/slab.h index 3e3c3ab8ff94..7d66385ae750 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h | |||
@@ -62,16 +62,9 @@ extern kmem_cache_t *kmem_cache_create(const char *, size_t, size_t, unsigned lo | |||
62 | extern int kmem_cache_destroy(kmem_cache_t *); | 62 | extern int kmem_cache_destroy(kmem_cache_t *); |
63 | extern int kmem_cache_shrink(kmem_cache_t *); | 63 | extern int kmem_cache_shrink(kmem_cache_t *); |
64 | extern void *kmem_cache_alloc(kmem_cache_t *, unsigned int __nocast); | 64 | extern void *kmem_cache_alloc(kmem_cache_t *, unsigned int __nocast); |
65 | #ifdef CONFIG_NUMA | ||
66 | extern void *kmem_cache_alloc_node(kmem_cache_t *, int); | ||
67 | #else | ||
68 | static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int node) | ||
69 | { | ||
70 | return kmem_cache_alloc(cachep, GFP_KERNEL); | ||
71 | } | ||
72 | #endif | ||
73 | extern void kmem_cache_free(kmem_cache_t *, void *); | 65 | extern void kmem_cache_free(kmem_cache_t *, void *); |
74 | extern unsigned int kmem_cache_size(kmem_cache_t *); | 66 | extern unsigned int kmem_cache_size(kmem_cache_t *); |
67 | extern kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags); | ||
75 | 68 | ||
76 | /* Size description struct for general caches. */ | 69 | /* Size description struct for general caches. */ |
77 | struct cache_sizes { | 70 | struct cache_sizes { |
@@ -109,6 +102,20 @@ extern void *kcalloc(size_t, size_t, unsigned int __nocast); | |||
109 | extern void kfree(const void *); | 102 | extern void kfree(const void *); |
110 | extern unsigned int ksize(const void *); | 103 | extern unsigned int ksize(const void *); |
111 | 104 | ||
105 | #ifdef CONFIG_NUMA | ||
106 | extern void *kmem_cache_alloc_node(kmem_cache_t *, int flags, int node); | ||
107 | extern void *kmalloc_node(size_t size, int flags, int node); | ||
108 | #else | ||
109 | static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node) | ||
110 | { | ||
111 | return kmem_cache_alloc(cachep, flags); | ||
112 | } | ||
113 | static inline void *kmalloc_node(size_t size, int flags, int node) | ||
114 | { | ||
115 | return kmalloc(size, flags); | ||
116 | } | ||
117 | #endif | ||
118 | |||
112 | extern int FASTCALL(kmem_cache_reap(int)); | 119 | extern int FASTCALL(kmem_cache_reap(int)); |
113 | extern int FASTCALL(kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)); | 120 | extern int FASTCALL(kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)); |
114 | 121 | ||
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 757cd9be7743..c39f6f72cbbc 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -456,8 +456,7 @@ asmlinkage long sys_semctl(int semid, int semnum, int cmd, union semun arg); | |||
456 | asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, | 456 | asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, |
457 | unsigned nsops, | 457 | unsigned nsops, |
458 | const struct timespec __user *timeout); | 458 | const struct timespec __user *timeout); |
459 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, | 459 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); |
460 | int shmflg, unsigned long __user *addr); | ||
461 | asmlinkage long sys_shmget(key_t key, size_t size, int flag); | 460 | asmlinkage long sys_shmget(key_t key, size_t size, int flag); |
462 | asmlinkage long sys_shmdt(char __user *shmaddr); | 461 | asmlinkage long sys_shmdt(char __user *shmaddr); |
463 | asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); | 462 | asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 358d52b0c445..772998147e3e 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -643,6 +643,7 @@ enum { | |||
643 | NET_SCTP_MAX_BURST = 12, | 643 | NET_SCTP_MAX_BURST = 12, |
644 | NET_SCTP_ADDIP_ENABLE = 13, | 644 | NET_SCTP_ADDIP_ENABLE = 13, |
645 | NET_SCTP_PRSCTP_ENABLE = 14, | 645 | NET_SCTP_PRSCTP_ENABLE = 14, |
646 | NET_SCTP_SNDBUF_POLICY = 15, | ||
646 | }; | 647 | }; |
647 | 648 | ||
648 | /* /proc/sys/net/bridge */ | 649 | /* /proc/sys/net/bridge */ |
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index f0df02ae68a4..fd2ef742a9fd 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h | |||
@@ -140,8 +140,11 @@ enum { | |||
140 | XFRM_MSG_FLUSHPOLICY, | 140 | XFRM_MSG_FLUSHPOLICY, |
141 | #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY | 141 | #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY |
142 | 142 | ||
143 | XFRM_MSG_MAX | 143 | __XFRM_MSG_MAX |
144 | }; | 144 | }; |
145 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) | ||
146 | |||
147 | #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) | ||
145 | 148 | ||
146 | struct xfrm_user_tmpl { | 149 | struct xfrm_user_tmpl { |
147 | struct xfrm_id id; | 150 | struct xfrm_id id; |
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 7af9a13cb9be..f1e5af4be98e 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h | |||
@@ -46,6 +46,7 @@ struct prefix_info { | |||
46 | #include <linux/in6.h> | 46 | #include <linux/in6.h> |
47 | #include <linux/netdevice.h> | 47 | #include <linux/netdevice.h> |
48 | #include <net/if_inet6.h> | 48 | #include <net/if_inet6.h> |
49 | #include <net/ipv6.h> | ||
49 | 50 | ||
50 | #define IN6_ADDR_HSIZE 16 | 51 | #define IN6_ADDR_HSIZE 16 |
51 | 52 | ||
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 87496e3aa330..fcb05a387dbe 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h | |||
@@ -140,7 +140,7 @@ psched_tod_diff(int delta_sec, int bound) | |||
140 | if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1) | 140 | if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1) |
141 | return bound; | 141 | return bound; |
142 | delta = delta_sec * 1000000; | 142 | delta = delta_sec * 1000000; |
143 | if (delta > bound) | 143 | if (delta > bound || delta < 0) |
144 | delta = bound; | 144 | delta = bound; |
145 | return delta; | 145 | return delta; |
146 | } | 146 | } |
@@ -156,7 +156,9 @@ psched_tod_diff(int delta_sec, int bound) | |||
156 | __delta += 1000000; \ | 156 | __delta += 1000000; \ |
157 | case 1: \ | 157 | case 1: \ |
158 | __delta += 1000000; \ | 158 | __delta += 1000000; \ |
159 | case 0: ; \ | 159 | case 0: \ |
160 | if (__delta > bound || __delta < 0) \ | ||
161 | __delta = bound; \ | ||
160 | } \ | 162 | } \ |
161 | __delta; \ | 163 | __delta; \ |
162 | }) | 164 | }) |
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 5576db56324d..f4fcee104707 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h | |||
@@ -407,32 +407,38 @@ sctp_vtag_verify(const struct sctp_chunk *chunk, | |||
407 | return 0; | 407 | return 0; |
408 | } | 408 | } |
409 | 409 | ||
410 | /* Check VTAG of the packet matches the sender's own tag OR its peer's | 410 | /* Check VTAG of the packet matches the sender's own tag and the T bit is |
411 | * tag and the T bit is set in the Chunk Flags. | 411 | * not set, OR its peer's tag and the T bit is set in the Chunk Flags. |
412 | */ | 412 | */ |
413 | static inline int | 413 | static inline int |
414 | sctp_vtag_verify_either(const struct sctp_chunk *chunk, | 414 | sctp_vtag_verify_either(const struct sctp_chunk *chunk, |
415 | const struct sctp_association *asoc) | 415 | const struct sctp_association *asoc) |
416 | { | 416 | { |
417 | /* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2 | 417 | /* RFC 2960 Section 8.5.1, sctpimpguide Section 2.41 |
418 | * | 418 | * |
419 | * B) The receiver of a ABORT shall accept the packet if the | 419 | * B) The receiver of a ABORT MUST accept the packet |
420 | * Verification Tag field of the packet matches its own tag OR it | 420 | * if the Verification Tag field of the packet matches its own tag |
421 | * is set to its peer's tag and the T bit is set in the Chunk | 421 | * and the T bit is not set |
422 | * Flags. Otherwise, the receiver MUST silently discard the packet | 422 | * OR |
423 | * and take no further action. | 423 | * it is set to its peer's tag and the T bit is set in the Chunk |
424 | * | 424 | * Flags. |
425 | * (C) The receiver of a SHUTDOWN COMPLETE shall accept the | 425 | * Otherwise, the receiver MUST silently discard the packet |
426 | * packet if the Verification Tag field of the packet | 426 | * and take no further action. |
427 | * matches its own tag OR it is set to its peer's tag and | ||
428 | * the T bit is set in the Chunk Flags. Otherwise, the | ||
429 | * receiver MUST silently discard the packet and take no | ||
430 | * further action.... | ||
431 | * | 427 | * |
428 | * C) The receiver of a SHUTDOWN COMPLETE shall accept the packet | ||
429 | * if the Verification Tag field of the packet matches its own tag | ||
430 | * and the T bit is not set | ||
431 | * OR | ||
432 | * it is set to its peer's tag and the T bit is set in the Chunk | ||
433 | * Flags. | ||
434 | * Otherwise, the receiver MUST silently discard the packet | ||
435 | * and take no further action. An endpoint MUST ignore the | ||
436 | * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state. | ||
432 | */ | 437 | */ |
433 | if ((ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) || | 438 | if ((!sctp_test_T_bit(chunk) && |
434 | (sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) | 439 | (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)) || |
435 | == asoc->c.peer_vtag))) { | 440 | (sctp_test_T_bit(chunk) && |
441 | (ntohl(chunk->sctp_hdr->vtag) == asoc->c.peer_vtag))) { | ||
436 | return 1; | 442 | return 1; |
437 | } | 443 | } |
438 | 444 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 7e64cf6bda1e..6c24d9cd3d66 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -154,6 +154,13 @@ extern struct sctp_globals { | |||
154 | int max_retrans_path; | 154 | int max_retrans_path; |
155 | int max_retrans_init; | 155 | int max_retrans_init; |
156 | 156 | ||
157 | /* | ||
158 | * Policy for preforming sctp/socket accounting | ||
159 | * 0 - do socket level accounting, all assocs share sk_sndbuf | ||
160 | * 1 - do sctp accounting, each asoc may use sk_sndbuf bytes | ||
161 | */ | ||
162 | int sndbuf_policy; | ||
163 | |||
157 | /* HB.interval - 30 seconds */ | 164 | /* HB.interval - 30 seconds */ |
158 | int hb_interval; | 165 | int hb_interval; |
159 | 166 | ||
@@ -207,6 +214,7 @@ extern struct sctp_globals { | |||
207 | #define sctp_valid_cookie_life (sctp_globals.valid_cookie_life) | 214 | #define sctp_valid_cookie_life (sctp_globals.valid_cookie_life) |
208 | #define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable) | 215 | #define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable) |
209 | #define sctp_max_retrans_association (sctp_globals.max_retrans_association) | 216 | #define sctp_max_retrans_association (sctp_globals.max_retrans_association) |
217 | #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) | ||
210 | #define sctp_max_retrans_path (sctp_globals.max_retrans_path) | 218 | #define sctp_max_retrans_path (sctp_globals.max_retrans_path) |
211 | #define sctp_max_retrans_init (sctp_globals.max_retrans_init) | 219 | #define sctp_max_retrans_init (sctp_globals.max_retrans_init) |
212 | #define sctp_hb_interval (sctp_globals.hb_interval) | 220 | #define sctp_hb_interval (sctp_globals.hb_interval) |
@@ -1212,7 +1220,8 @@ struct sctp_endpoint { | |||
1212 | /* Default timeouts. */ | 1220 | /* Default timeouts. */ |
1213 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; | 1221 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; |
1214 | 1222 | ||
1215 | /* Various thresholds. */ | 1223 | /* sendbuf acct. policy. */ |
1224 | __u32 sndbuf_policy; | ||
1216 | 1225 | ||
1217 | /* Name for debugging output... */ | 1226 | /* Name for debugging output... */ |
1218 | char *debug_name; | 1227 | char *debug_name; |
diff --git a/include/net/sock.h b/include/net/sock.h index be81cabd0da3..cc4c9190b7fd 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -90,17 +90,17 @@ do { spin_lock_init(&((__sk)->sk_lock.slock)); \ | |||
90 | struct sock; | 90 | struct sock; |
91 | 91 | ||
92 | /** | 92 | /** |
93 | * struct sock_common - minimal network layer representation of sockets | 93 | * struct sock_common - minimal network layer representation of sockets |
94 | * @skc_family - network address family | 94 | * @skc_family: network address family |
95 | * @skc_state - Connection state | 95 | * @skc_state: Connection state |
96 | * @skc_reuse - %SO_REUSEADDR setting | 96 | * @skc_reuse: %SO_REUSEADDR setting |
97 | * @skc_bound_dev_if - bound device index if != 0 | 97 | * @skc_bound_dev_if: bound device index if != 0 |
98 | * @skc_node - main hash linkage for various protocol lookup tables | 98 | * @skc_node: main hash linkage for various protocol lookup tables |
99 | * @skc_bind_node - bind hash linkage for various protocol lookup tables | 99 | * @skc_bind_node: bind hash linkage for various protocol lookup tables |
100 | * @skc_refcnt - reference count | 100 | * @skc_refcnt: reference count |
101 | * | 101 | * |
102 | * This is the minimal network layer representation of sockets, the header | 102 | * This is the minimal network layer representation of sockets, the header |
103 | * for struct sock and struct tcp_tw_bucket. | 103 | * for struct sock and struct tcp_tw_bucket. |
104 | */ | 104 | */ |
105 | struct sock_common { | 105 | struct sock_common { |
106 | unsigned short skc_family; | 106 | unsigned short skc_family; |
@@ -114,60 +114,61 @@ struct sock_common { | |||
114 | 114 | ||
115 | /** | 115 | /** |
116 | * struct sock - network layer representation of sockets | 116 | * struct sock - network layer representation of sockets |
117 | * @__sk_common - shared layout with tcp_tw_bucket | 117 | * @__sk_common: shared layout with tcp_tw_bucket |
118 | * @sk_shutdown - mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN | 118 | * @sk_shutdown: mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN |
119 | * @sk_userlocks - %SO_SNDBUF and %SO_RCVBUF settings | 119 | * @sk_userlocks: %SO_SNDBUF and %SO_RCVBUF settings |
120 | * @sk_lock - synchronizer | 120 | * @sk_lock: synchronizer |
121 | * @sk_rcvbuf - size of receive buffer in bytes | 121 | * @sk_rcvbuf: size of receive buffer in bytes |
122 | * @sk_sleep - sock wait queue | 122 | * @sk_sleep: sock wait queue |
123 | * @sk_dst_cache - destination cache | 123 | * @sk_dst_cache: destination cache |
124 | * @sk_dst_lock - destination cache lock | 124 | * @sk_dst_lock: destination cache lock |
125 | * @sk_policy - flow policy | 125 | * @sk_policy: flow policy |
126 | * @sk_rmem_alloc - receive queue bytes committed | 126 | * @sk_rmem_alloc: receive queue bytes committed |
127 | * @sk_receive_queue - incoming packets | 127 | * @sk_receive_queue: incoming packets |
128 | * @sk_wmem_alloc - transmit queue bytes committed | 128 | * @sk_wmem_alloc: transmit queue bytes committed |
129 | * @sk_write_queue - Packet sending queue | 129 | * @sk_write_queue: Packet sending queue |
130 | * @sk_omem_alloc - "o" is "option" or "other" | 130 | * @sk_omem_alloc: "o" is "option" or "other" |
131 | * @sk_wmem_queued - persistent queue size | 131 | * @sk_wmem_queued: persistent queue size |
132 | * @sk_forward_alloc - space allocated forward | 132 | * @sk_forward_alloc: space allocated forward |
133 | * @sk_allocation - allocation mode | 133 | * @sk_allocation: allocation mode |
134 | * @sk_sndbuf - size of send buffer in bytes | 134 | * @sk_sndbuf: size of send buffer in bytes |
135 | * @sk_flags - %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings | 135 | * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings |
136 | * @sk_no_check - %SO_NO_CHECK setting, wether or not checkup packets | 136 | * @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets |
137 | * @sk_route_caps - route capabilities (e.g. %NETIF_F_TSO) | 137 | * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) |
138 | * @sk_lingertime - %SO_LINGER l_linger setting | 138 | * @sk_lingertime: %SO_LINGER l_linger setting |
139 | * @sk_hashent - hash entry in several tables (e.g. tcp_ehash) | 139 | * @sk_hashent: hash entry in several tables (e.g. tcp_ehash) |
140 | * @sk_backlog - always used with the per-socket spinlock held | 140 | * @sk_backlog: always used with the per-socket spinlock held |
141 | * @sk_callback_lock - used with the callbacks in the end of this struct | 141 | * @sk_callback_lock: used with the callbacks in the end of this struct |
142 | * @sk_error_queue - rarely used | 142 | * @sk_error_queue: rarely used |
143 | * @sk_prot - protocol handlers inside a network family | 143 | * @sk_prot: protocol handlers inside a network family |
144 | * @sk_err - last error | 144 | * @sk_err: last error |
145 | * @sk_err_soft - errors that don't cause failure but are the cause of a persistent failure not just 'timed out' | 145 | * @sk_err_soft: errors that don't cause failure but are the cause of a persistent failure not just 'timed out' |
146 | * @sk_ack_backlog - current listen backlog | 146 | * @sk_ack_backlog: current listen backlog |
147 | * @sk_max_ack_backlog - listen backlog set in listen() | 147 | * @sk_max_ack_backlog: listen backlog set in listen() |
148 | * @sk_priority - %SO_PRIORITY setting | 148 | * @sk_priority: %SO_PRIORITY setting |
149 | * @sk_type - socket type (%SOCK_STREAM, etc) | 149 | * @sk_type: socket type (%SOCK_STREAM, etc) |
150 | * @sk_protocol - which protocol this socket belongs in this network family | 150 | * @sk_protocol: which protocol this socket belongs in this network family |
151 | * @sk_peercred - %SO_PEERCRED setting | 151 | * @sk_peercred: %SO_PEERCRED setting |
152 | * @sk_rcvlowat - %SO_RCVLOWAT setting | 152 | * @sk_rcvlowat: %SO_RCVLOWAT setting |
153 | * @sk_rcvtimeo - %SO_RCVTIMEO setting | 153 | * @sk_rcvtimeo: %SO_RCVTIMEO setting |
154 | * @sk_sndtimeo - %SO_SNDTIMEO setting | 154 | * @sk_sndtimeo: %SO_SNDTIMEO setting |
155 | * @sk_filter - socket filtering instructions | 155 | * @sk_filter: socket filtering instructions |
156 | * @sk_protinfo - private area, net family specific, when not using slab | 156 | * @sk_protinfo: private area, net family specific, when not using slab |
157 | * @sk_timer - sock cleanup timer | 157 | * @sk_timer: sock cleanup timer |
158 | * @sk_stamp - time stamp of last packet received | 158 | * @sk_stamp: time stamp of last packet received |
159 | * @sk_socket - Identd and reporting IO signals | 159 | * @sk_socket: Identd and reporting IO signals |
160 | * @sk_user_data - RPC layer private data | 160 | * @sk_user_data: RPC layer private data |
161 | * @sk_sndmsg_page - cached page for sendmsg | 161 | * @sk_sndmsg_page: cached page for sendmsg |
162 | * @sk_sndmsg_off - cached offset for sendmsg | 162 | * @sk_sndmsg_off: cached offset for sendmsg |
163 | * @sk_send_head - front of stuff to transmit | 163 | * @sk_send_head: front of stuff to transmit |
164 | * @sk_write_pending - a write to stream socket waits to start | 164 | * @sk_security: used by security modules |
165 | * @sk_state_change - callback to indicate change in the state of the sock | 165 | * @sk_write_pending: a write to stream socket waits to start |
166 | * @sk_data_ready - callback to indicate there is data to be processed | 166 | * @sk_state_change: callback to indicate change in the state of the sock |
167 | * @sk_write_space - callback to indicate there is bf sending space available | 167 | * @sk_data_ready: callback to indicate there is data to be processed |
168 | * @sk_error_report - callback to indicate errors (e.g. %MSG_ERRQUEUE) | 168 | * @sk_write_space: callback to indicate there is bf sending space available |
169 | * @sk_backlog_rcv - callback to process the backlog | 169 | * @sk_error_report: callback to indicate errors (e.g. %MSG_ERRQUEUE) |
170 | * @sk_destruct - called at sock freeing time, i.e. when all refcnt == 0 | 170 | * @sk_backlog_rcv: callback to process the backlog |
171 | * @sk_destruct: called at sock freeing time, i.e. when all refcnt == 0 | ||
171 | */ | 172 | */ |
172 | struct sock { | 173 | struct sock { |
173 | /* | 174 | /* |
@@ -1223,8 +1224,8 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) | |||
1223 | 1224 | ||
1224 | /** | 1225 | /** |
1225 | * sk_eat_skb - Release a skb if it is no longer needed | 1226 | * sk_eat_skb - Release a skb if it is no longer needed |
1226 | * @sk - socket to eat this skb from | 1227 | * @sk: socket to eat this skb from |
1227 | * @skb - socket buffer to eat | 1228 | * @skb: socket buffer to eat |
1228 | * | 1229 | * |
1229 | * This routine must be called with interrupts disabled or with the socket | 1230 | * This routine must be called with interrupts disabled or with the socket |
1230 | * locked so that the sk_buff queue operation is ok. | 1231 | * locked so that the sk_buff queue operation is ok. |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 73e9a8ca3d3b..e142a256d5dc 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _NET_XFRM_H | 1 | #ifndef _NET_XFRM_H |
2 | #define _NET_XFRM_H | 2 | #define _NET_XFRM_H |
3 | 3 | ||
4 | #include <linux/compiler.h> | ||
4 | #include <linux/xfrm.h> | 5 | #include <linux/xfrm.h> |
5 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
6 | #include <linux/list.h> | 7 | #include <linux/list.h> |
@@ -516,6 +517,15 @@ struct xfrm_dst | |||
516 | u32 child_mtu_cached; | 517 | u32 child_mtu_cached; |
517 | }; | 518 | }; |
518 | 519 | ||
520 | static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) | ||
521 | { | ||
522 | dst_release(xdst->route); | ||
523 | if (likely(xdst->u.dst.xfrm)) | ||
524 | xfrm_state_put(xdst->u.dst.xfrm); | ||
525 | } | ||
526 | |||
527 | extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev); | ||
528 | |||
519 | /* Decapsulation state, used by the input to store data during | 529 | /* Decapsulation state, used by the input to store data during |
520 | * decapsulation procedure, to be used later (during the policy | 530 | * decapsulation procedure, to be used later (during the policy |
521 | * check | 531 | * check |
diff --git a/include/video/edid.h b/include/video/edid.h index abc1b489c0db..b913f196131d 100644 --- a/include/video/edid.h +++ b/include/video/edid.h | |||
@@ -4,9 +4,6 @@ | |||
4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | 5 | ||
6 | #include <linux/config.h> | 6 | #include <linux/config.h> |
7 | #ifdef CONFIG_PPC_OF | ||
8 | #include <linux/pci.h> | ||
9 | #endif | ||
10 | 7 | ||
11 | #ifdef CONFIG_X86 | 8 | #ifdef CONFIG_X86 |
12 | struct edid_info { | 9 | struct edid_info { |
@@ -14,14 +11,8 @@ struct edid_info { | |||
14 | }; | 11 | }; |
15 | 12 | ||
16 | extern struct edid_info edid_info; | 13 | extern struct edid_info edid_info; |
17 | extern char *get_EDID_from_BIOS(void *); | ||
18 | |||
19 | #endif /* CONFIG_X86 */ | 14 | #endif /* CONFIG_X86 */ |
20 | 15 | ||
21 | #ifdef CONFIG_PPC_OF | ||
22 | extern char *get_EDID_from_OF(struct pci_dev *pdev); | ||
23 | #endif | ||
24 | |||
25 | #endif /* __KERNEL__ */ | 16 | #endif /* __KERNEL__ */ |
26 | 17 | ||
27 | #endif /* __linux_video_edid_h__ */ | 18 | #endif /* __linux_video_edid_h__ */ |
diff --git a/include/video/tdfx.h b/include/video/tdfx.h index a896e4442060..04237676b17c 100644 --- a/include/video/tdfx.h +++ b/include/video/tdfx.h | |||
@@ -99,6 +99,8 @@ | |||
99 | #define MISCINIT1_2DBLOCK_DIS BIT(15) | 99 | #define MISCINIT1_2DBLOCK_DIS BIT(15) |
100 | #define DRAMINIT0_SGRAM_NUM BIT(26) | 100 | #define DRAMINIT0_SGRAM_NUM BIT(26) |
101 | #define DRAMINIT0_SGRAM_TYPE BIT(27) | 101 | #define DRAMINIT0_SGRAM_TYPE BIT(27) |
102 | #define DRAMINIT0_SGRAM_TYPE_MASK (BIT(27)|BIT(28)|BIT(29)) | ||
103 | #define DRAMINIT0_SGRAM_TYPE_SHIFT 27 | ||
102 | #define DRAMINIT1_MEM_SDRAM BIT(30) | 104 | #define DRAMINIT1_MEM_SDRAM BIT(30) |
103 | #define VGAINIT0_VGA_DISABLE BIT(0) | 105 | #define VGAINIT0_VGA_DISABLE BIT(0) |
104 | #define VGAINIT0_EXT_TIMING BIT(1) | 106 | #define VGAINIT0_EXT_TIMING BIT(1) |
diff --git a/init/Kconfig b/init/Kconfig index abe2682a6ca6..40d286d1d118 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -275,6 +275,27 @@ config KALLSYMS_EXTRA_PASS | |||
275 | reported. KALLSYMS_EXTRA_PASS is only a temporary workaround while | 275 | reported. KALLSYMS_EXTRA_PASS is only a temporary workaround while |
276 | you wait for kallsyms to be fixed. | 276 | you wait for kallsyms to be fixed. |
277 | 277 | ||
278 | |||
279 | config PRINTK | ||
280 | default y | ||
281 | bool "Enable support for printk" if EMBEDDED | ||
282 | help | ||
283 | This option enables normal printk support. Removing it | ||
284 | eliminates most of the message strings from the kernel image | ||
285 | and makes the kernel more or less silent. As this makes it | ||
286 | very difficult to diagnose system problems, saying N here is | ||
287 | strongly discouraged. | ||
288 | |||
289 | config BUG | ||
290 | bool "BUG() support" if EMBEDDED | ||
291 | default y | ||
292 | help | ||
293 | Disabling this option eliminates support for BUG and WARN, reducing | ||
294 | the size of your kernel image and potentially quietly ignoring | ||
295 | numerous fatal conditions. You should only consider disabling this | ||
296 | option for embedded systems with no facilities for reporting errors. | ||
297 | Just say Y. | ||
298 | |||
278 | config BASE_FULL | 299 | config BASE_FULL |
279 | default y | 300 | default y |
280 | bool "Enable full-sized data structures for core" if EMBEDDED | 301 | bool "Enable full-sized data structures for core" if EMBEDDED |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index cb0cd3cf3b5a..0acf245f441d 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
24 | #include <linux/netlink.h> | 24 | #include <linux/netlink.h> |
25 | #include <linux/syscalls.h> | 25 | #include <linux/syscalls.h> |
26 | #include <linux/signal.h> | ||
26 | #include <net/sock.h> | 27 | #include <net/sock.h> |
27 | #include "util.h" | 28 | #include "util.h" |
28 | 29 | ||
@@ -767,7 +768,7 @@ static inline void pipelined_send(struct mqueue_inode_info *info, | |||
767 | list_del(&receiver->list); | 768 | list_del(&receiver->list); |
768 | receiver->state = STATE_PENDING; | 769 | receiver->state = STATE_PENDING; |
769 | wake_up_process(receiver->task); | 770 | wake_up_process(receiver->task); |
770 | wmb(); | 771 | smp_wmb(); |
771 | receiver->state = STATE_READY; | 772 | receiver->state = STATE_READY; |
772 | } | 773 | } |
773 | 774 | ||
@@ -786,7 +787,7 @@ static inline void pipelined_receive(struct mqueue_inode_info *info) | |||
786 | list_del(&sender->list); | 787 | list_del(&sender->list); |
787 | sender->state = STATE_PENDING; | 788 | sender->state = STATE_PENDING; |
788 | wake_up_process(sender->task); | 789 | wake_up_process(sender->task); |
789 | wmb(); | 790 | smp_wmb(); |
790 | sender->state = STATE_READY; | 791 | sender->state = STATE_READY; |
791 | } | 792 | } |
792 | 793 | ||
@@ -976,8 +977,7 @@ asmlinkage long sys_mq_notify(mqd_t mqdes, | |||
976 | notification.sigev_notify != SIGEV_THREAD)) | 977 | notification.sigev_notify != SIGEV_THREAD)) |
977 | return -EINVAL; | 978 | return -EINVAL; |
978 | if (notification.sigev_notify == SIGEV_SIGNAL && | 979 | if (notification.sigev_notify == SIGEV_SIGNAL && |
979 | (notification.sigev_signo < 0 || | 980 | !valid_signal(notification.sigev_signo)) { |
980 | notification.sigev_signo > _NSIG)) { | ||
981 | return -EINVAL; | 981 | return -EINVAL; |
982 | } | 982 | } |
983 | if (notification.sigev_notify == SIGEV_THREAD) { | 983 | if (notification.sigev_notify == SIGEV_THREAD) { |
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
30 | #include <linux/audit.h> | 30 | #include <linux/audit.h> |
31 | #include <linux/ptrace.h> | ||
32 | |||
31 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
32 | 34 | ||
33 | #include "util.h" | 35 | #include "util.h" |
@@ -771,6 +773,18 @@ out: | |||
771 | return err; | 773 | return err; |
772 | } | 774 | } |
773 | 775 | ||
776 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) | ||
777 | { | ||
778 | unsigned long ret; | ||
779 | long err; | ||
780 | |||
781 | err = do_shmat(shmid, shmaddr, shmflg, &ret); | ||
782 | if (err) | ||
783 | return err; | ||
784 | force_successful_syscall_return(); | ||
785 | return (long)ret; | ||
786 | } | ||
787 | |||
774 | /* | 788 | /* |
775 | * detach and kill segment if marked destroyed. | 789 | * detach and kill segment if marked destroyed. |
776 | * The work is done in shm_close. | 790 | * The work is done in shm_close. |
diff --git a/kernel/audit.c b/kernel/audit.c index 0f84dd7af2c8..ac26d4d960d3 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -427,7 +427,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
427 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is | 427 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is |
428 | * processed by audit_receive_msg. Malformed skbs with wrong length are | 428 | * processed by audit_receive_msg. Malformed skbs with wrong length are |
429 | * discarded silently. */ | 429 | * discarded silently. */ |
430 | static int audit_receive_skb(struct sk_buff *skb) | 430 | static void audit_receive_skb(struct sk_buff *skb) |
431 | { | 431 | { |
432 | int err; | 432 | int err; |
433 | struct nlmsghdr *nlh; | 433 | struct nlmsghdr *nlh; |
@@ -436,7 +436,7 @@ static int audit_receive_skb(struct sk_buff *skb) | |||
436 | while (skb->len >= NLMSG_SPACE(0)) { | 436 | while (skb->len >= NLMSG_SPACE(0)) { |
437 | nlh = (struct nlmsghdr *)skb->data; | 437 | nlh = (struct nlmsghdr *)skb->data; |
438 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) | 438 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) |
439 | return 0; | 439 | return; |
440 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | 440 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); |
441 | if (rlen > skb->len) | 441 | if (rlen > skb->len) |
442 | rlen = skb->len; | 442 | rlen = skb->len; |
@@ -446,23 +446,20 @@ static int audit_receive_skb(struct sk_buff *skb) | |||
446 | netlink_ack(skb, nlh, 0); | 446 | netlink_ack(skb, nlh, 0); |
447 | skb_pull(skb, rlen); | 447 | skb_pull(skb, rlen); |
448 | } | 448 | } |
449 | return 0; | ||
450 | } | 449 | } |
451 | 450 | ||
452 | /* Receive messages from netlink socket. */ | 451 | /* Receive messages from netlink socket. */ |
453 | static void audit_receive(struct sock *sk, int length) | 452 | static void audit_receive(struct sock *sk, int length) |
454 | { | 453 | { |
455 | struct sk_buff *skb; | 454 | struct sk_buff *skb; |
455 | unsigned int qlen; | ||
456 | 456 | ||
457 | if (down_trylock(&audit_netlink_sem)) | 457 | down(&audit_netlink_sem); |
458 | return; | ||
459 | 458 | ||
460 | /* FIXME: this must not cause starvation */ | 459 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
461 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { | 460 | skb = skb_dequeue(&sk->sk_receive_queue); |
462 | if (audit_receive_skb(skb) && skb->len) | 461 | audit_receive_skb(skb); |
463 | skb_queue_head(&sk->sk_receive_queue, skb); | 462 | kfree_skb(skb); |
464 | else | ||
465 | kfree_skb(skb); | ||
466 | } | 463 | } |
467 | up(&audit_netlink_sem); | 464 | up(&audit_netlink_sem); |
468 | } | 465 | } |
diff --git a/kernel/exit.c b/kernel/exit.c index 39d35935b371..7be283d98983 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/mempolicy.h> | 27 | #include <linux/mempolicy.h> |
28 | #include <linux/cpuset.h> | 28 | #include <linux/cpuset.h> |
29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
30 | #include <linux/signal.h> | ||
30 | 31 | ||
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include <asm/unistd.h> | 33 | #include <asm/unistd.h> |
@@ -38,6 +39,8 @@ extern struct task_struct *child_reaper; | |||
38 | 39 | ||
39 | int getrusage(struct task_struct *, int, struct rusage __user *); | 40 | int getrusage(struct task_struct *, int, struct rusage __user *); |
40 | 41 | ||
42 | static void exit_mm(struct task_struct * tsk); | ||
43 | |||
41 | static void __unhash_process(struct task_struct *p) | 44 | static void __unhash_process(struct task_struct *p) |
42 | { | 45 | { |
43 | nr_threads--; | 46 | nr_threads--; |
@@ -209,7 +212,7 @@ static inline int has_stopped_jobs(int pgrp) | |||
209 | } | 212 | } |
210 | 213 | ||
211 | /** | 214 | /** |
212 | * reparent_to_init() - Reparent the calling kernel thread to the init task. | 215 | * reparent_to_init - Reparent the calling kernel thread to the init task. |
213 | * | 216 | * |
214 | * If a kernel thread is launched as a result of a system call, or if | 217 | * If a kernel thread is launched as a result of a system call, or if |
215 | * it ever exits, it should generally reparent itself to init so that | 218 | * it ever exits, it should generally reparent itself to init so that |
@@ -277,7 +280,7 @@ void set_special_pids(pid_t session, pid_t pgrp) | |||
277 | */ | 280 | */ |
278 | int allow_signal(int sig) | 281 | int allow_signal(int sig) |
279 | { | 282 | { |
280 | if (sig < 1 || sig > _NSIG) | 283 | if (!valid_signal(sig) || sig < 1) |
281 | return -EINVAL; | 284 | return -EINVAL; |
282 | 285 | ||
283 | spin_lock_irq(¤t->sighand->siglock); | 286 | spin_lock_irq(¤t->sighand->siglock); |
@@ -298,7 +301,7 @@ EXPORT_SYMBOL(allow_signal); | |||
298 | 301 | ||
299 | int disallow_signal(int sig) | 302 | int disallow_signal(int sig) |
300 | { | 303 | { |
301 | if (sig < 1 || sig > _NSIG) | 304 | if (!valid_signal(sig) || sig < 1) |
302 | return -EINVAL; | 305 | return -EINVAL; |
303 | 306 | ||
304 | spin_lock_irq(¤t->sighand->siglock); | 307 | spin_lock_irq(¤t->sighand->siglock); |
@@ -473,7 +476,7 @@ EXPORT_SYMBOL_GPL(exit_fs); | |||
473 | * Turn us into a lazy TLB process if we | 476 | * Turn us into a lazy TLB process if we |
474 | * aren't already.. | 477 | * aren't already.. |
475 | */ | 478 | */ |
476 | void exit_mm(struct task_struct * tsk) | 479 | static void exit_mm(struct task_struct * tsk) |
477 | { | 480 | { |
478 | struct mm_struct *mm = tsk->mm; | 481 | struct mm_struct *mm = tsk->mm; |
479 | 482 | ||
@@ -517,8 +520,6 @@ static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_re | |||
517 | */ | 520 | */ |
518 | BUG_ON(p == reaper || reaper->exit_state >= EXIT_ZOMBIE); | 521 | BUG_ON(p == reaper || reaper->exit_state >= EXIT_ZOMBIE); |
519 | p->real_parent = reaper; | 522 | p->real_parent = reaper; |
520 | if (p->parent == p->real_parent) | ||
521 | BUG(); | ||
522 | } | 523 | } |
523 | 524 | ||
524 | static inline void reparent_thread(task_t *p, task_t *father, int traced) | 525 | static inline void reparent_thread(task_t *p, task_t *father, int traced) |
diff --git a/kernel/futex.c b/kernel/futex.c index 7b54a672d0ad..c7130f86106c 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/mount.h> | 39 | #include <linux/mount.h> |
40 | #include <linux/pagemap.h> | 40 | #include <linux/pagemap.h> |
41 | #include <linux/syscalls.h> | 41 | #include <linux/syscalls.h> |
42 | #include <linux/signal.h> | ||
42 | 43 | ||
43 | #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8) | 44 | #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8) |
44 | 45 | ||
@@ -654,7 +655,7 @@ static int futex_fd(unsigned long uaddr, int signal) | |||
654 | int ret, err; | 655 | int ret, err; |
655 | 656 | ||
656 | ret = -EINVAL; | 657 | ret = -EINVAL; |
657 | if (signal < 0 || signal > _NSIG) | 658 | if (!valid_signal(signal)) |
658 | goto out; | 659 | goto out; |
659 | 660 | ||
660 | ret = get_unused_fd(); | 661 | ret = get_unused_fd(); |
diff --git a/kernel/kthread.c b/kernel/kthread.c index e377e2244103..f50f174e92da 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -174,7 +174,7 @@ int kthread_stop(struct task_struct *k) | |||
174 | 174 | ||
175 | /* Must init completion *before* thread sees kthread_stop_info.k */ | 175 | /* Must init completion *before* thread sees kthread_stop_info.k */ |
176 | init_completion(&kthread_stop_info.done); | 176 | init_completion(&kthread_stop_info.done); |
177 | wmb(); | 177 | smp_wmb(); |
178 | 178 | ||
179 | /* Now set kthread_should_stop() to true, and wake it up. */ | 179 | /* Now set kthread_should_stop() to true, and wake it up. */ |
180 | kthread_stop_info.k = k; | 180 | kthread_stop_info.k = k; |
diff --git a/kernel/module.c b/kernel/module.c index 2dbfa0773faf..5734ab09d3f9 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1801,7 +1801,7 @@ sys_init_module(void __user *umod, | |||
1801 | /* Init routine failed: abort. Try to protect us from | 1801 | /* Init routine failed: abort. Try to protect us from |
1802 | buggy refcounters. */ | 1802 | buggy refcounters. */ |
1803 | mod->state = MODULE_STATE_GOING; | 1803 | mod->state = MODULE_STATE_GOING; |
1804 | synchronize_kernel(); | 1804 | synchronize_sched(); |
1805 | if (mod->unsafe) | 1805 | if (mod->unsafe) |
1806 | printk(KERN_ERR "%s: module is now stuck!\n", | 1806 | printk(KERN_ERR "%s: module is now stuck!\n", |
1807 | mod->name); | 1807 | mod->name); |
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index ae5bebc3b18f..90b3b68dee3f 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
@@ -1099,7 +1099,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist) | |||
1099 | return pblist; | 1099 | return pblist; |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | /** | 1102 | /* |
1103 | * Using bio to read from swap. | 1103 | * Using bio to read from swap. |
1104 | * This code requires a bit more work than just using buffer heads | 1104 | * This code requires a bit more work than just using buffer heads |
1105 | * but, it is the recommended way for 2.5/2.6. | 1105 | * but, it is the recommended way for 2.5/2.6. |
diff --git a/kernel/printk.c b/kernel/printk.c index 1498689548d1..290a07ce2c8a 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -85,10 +85,6 @@ static int console_locked; | |||
85 | */ | 85 | */ |
86 | static DEFINE_SPINLOCK(logbuf_lock); | 86 | static DEFINE_SPINLOCK(logbuf_lock); |
87 | 87 | ||
88 | static char __log_buf[__LOG_BUF_LEN]; | ||
89 | static char *log_buf = __log_buf; | ||
90 | static int log_buf_len = __LOG_BUF_LEN; | ||
91 | |||
92 | #define LOG_BUF_MASK (log_buf_len-1) | 88 | #define LOG_BUF_MASK (log_buf_len-1) |
93 | #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) | 89 | #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) |
94 | 90 | ||
@@ -99,7 +95,6 @@ static int log_buf_len = __LOG_BUF_LEN; | |||
99 | static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */ | 95 | static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */ |
100 | static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */ | 96 | static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */ |
101 | static unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */ | 97 | static unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */ |
102 | static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */ | ||
103 | 98 | ||
104 | /* | 99 | /* |
105 | * Array of consoles built from command line options (console=) | 100 | * Array of consoles built from command line options (console=) |
@@ -120,6 +115,13 @@ static int preferred_console = -1; | |||
120 | /* Flag: console code may call schedule() */ | 115 | /* Flag: console code may call schedule() */ |
121 | static int console_may_schedule; | 116 | static int console_may_schedule; |
122 | 117 | ||
118 | #ifdef CONFIG_PRINTK | ||
119 | |||
120 | static char __log_buf[__LOG_BUF_LEN]; | ||
121 | static char *log_buf = __log_buf; | ||
122 | static int log_buf_len = __LOG_BUF_LEN; | ||
123 | static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */ | ||
124 | |||
123 | /* | 125 | /* |
124 | * Setup a list of consoles. Called from init/main.c | 126 | * Setup a list of consoles. Called from init/main.c |
125 | */ | 127 | */ |
@@ -535,6 +537,7 @@ __setup("time", printk_time_setup); | |||
535 | * then changes console_loglevel may break. This is because console_loglevel | 537 | * then changes console_loglevel may break. This is because console_loglevel |
536 | * is inspected when the actual printing occurs. | 538 | * is inspected when the actual printing occurs. |
537 | */ | 539 | */ |
540 | |||
538 | asmlinkage int printk(const char *fmt, ...) | 541 | asmlinkage int printk(const char *fmt, ...) |
539 | { | 542 | { |
540 | va_list args; | 543 | va_list args; |
@@ -655,6 +658,18 @@ out: | |||
655 | EXPORT_SYMBOL(printk); | 658 | EXPORT_SYMBOL(printk); |
656 | EXPORT_SYMBOL(vprintk); | 659 | EXPORT_SYMBOL(vprintk); |
657 | 660 | ||
661 | #else | ||
662 | |||
663 | asmlinkage long sys_syslog(int type, char __user * buf, int len) | ||
664 | { | ||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | int do_syslog(int type, char __user * buf, int len) { return 0; } | ||
669 | static void call_console_drivers(unsigned long start, unsigned long end) {} | ||
670 | |||
671 | #endif | ||
672 | |||
658 | /** | 673 | /** |
659 | * acquire_console_sem - lock the console system for exclusive use. | 674 | * acquire_console_sem - lock the console system for exclusive use. |
660 | * | 675 | * |
@@ -931,7 +946,7 @@ int unregister_console(struct console * console) | |||
931 | return res; | 946 | return res; |
932 | } | 947 | } |
933 | EXPORT_SYMBOL(unregister_console); | 948 | EXPORT_SYMBOL(unregister_console); |
934 | 949 | ||
935 | /** | 950 | /** |
936 | * tty_write_message - write a message to a certain tty, not just the console. | 951 | * tty_write_message - write a message to a certain tty, not just the console. |
937 | * | 952 | * |
diff --git a/kernel/profile.c b/kernel/profile.c index a38fa70075fe..0221a50ca867 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
@@ -184,7 +184,7 @@ void unregister_timer_hook(int (*hook)(struct pt_regs *)) | |||
184 | WARN_ON(hook != timer_hook); | 184 | WARN_ON(hook != timer_hook); |
185 | timer_hook = NULL; | 185 | timer_hook = NULL; |
186 | /* make sure all CPUs see the NULL hook */ | 186 | /* make sure all CPUs see the NULL hook */ |
187 | synchronize_kernel(); | 187 | synchronize_sched(); /* Allow ongoing interrupts to complete. */ |
188 | } | 188 | } |
189 | 189 | ||
190 | EXPORT_SYMBOL_GPL(register_timer_hook); | 190 | EXPORT_SYMBOL_GPL(register_timer_hook); |
@@ -522,7 +522,7 @@ static int __init create_hash_tables(void) | |||
522 | return 0; | 522 | return 0; |
523 | out_cleanup: | 523 | out_cleanup: |
524 | prof_on = 0; | 524 | prof_on = 0; |
525 | mb(); | 525 | smp_mb(); |
526 | on_each_cpu(profile_nop, NULL, 0, 1); | 526 | on_each_cpu(profile_nop, NULL, 0, 1); |
527 | for_each_online_cpu(cpu) { | 527 | for_each_online_cpu(cpu) { |
528 | struct page *page; | 528 | struct page *page; |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 88b306c4e841..8dcb8f6288bc 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/smp_lock.h> | 16 | #include <linux/smp_lock.h> |
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/signal.h> | ||
19 | 20 | ||
20 | #include <asm/pgtable.h> | 21 | #include <asm/pgtable.h> |
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
@@ -135,7 +136,7 @@ int ptrace_attach(struct task_struct *task) | |||
135 | (current->gid != task->sgid) || | 136 | (current->gid != task->sgid) || |
136 | (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) | 137 | (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) |
137 | goto bad; | 138 | goto bad; |
138 | rmb(); | 139 | smp_rmb(); |
139 | if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE)) | 140 | if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE)) |
140 | goto bad; | 141 | goto bad; |
141 | /* the same process cannot be attached many times */ | 142 | /* the same process cannot be attached many times */ |
@@ -166,7 +167,7 @@ bad: | |||
166 | 167 | ||
167 | int ptrace_detach(struct task_struct *child, unsigned int data) | 168 | int ptrace_detach(struct task_struct *child, unsigned int data) |
168 | { | 169 | { |
169 | if ((unsigned long) data > _NSIG) | 170 | if (!valid_signal(data)) |
170 | return -EIO; | 171 | return -EIO; |
171 | 172 | ||
172 | /* Architecture-specific hardware disable .. */ | 173 | /* Architecture-specific hardware disable .. */ |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index d00eded75d71..f436993bd590 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -444,15 +444,18 @@ static void wakeme_after_rcu(struct rcu_head *head) | |||
444 | } | 444 | } |
445 | 445 | ||
446 | /** | 446 | /** |
447 | * synchronize_kernel - wait until a grace period has elapsed. | 447 | * synchronize_rcu - wait until a grace period has elapsed. |
448 | * | 448 | * |
449 | * Control will return to the caller some time after a full grace | 449 | * Control will return to the caller some time after a full grace |
450 | * period has elapsed, in other words after all currently executing RCU | 450 | * period has elapsed, in other words after all currently executing RCU |
451 | * read-side critical sections have completed. RCU read-side critical | 451 | * read-side critical sections have completed. RCU read-side critical |
452 | * sections are delimited by rcu_read_lock() and rcu_read_unlock(), | 452 | * sections are delimited by rcu_read_lock() and rcu_read_unlock(), |
453 | * and may be nested. | 453 | * and may be nested. |
454 | * | ||
455 | * If your read-side code is not protected by rcu_read_lock(), do -not- | ||
456 | * use synchronize_rcu(). | ||
454 | */ | 457 | */ |
455 | void synchronize_kernel(void) | 458 | void synchronize_rcu(void) |
456 | { | 459 | { |
457 | struct rcu_synchronize rcu; | 460 | struct rcu_synchronize rcu; |
458 | 461 | ||
@@ -464,7 +467,16 @@ void synchronize_kernel(void) | |||
464 | wait_for_completion(&rcu.completion); | 467 | wait_for_completion(&rcu.completion); |
465 | } | 468 | } |
466 | 469 | ||
470 | /* | ||
471 | * Deprecated, use synchronize_rcu() or synchronize_sched() instead. | ||
472 | */ | ||
473 | void synchronize_kernel(void) | ||
474 | { | ||
475 | synchronize_rcu(); | ||
476 | } | ||
477 | |||
467 | module_param(maxbatch, int, 0); | 478 | module_param(maxbatch, int, 0); |
468 | EXPORT_SYMBOL_GPL(call_rcu); | 479 | EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */ |
469 | EXPORT_SYMBOL_GPL(call_rcu_bh); | 480 | EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */ |
470 | EXPORT_SYMBOL_GPL(synchronize_kernel); | 481 | EXPORT_SYMBOL_GPL(synchronize_rcu); |
482 | EXPORT_SYMBOL(synchronize_kernel); /* WARNING: GPL-only in April 2006. */ | ||
diff --git a/kernel/sched.c b/kernel/sched.c index 9bb7489ee645..0dc3158667a2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2906,6 +2906,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, | |||
2906 | * @q: the waitqueue | 2906 | * @q: the waitqueue |
2907 | * @mode: which threads | 2907 | * @mode: which threads |
2908 | * @nr_exclusive: how many wake-one or wake-many threads to wake up | 2908 | * @nr_exclusive: how many wake-one or wake-many threads to wake up |
2909 | * @key: is directly passed to the wakeup function | ||
2909 | */ | 2910 | */ |
2910 | void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode, | 2911 | void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode, |
2911 | int nr_exclusive, void *key) | 2912 | int nr_exclusive, void *key) |
@@ -2928,7 +2929,7 @@ void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode) | |||
2928 | } | 2929 | } |
2929 | 2930 | ||
2930 | /** | 2931 | /** |
2931 | * __wake_up - sync- wake up threads blocked on a waitqueue. | 2932 | * __wake_up_sync - wake up threads blocked on a waitqueue. |
2932 | * @q: the waitqueue | 2933 | * @q: the waitqueue |
2933 | * @mode: which threads | 2934 | * @mode: which threads |
2934 | * @nr_exclusive: how many wake-one or wake-many threads to wake up | 2935 | * @nr_exclusive: how many wake-one or wake-many threads to wake up |
@@ -3223,6 +3224,19 @@ out_unlock: | |||
3223 | 3224 | ||
3224 | EXPORT_SYMBOL(set_user_nice); | 3225 | EXPORT_SYMBOL(set_user_nice); |
3225 | 3226 | ||
3227 | /* | ||
3228 | * can_nice - check if a task can reduce its nice value | ||
3229 | * @p: task | ||
3230 | * @nice: nice value | ||
3231 | */ | ||
3232 | int can_nice(const task_t *p, const int nice) | ||
3233 | { | ||
3234 | /* convert nice value [19,-20] to rlimit style value [0,39] */ | ||
3235 | int nice_rlim = 19 - nice; | ||
3236 | return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || | ||
3237 | capable(CAP_SYS_NICE)); | ||
3238 | } | ||
3239 | |||
3226 | #ifdef __ARCH_WANT_SYS_NICE | 3240 | #ifdef __ARCH_WANT_SYS_NICE |
3227 | 3241 | ||
3228 | /* | 3242 | /* |
@@ -3242,12 +3256,8 @@ asmlinkage long sys_nice(int increment) | |||
3242 | * We don't have to worry. Conceptually one call occurs first | 3256 | * We don't have to worry. Conceptually one call occurs first |
3243 | * and we have a single winner. | 3257 | * and we have a single winner. |
3244 | */ | 3258 | */ |
3245 | if (increment < 0) { | 3259 | if (increment < -40) |
3246 | if (!capable(CAP_SYS_NICE)) | 3260 | increment = -40; |
3247 | return -EPERM; | ||
3248 | if (increment < -40) | ||
3249 | increment = -40; | ||
3250 | } | ||
3251 | if (increment > 40) | 3261 | if (increment > 40) |
3252 | increment = 40; | 3262 | increment = 40; |
3253 | 3263 | ||
@@ -3257,6 +3267,9 @@ asmlinkage long sys_nice(int increment) | |||
3257 | if (nice > 19) | 3267 | if (nice > 19) |
3258 | nice = 19; | 3268 | nice = 19; |
3259 | 3269 | ||
3270 | if (increment < 0 && !can_nice(current, nice)) | ||
3271 | return -EPERM; | ||
3272 | |||
3260 | retval = security_task_setnice(current, nice); | 3273 | retval = security_task_setnice(current, nice); |
3261 | if (retval) | 3274 | if (retval) |
3262 | return retval; | 3275 | return retval; |
@@ -3372,6 +3385,7 @@ recheck: | |||
3372 | return -EINVAL; | 3385 | return -EINVAL; |
3373 | 3386 | ||
3374 | if ((policy == SCHED_FIFO || policy == SCHED_RR) && | 3387 | if ((policy == SCHED_FIFO || policy == SCHED_RR) && |
3388 | param->sched_priority > p->signal->rlim[RLIMIT_RTPRIO].rlim_cur && | ||
3375 | !capable(CAP_SYS_NICE)) | 3389 | !capable(CAP_SYS_NICE)) |
3376 | return -EPERM; | 3390 | return -EPERM; |
3377 | if ((current->euid != p->euid) && (current->euid != p->uid) && | 3391 | if ((current->euid != p->euid) && (current->euid != p->uid) && |
diff --git a/kernel/signal.c b/kernel/signal.c index e6567d7f2b62..8f3debc77c5b 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/syscalls.h> | 23 | #include <linux/syscalls.h> |
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/posix-timers.h> | 25 | #include <linux/posix-timers.h> |
26 | #include <linux/signal.h> | ||
26 | #include <asm/param.h> | 27 | #include <asm/param.h> |
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | #include <asm/unistd.h> | 29 | #include <asm/unistd.h> |
@@ -646,7 +647,7 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
646 | struct task_struct *t) | 647 | struct task_struct *t) |
647 | { | 648 | { |
648 | int error = -EINVAL; | 649 | int error = -EINVAL; |
649 | if (sig < 0 || sig > _NSIG) | 650 | if (!valid_signal(sig)) |
650 | return error; | 651 | return error; |
651 | error = -EPERM; | 652 | error = -EPERM; |
652 | if ((!info || ((unsigned long)info != 1 && | 653 | if ((!info || ((unsigned long)info != 1 && |
@@ -1245,7 +1246,7 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p) | |||
1245 | * Make sure legacy kernel users don't send in bad values | 1246 | * Make sure legacy kernel users don't send in bad values |
1246 | * (normal paths check this in check_kill_permission). | 1247 | * (normal paths check this in check_kill_permission). |
1247 | */ | 1248 | */ |
1248 | if (sig < 0 || sig > _NSIG) | 1249 | if (!valid_signal(sig)) |
1249 | return -EINVAL; | 1250 | return -EINVAL; |
1250 | 1251 | ||
1251 | /* | 1252 | /* |
@@ -1520,7 +1521,7 @@ void do_notify_parent(struct task_struct *tsk, int sig) | |||
1520 | if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) | 1521 | if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) |
1521 | sig = 0; | 1522 | sig = 0; |
1522 | } | 1523 | } |
1523 | if (sig > 0 && sig <= _NSIG) | 1524 | if (valid_signal(sig) && sig > 0) |
1524 | __group_send_sig_info(sig, &info, tsk->parent); | 1525 | __group_send_sig_info(sig, &info, tsk->parent); |
1525 | __wake_up_parent(tsk, tsk->parent); | 1526 | __wake_up_parent(tsk, tsk->parent); |
1526 | spin_unlock_irqrestore(&psig->siglock, flags); | 1527 | spin_unlock_irqrestore(&psig->siglock, flags); |
@@ -2364,7 +2365,7 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact) | |||
2364 | { | 2365 | { |
2365 | struct k_sigaction *k; | 2366 | struct k_sigaction *k; |
2366 | 2367 | ||
2367 | if (sig < 1 || sig > _NSIG || (act && sig_kernel_only(sig))) | 2368 | if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig))) |
2368 | return -EINVAL; | 2369 | return -EINVAL; |
2369 | 2370 | ||
2370 | k = ¤t->sighand->action[sig-1]; | 2371 | k = ¤t->sighand->action[sig-1]; |
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index c39ed70af174..6116b25aa7cf 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c | |||
@@ -33,7 +33,7 @@ static int stopmachine(void *cpu) | |||
33 | set_cpus_allowed(current, cpumask_of_cpu((int)(long)cpu)); | 33 | set_cpus_allowed(current, cpumask_of_cpu((int)(long)cpu)); |
34 | 34 | ||
35 | /* Ack: we are alive */ | 35 | /* Ack: we are alive */ |
36 | mb(); /* Theoretically the ack = 0 might not be on this CPU yet. */ | 36 | smp_mb(); /* Theoretically the ack = 0 might not be on this CPU yet. */ |
37 | atomic_inc(&stopmachine_thread_ack); | 37 | atomic_inc(&stopmachine_thread_ack); |
38 | 38 | ||
39 | /* Simple state machine */ | 39 | /* Simple state machine */ |
@@ -43,14 +43,14 @@ static int stopmachine(void *cpu) | |||
43 | local_irq_disable(); | 43 | local_irq_disable(); |
44 | irqs_disabled = 1; | 44 | irqs_disabled = 1; |
45 | /* Ack: irqs disabled. */ | 45 | /* Ack: irqs disabled. */ |
46 | mb(); /* Must read state first. */ | 46 | smp_mb(); /* Must read state first. */ |
47 | atomic_inc(&stopmachine_thread_ack); | 47 | atomic_inc(&stopmachine_thread_ack); |
48 | } else if (stopmachine_state == STOPMACHINE_PREPARE | 48 | } else if (stopmachine_state == STOPMACHINE_PREPARE |
49 | && !prepared) { | 49 | && !prepared) { |
50 | /* Everyone is in place, hold CPU. */ | 50 | /* Everyone is in place, hold CPU. */ |
51 | preempt_disable(); | 51 | preempt_disable(); |
52 | prepared = 1; | 52 | prepared = 1; |
53 | mb(); /* Must read state first. */ | 53 | smp_mb(); /* Must read state first. */ |
54 | atomic_inc(&stopmachine_thread_ack); | 54 | atomic_inc(&stopmachine_thread_ack); |
55 | } | 55 | } |
56 | /* Yield in first stage: migration threads need to | 56 | /* Yield in first stage: migration threads need to |
@@ -62,7 +62,7 @@ static int stopmachine(void *cpu) | |||
62 | } | 62 | } |
63 | 63 | ||
64 | /* Ack: we are exiting. */ | 64 | /* Ack: we are exiting. */ |
65 | mb(); /* Must read state first. */ | 65 | smp_mb(); /* Must read state first. */ |
66 | atomic_inc(&stopmachine_thread_ack); | 66 | atomic_inc(&stopmachine_thread_ack); |
67 | 67 | ||
68 | if (irqs_disabled) | 68 | if (irqs_disabled) |
@@ -77,7 +77,7 @@ static int stopmachine(void *cpu) | |||
77 | static void stopmachine_set_state(enum stopmachine_state state) | 77 | static void stopmachine_set_state(enum stopmachine_state state) |
78 | { | 78 | { |
79 | atomic_set(&stopmachine_thread_ack, 0); | 79 | atomic_set(&stopmachine_thread_ack, 0); |
80 | wmb(); | 80 | smp_wmb(); |
81 | stopmachine_state = state; | 81 | stopmachine_state = state; |
82 | while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads) | 82 | while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads) |
83 | cpu_relax(); | 83 | cpu_relax(); |
diff --git a/kernel/sys.c b/kernel/sys.c index 462d78d55895..f64e97cabe25 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/dcookies.h> | 25 | #include <linux/dcookies.h> |
26 | #include <linux/suspend.h> | 26 | #include <linux/suspend.h> |
27 | #include <linux/tty.h> | 27 | #include <linux/tty.h> |
28 | #include <linux/signal.h> | ||
28 | 29 | ||
29 | #include <linux/compat.h> | 30 | #include <linux/compat.h> |
30 | #include <linux/syscalls.h> | 31 | #include <linux/syscalls.h> |
@@ -227,7 +228,7 @@ static int set_one_prio(struct task_struct *p, int niceval, int error) | |||
227 | error = -EPERM; | 228 | error = -EPERM; |
228 | goto out; | 229 | goto out; |
229 | } | 230 | } |
230 | if (niceval < task_nice(p) && !capable(CAP_SYS_NICE)) { | 231 | if (niceval < task_nice(p) && !can_nice(p, niceval)) { |
231 | error = -EACCES; | 232 | error = -EACCES; |
232 | goto out; | 233 | goto out; |
233 | } | 234 | } |
@@ -525,7 +526,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid) | |||
525 | if (new_egid != old_egid) | 526 | if (new_egid != old_egid) |
526 | { | 527 | { |
527 | current->mm->dumpable = 0; | 528 | current->mm->dumpable = 0; |
528 | wmb(); | 529 | smp_wmb(); |
529 | } | 530 | } |
530 | if (rgid != (gid_t) -1 || | 531 | if (rgid != (gid_t) -1 || |
531 | (egid != (gid_t) -1 && egid != old_rgid)) | 532 | (egid != (gid_t) -1 && egid != old_rgid)) |
@@ -556,7 +557,7 @@ asmlinkage long sys_setgid(gid_t gid) | |||
556 | if(old_egid != gid) | 557 | if(old_egid != gid) |
557 | { | 558 | { |
558 | current->mm->dumpable=0; | 559 | current->mm->dumpable=0; |
559 | wmb(); | 560 | smp_wmb(); |
560 | } | 561 | } |
561 | current->gid = current->egid = current->sgid = current->fsgid = gid; | 562 | current->gid = current->egid = current->sgid = current->fsgid = gid; |
562 | } | 563 | } |
@@ -565,7 +566,7 @@ asmlinkage long sys_setgid(gid_t gid) | |||
565 | if(old_egid != gid) | 566 | if(old_egid != gid) |
566 | { | 567 | { |
567 | current->mm->dumpable=0; | 568 | current->mm->dumpable=0; |
568 | wmb(); | 569 | smp_wmb(); |
569 | } | 570 | } |
570 | current->egid = current->fsgid = gid; | 571 | current->egid = current->fsgid = gid; |
571 | } | 572 | } |
@@ -596,7 +597,7 @@ static int set_user(uid_t new_ruid, int dumpclear) | |||
596 | if(dumpclear) | 597 | if(dumpclear) |
597 | { | 598 | { |
598 | current->mm->dumpable = 0; | 599 | current->mm->dumpable = 0; |
599 | wmb(); | 600 | smp_wmb(); |
600 | } | 601 | } |
601 | current->uid = new_ruid; | 602 | current->uid = new_ruid; |
602 | return 0; | 603 | return 0; |
@@ -653,7 +654,7 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) | |||
653 | if (new_euid != old_euid) | 654 | if (new_euid != old_euid) |
654 | { | 655 | { |
655 | current->mm->dumpable=0; | 656 | current->mm->dumpable=0; |
656 | wmb(); | 657 | smp_wmb(); |
657 | } | 658 | } |
658 | current->fsuid = current->euid = new_euid; | 659 | current->fsuid = current->euid = new_euid; |
659 | if (ruid != (uid_t) -1 || | 660 | if (ruid != (uid_t) -1 || |
@@ -703,7 +704,7 @@ asmlinkage long sys_setuid(uid_t uid) | |||
703 | if (old_euid != uid) | 704 | if (old_euid != uid) |
704 | { | 705 | { |
705 | current->mm->dumpable = 0; | 706 | current->mm->dumpable = 0; |
706 | wmb(); | 707 | smp_wmb(); |
707 | } | 708 | } |
708 | current->fsuid = current->euid = uid; | 709 | current->fsuid = current->euid = uid; |
709 | current->suid = new_suid; | 710 | current->suid = new_suid; |
@@ -748,7 +749,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) | |||
748 | if (euid != current->euid) | 749 | if (euid != current->euid) |
749 | { | 750 | { |
750 | current->mm->dumpable = 0; | 751 | current->mm->dumpable = 0; |
751 | wmb(); | 752 | smp_wmb(); |
752 | } | 753 | } |
753 | current->euid = euid; | 754 | current->euid = euid; |
754 | } | 755 | } |
@@ -798,7 +799,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) | |||
798 | if (egid != current->egid) | 799 | if (egid != current->egid) |
799 | { | 800 | { |
800 | current->mm->dumpable = 0; | 801 | current->mm->dumpable = 0; |
801 | wmb(); | 802 | smp_wmb(); |
802 | } | 803 | } |
803 | current->egid = egid; | 804 | current->egid = egid; |
804 | } | 805 | } |
@@ -845,7 +846,7 @@ asmlinkage long sys_setfsuid(uid_t uid) | |||
845 | if (uid != old_fsuid) | 846 | if (uid != old_fsuid) |
846 | { | 847 | { |
847 | current->mm->dumpable = 0; | 848 | current->mm->dumpable = 0; |
848 | wmb(); | 849 | smp_wmb(); |
849 | } | 850 | } |
850 | current->fsuid = uid; | 851 | current->fsuid = uid; |
851 | } | 852 | } |
@@ -875,7 +876,7 @@ asmlinkage long sys_setfsgid(gid_t gid) | |||
875 | if (gid != old_fsgid) | 876 | if (gid != old_fsgid) |
876 | { | 877 | { |
877 | current->mm->dumpable = 0; | 878 | current->mm->dumpable = 0; |
878 | wmb(); | 879 | smp_wmb(); |
879 | } | 880 | } |
880 | current->fsgid = gid; | 881 | current->fsgid = gid; |
881 | key_fsgid_changed(current); | 882 | key_fsgid_changed(current); |
@@ -1637,7 +1638,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1637 | switch (option) { | 1638 | switch (option) { |
1638 | case PR_SET_PDEATHSIG: | 1639 | case PR_SET_PDEATHSIG: |
1639 | sig = arg2; | 1640 | sig = arg2; |
1640 | if (sig < 0 || sig > _NSIG) { | 1641 | if (!valid_signal(sig)) { |
1641 | error = -EINVAL; | 1642 | error = -EINVAL; |
1642 | break; | 1643 | break; |
1643 | } | 1644 | } |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 1802a311dd3f..0dda70ed1f98 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
@@ -52,6 +52,7 @@ cond_syscall(sys_msgsnd); | |||
52 | cond_syscall(sys_msgrcv); | 52 | cond_syscall(sys_msgrcv); |
53 | cond_syscall(sys_msgctl); | 53 | cond_syscall(sys_msgctl); |
54 | cond_syscall(sys_shmget); | 54 | cond_syscall(sys_shmget); |
55 | cond_syscall(sys_shmat); | ||
55 | cond_syscall(sys_shmdt); | 56 | cond_syscall(sys_shmdt); |
56 | cond_syscall(sys_shmctl); | 57 | cond_syscall(sys_shmctl); |
57 | cond_syscall(sys_mq_open); | 58 | cond_syscall(sys_mq_open); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 79dbd93bd697..701d12c63068 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1991,6 +1991,8 @@ int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, | |||
1991 | * @filp: the file structure | 1991 | * @filp: the file structure |
1992 | * @buffer: the user buffer | 1992 | * @buffer: the user buffer |
1993 | * @lenp: the size of the user buffer | 1993 | * @lenp: the size of the user buffer |
1994 | * @ppos: file position | ||
1995 | * @ppos: the current position in the file | ||
1994 | * | 1996 | * |
1995 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 1997 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
1996 | * values from/to the user buffer, treated as an ASCII string. | 1998 | * values from/to the user buffer, treated as an ASCII string. |
diff --git a/kernel/time.c b/kernel/time.c index 96fd0f499631..d4335c1c884c 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -516,14 +516,6 @@ int do_settimeofday (struct timespec *tv) | |||
516 | 516 | ||
517 | write_seqlock_irq(&xtime_lock); | 517 | write_seqlock_irq(&xtime_lock); |
518 | { | 518 | { |
519 | /* | ||
520 | * This is revolting. We need to set "xtime" correctly. However, the value | ||
521 | * in this location is the value at the most recent update of wall time. | ||
522 | * Discover what correction gettimeofday would have done, and then undo | ||
523 | * it! | ||
524 | */ | ||
525 | nsec -= time_interpolator_get_offset(); | ||
526 | |||
527 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); | 519 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); |
528 | wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); | 520 | wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); |
529 | 521 | ||
diff --git a/kernel/timer.c b/kernel/timer.c index ecb3d67c0e14..207aa4f0aa10 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1007,7 +1007,7 @@ asmlinkage long sys_getppid(void) | |||
1007 | * Make sure we read the pid before re-reading the | 1007 | * Make sure we read the pid before re-reading the |
1008 | * parent pointer: | 1008 | * parent pointer: |
1009 | */ | 1009 | */ |
1010 | rmb(); | 1010 | smp_rmb(); |
1011 | parent = me->group_leader->real_parent; | 1011 | parent = me->group_leader->real_parent; |
1012 | if (old != parent) | 1012 | if (old != parent) |
1013 | continue; | 1013 | continue; |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 426a0cf7b11c..ac23847ce0e3 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -108,6 +108,7 @@ config DEBUG_HIGHMEM | |||
108 | 108 | ||
109 | config DEBUG_BUGVERBOSE | 109 | config DEBUG_BUGVERBOSE |
110 | bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED | 110 | bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED |
111 | depends on BUG | ||
111 | depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || (X86 && !X86_64) || FRV | 112 | depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || (X86 && !X86_64) || FRV |
112 | default !EMBEDDED | 113 | default !EMBEDDED |
113 | help | 114 | help |
diff --git a/lib/kobject.c b/lib/kobject.c index 5df8441c44e7..94048826624c 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -216,13 +216,12 @@ int kobject_register(struct kobject * kobj) | |||
216 | /** | 216 | /** |
217 | * kobject_set_name - Set the name of an object | 217 | * kobject_set_name - Set the name of an object |
218 | * @kobj: object. | 218 | * @kobj: object. |
219 | * @name: name. | 219 | * @fmt: format string used to build the name |
220 | * | 220 | * |
221 | * If strlen(name) >= KOBJ_NAME_LEN, then use a dynamically allocated | 221 | * If strlen(name) >= KOBJ_NAME_LEN, then use a dynamically allocated |
222 | * string that @kobj->k_name points to. Otherwise, use the static | 222 | * string that @kobj->k_name points to. Otherwise, use the static |
223 | * @kobj->name array. | 223 | * @kobj->name array. |
224 | */ | 224 | */ |
225 | |||
226 | int kobject_set_name(struct kobject * kobj, const char * fmt, ...) | 225 | int kobject_set_name(struct kobject * kobj, const char * fmt, ...) |
227 | { | 226 | { |
228 | int error = 0; | 227 | int error = 0; |
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c index 21f0db2c9711..40ffde940a86 100644 --- a/lib/rwsem-spinlock.c +++ b/lib/rwsem-spinlock.c | |||
@@ -76,7 +76,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite) | |||
76 | list_del(&waiter->list); | 76 | list_del(&waiter->list); |
77 | tsk = waiter->task; | 77 | tsk = waiter->task; |
78 | /* Don't touch waiter after ->task has been NULLed */ | 78 | /* Don't touch waiter after ->task has been NULLed */ |
79 | mb(); | 79 | smp_mb(); |
80 | waiter->task = NULL; | 80 | waiter->task = NULL; |
81 | wake_up_process(tsk); | 81 | wake_up_process(tsk); |
82 | put_task_struct(tsk); | 82 | put_task_struct(tsk); |
@@ -91,7 +91,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite) | |||
91 | 91 | ||
92 | list_del(&waiter->list); | 92 | list_del(&waiter->list); |
93 | tsk = waiter->task; | 93 | tsk = waiter->task; |
94 | mb(); | 94 | smp_mb(); |
95 | waiter->task = NULL; | 95 | waiter->task = NULL; |
96 | wake_up_process(tsk); | 96 | wake_up_process(tsk); |
97 | put_task_struct(tsk); | 97 | put_task_struct(tsk); |
@@ -123,7 +123,7 @@ __rwsem_wake_one_writer(struct rw_semaphore *sem) | |||
123 | list_del(&waiter->list); | 123 | list_del(&waiter->list); |
124 | 124 | ||
125 | tsk = waiter->task; | 125 | tsk = waiter->task; |
126 | mb(); | 126 | smp_mb(); |
127 | waiter->task = NULL; | 127 | waiter->task = NULL; |
128 | wake_up_process(tsk); | 128 | wake_up_process(tsk); |
129 | put_task_struct(tsk); | 129 | put_task_struct(tsk); |
diff --git a/lib/rwsem.c b/lib/rwsem.c index 7644089ec8fa..62fa4eba9ffe 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c | |||
@@ -74,7 +74,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) | |||
74 | */ | 74 | */ |
75 | list_del(&waiter->list); | 75 | list_del(&waiter->list); |
76 | tsk = waiter->task; | 76 | tsk = waiter->task; |
77 | mb(); | 77 | smp_mb(); |
78 | waiter->task = NULL; | 78 | waiter->task = NULL; |
79 | wake_up_process(tsk); | 79 | wake_up_process(tsk); |
80 | put_task_struct(tsk); | 80 | put_task_struct(tsk); |
@@ -117,7 +117,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) | |||
117 | waiter = list_entry(next, struct rwsem_waiter, list); | 117 | waiter = list_entry(next, struct rwsem_waiter, list); |
118 | next = waiter->list.next; | 118 | next = waiter->list.next; |
119 | tsk = waiter->task; | 119 | tsk = waiter->task; |
120 | mb(); | 120 | smp_mb(); |
121 | waiter->task = NULL; | 121 | waiter->task = NULL; |
122 | wake_up_process(tsk); | 122 | wake_up_process(tsk); |
123 | put_task_struct(tsk); | 123 | put_task_struct(tsk); |
diff --git a/mm/filemap.c b/mm/filemap.c index 93595c327bbd..d5fdae2eb183 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -123,8 +123,7 @@ void remove_from_page_cache(struct page *page) | |||
123 | { | 123 | { |
124 | struct address_space *mapping = page->mapping; | 124 | struct address_space *mapping = page->mapping; |
125 | 125 | ||
126 | if (unlikely(!PageLocked(page))) | 126 | BUG_ON(!PageLocked(page)); |
127 | PAGE_BUG(page); | ||
128 | 127 | ||
129 | write_lock_irq(&mapping->tree_lock); | 128 | write_lock_irq(&mapping->tree_lock); |
130 | __remove_from_page_cache(page); | 129 | __remove_from_page_cache(page); |
@@ -139,7 +138,25 @@ static int sync_page(void *word) | |||
139 | page = container_of((page_flags_t *)word, struct page, flags); | 138 | page = container_of((page_flags_t *)word, struct page, flags); |
140 | 139 | ||
141 | /* | 140 | /* |
142 | * FIXME, fercrissake. What is this barrier here for? | 141 | * page_mapping() is being called without PG_locked held. |
142 | * Some knowledge of the state and use of the page is used to | ||
143 | * reduce the requirements down to a memory barrier. | ||
144 | * The danger here is of a stale page_mapping() return value | ||
145 | * indicating a struct address_space different from the one it's | ||
146 | * associated with when it is associated with one. | ||
147 | * After smp_mb(), it's either the correct page_mapping() for | ||
148 | * the page, or an old page_mapping() and the page's own | ||
149 | * page_mapping() has gone NULL. | ||
150 | * The ->sync_page() address_space operation must tolerate | ||
151 | * page_mapping() going NULL. By an amazing coincidence, | ||
152 | * this comes about because none of the users of the page | ||
153 | * in the ->sync_page() methods make essential use of the | ||
154 | * page_mapping(), merely passing the page down to the backing | ||
155 | * device's unplug functions when it's non-NULL, which in turn | ||
156 | * ignore it for all cases but swap, where only page->private is | ||
157 | * of interest. When page_mapping() does go NULL, the entire | ||
158 | * call stack gracefully ignores the page and returns. | ||
159 | * -- wli | ||
143 | */ | 160 | */ |
144 | smp_mb(); | 161 | smp_mb(); |
145 | mapping = page_mapping(page); | 162 | mapping = page_mapping(page); |
@@ -152,9 +169,10 @@ static int sync_page(void *word) | |||
152 | /** | 169 | /** |
153 | * filemap_fdatawrite_range - start writeback against all of a mapping's | 170 | * filemap_fdatawrite_range - start writeback against all of a mapping's |
154 | * dirty pages that lie within the byte offsets <start, end> | 171 | * dirty pages that lie within the byte offsets <start, end> |
155 | * @mapping: address space structure to write | 172 | * @mapping: address space structure to write |
156 | * @start: offset in bytes where the range starts | 173 | * @start: offset in bytes where the range starts |
157 | * @end : offset in bytes where the range ends | 174 | * @end: offset in bytes where the range ends |
175 | * @sync_mode: enable synchronous operation | ||
158 | * | 176 | * |
159 | * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as | 177 | * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as |
160 | * opposed to a regular memory * cleansing writeback. The difference between | 178 | * opposed to a regular memory * cleansing writeback. The difference between |
@@ -518,8 +536,8 @@ EXPORT_SYMBOL(find_trylock_page); | |||
518 | /** | 536 | /** |
519 | * find_lock_page - locate, pin and lock a pagecache page | 537 | * find_lock_page - locate, pin and lock a pagecache page |
520 | * | 538 | * |
521 | * @mapping - the address_space to search | 539 | * @mapping: the address_space to search |
522 | * @offset - the page index | 540 | * @offset: the page index |
523 | * | 541 | * |
524 | * Locates the desired pagecache page, locks it, increments its reference | 542 | * Locates the desired pagecache page, locks it, increments its reference |
525 | * count and returns its address. | 543 | * count and returns its address. |
@@ -558,9 +576,9 @@ EXPORT_SYMBOL(find_lock_page); | |||
558 | /** | 576 | /** |
559 | * find_or_create_page - locate or add a pagecache page | 577 | * find_or_create_page - locate or add a pagecache page |
560 | * | 578 | * |
561 | * @mapping - the page's address_space | 579 | * @mapping: the page's address_space |
562 | * @index - the page's index into the mapping | 580 | * @index: the page's index into the mapping |
563 | * @gfp_mask - page allocation mode | 581 | * @gfp_mask: page allocation mode |
564 | * | 582 | * |
565 | * Locates a page in the pagecache. If the page is not present, a new page | 583 | * Locates a page in the pagecache. If the page is not present, a new page |
566 | * is allocated using @gfp_mask and is added to the pagecache and to the VM's | 584 | * is allocated using @gfp_mask and is added to the pagecache and to the VM's |
@@ -1949,7 +1967,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
1949 | buf = iov->iov_base + written; | 1967 | buf = iov->iov_base + written; |
1950 | else { | 1968 | else { |
1951 | filemap_set_next_iovec(&cur_iov, &iov_base, written); | 1969 | filemap_set_next_iovec(&cur_iov, &iov_base, written); |
1952 | buf = iov->iov_base + iov_base; | 1970 | buf = cur_iov->iov_base + iov_base; |
1953 | } | 1971 | } |
1954 | 1972 | ||
1955 | do { | 1973 | do { |
@@ -2007,9 +2025,11 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
2007 | count -= status; | 2025 | count -= status; |
2008 | pos += status; | 2026 | pos += status; |
2009 | buf += status; | 2027 | buf += status; |
2010 | if (unlikely(nr_segs > 1)) | 2028 | if (unlikely(nr_segs > 1)) { |
2011 | filemap_set_next_iovec(&cur_iov, | 2029 | filemap_set_next_iovec(&cur_iov, |
2012 | &iov_base, status); | 2030 | &iov_base, status); |
2031 | buf = cur_iov->iov_base + iov_base; | ||
2032 | } | ||
2013 | } | 2033 | } |
2014 | } | 2034 | } |
2015 | if (unlikely(copied != bytes)) | 2035 | if (unlikely(copied != bytes)) |
diff --git a/mm/highmem.c b/mm/highmem.c index d01276506b00..400911599468 100644 --- a/mm/highmem.c +++ b/mm/highmem.c | |||
@@ -325,6 +325,7 @@ static void bounce_end_io(struct bio *bio, mempool_t *pool, int err) | |||
325 | continue; | 325 | continue; |
326 | 326 | ||
327 | mempool_free(bvec->bv_page, pool); | 327 | mempool_free(bvec->bv_page, pool); |
328 | dec_page_state(nr_bounce); | ||
328 | } | 329 | } |
329 | 330 | ||
330 | bio_endio(bio_orig, bio_orig->bi_size, err); | 331 | bio_endio(bio_orig, bio_orig->bi_size, err); |
@@ -405,6 +406,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, | |||
405 | to->bv_page = mempool_alloc(pool, q->bounce_gfp); | 406 | to->bv_page = mempool_alloc(pool, q->bounce_gfp); |
406 | to->bv_len = from->bv_len; | 407 | to->bv_len = from->bv_len; |
407 | to->bv_offset = from->bv_offset; | 408 | to->bv_offset = from->bv_offset; |
409 | inc_page_state(nr_bounce); | ||
408 | 410 | ||
409 | if (rw == WRITE) { | 411 | if (rw == WRITE) { |
410 | char *vto, *vfrom; | 412 | char *vto, *vfrom; |
diff --git a/mm/mempool.c b/mm/mempool.c index b014ffeaa413..c9f3d4620428 100644 --- a/mm/mempool.c +++ b/mm/mempool.c | |||
@@ -198,31 +198,22 @@ void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask) | |||
198 | void *element; | 198 | void *element; |
199 | unsigned long flags; | 199 | unsigned long flags; |
200 | DEFINE_WAIT(wait); | 200 | DEFINE_WAIT(wait); |
201 | int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO); | 201 | int gfp_temp; |
202 | 202 | ||
203 | might_sleep_if(gfp_mask & __GFP_WAIT); | 203 | might_sleep_if(gfp_mask & __GFP_WAIT); |
204 | |||
205 | gfp_mask |= __GFP_NOMEMALLOC; /* don't allocate emergency reserves */ | ||
206 | gfp_mask |= __GFP_NORETRY; /* don't loop in __alloc_pages */ | ||
207 | gfp_mask |= __GFP_NOWARN; /* failures are OK */ | ||
208 | |||
209 | gfp_temp = gfp_mask & ~(__GFP_WAIT|__GFP_IO); | ||
210 | |||
204 | repeat_alloc: | 211 | repeat_alloc: |
205 | element = pool->alloc(gfp_nowait|__GFP_NOWARN, pool->pool_data); | 212 | |
213 | element = pool->alloc(gfp_temp, pool->pool_data); | ||
206 | if (likely(element != NULL)) | 214 | if (likely(element != NULL)) |
207 | return element; | 215 | return element; |
208 | 216 | ||
209 | /* | ||
210 | * If the pool is less than 50% full and we can perform effective | ||
211 | * page reclaim then try harder to allocate an element. | ||
212 | */ | ||
213 | mb(); | ||
214 | if ((gfp_mask & __GFP_FS) && (gfp_mask != gfp_nowait) && | ||
215 | (pool->curr_nr <= pool->min_nr/2)) { | ||
216 | element = pool->alloc(gfp_mask, pool->pool_data); | ||
217 | if (likely(element != NULL)) | ||
218 | return element; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * Kick the VM at this point. | ||
223 | */ | ||
224 | wakeup_bdflush(0); | ||
225 | |||
226 | spin_lock_irqsave(&pool->lock, flags); | 217 | spin_lock_irqsave(&pool->lock, flags); |
227 | if (likely(pool->curr_nr)) { | 218 | if (likely(pool->curr_nr)) { |
228 | element = remove_element(pool); | 219 | element = remove_element(pool); |
@@ -235,8 +226,10 @@ repeat_alloc: | |||
235 | if (!(gfp_mask & __GFP_WAIT)) | 226 | if (!(gfp_mask & __GFP_WAIT)) |
236 | return NULL; | 227 | return NULL; |
237 | 228 | ||
229 | /* Now start performing page reclaim */ | ||
230 | gfp_temp = gfp_mask; | ||
238 | prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE); | 231 | prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE); |
239 | mb(); | 232 | smp_mb(); |
240 | if (!pool->curr_nr) | 233 | if (!pool->curr_nr) |
241 | io_schedule(); | 234 | io_schedule(); |
242 | finish_wait(&pool->wait, &wait); | 235 | finish_wait(&pool->wait, &wait); |
@@ -257,7 +250,7 @@ void mempool_free(void *element, mempool_t *pool) | |||
257 | { | 250 | { |
258 | unsigned long flags; | 251 | unsigned long flags; |
259 | 252 | ||
260 | mb(); | 253 | smp_mb(); |
261 | if (pool->curr_nr < pool->min_nr) { | 254 | if (pool->curr_nr < pool->min_nr) { |
262 | spin_lock_irqsave(&pool->lock, flags); | 255 | spin_lock_irqsave(&pool->lock, flags); |
263 | if (pool->curr_nr < pool->min_nr) { | 256 | if (pool->curr_nr < pool->min_nr) { |
@@ -937,9 +937,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, | |||
937 | /* mlock MCL_FUTURE? */ | 937 | /* mlock MCL_FUTURE? */ |
938 | if (vm_flags & VM_LOCKED) { | 938 | if (vm_flags & VM_LOCKED) { |
939 | unsigned long locked, lock_limit; | 939 | unsigned long locked, lock_limit; |
940 | locked = mm->locked_vm << PAGE_SHIFT; | 940 | locked = len >> PAGE_SHIFT; |
941 | locked += mm->locked_vm; | ||
941 | lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; | 942 | lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; |
942 | locked += len; | 943 | lock_limit >>= PAGE_SHIFT; |
943 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) | 944 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
944 | return -EAGAIN; | 945 | return -EAGAIN; |
945 | } | 946 | } |
@@ -1009,8 +1010,7 @@ munmap_back: | |||
1009 | } | 1010 | } |
1010 | 1011 | ||
1011 | /* Check against address space limit. */ | 1012 | /* Check against address space limit. */ |
1012 | if ((mm->total_vm << PAGE_SHIFT) + len | 1013 | if (!may_expand_vm(mm, len >> PAGE_SHIFT)) |
1013 | > current->signal->rlim[RLIMIT_AS].rlim_cur) | ||
1014 | return -ENOMEM; | 1014 | return -ENOMEM; |
1015 | 1015 | ||
1016 | if (accountable && (!(flags & MAP_NORESERVE) || | 1016 | if (accountable && (!(flags & MAP_NORESERVE) || |
@@ -1421,7 +1421,7 @@ static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, un | |||
1421 | struct rlimit *rlim = current->signal->rlim; | 1421 | struct rlimit *rlim = current->signal->rlim; |
1422 | 1422 | ||
1423 | /* address space limit tests */ | 1423 | /* address space limit tests */ |
1424 | if (mm->total_vm + grow > rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT) | 1424 | if (!may_expand_vm(mm, grow)) |
1425 | return -ENOMEM; | 1425 | return -ENOMEM; |
1426 | 1426 | ||
1427 | /* Stack limit test */ | 1427 | /* Stack limit test */ |
@@ -1823,9 +1823,10 @@ unsigned long do_brk(unsigned long addr, unsigned long len) | |||
1823 | */ | 1823 | */ |
1824 | if (mm->def_flags & VM_LOCKED) { | 1824 | if (mm->def_flags & VM_LOCKED) { |
1825 | unsigned long locked, lock_limit; | 1825 | unsigned long locked, lock_limit; |
1826 | locked = mm->locked_vm << PAGE_SHIFT; | 1826 | locked = len >> PAGE_SHIFT; |
1827 | locked += mm->locked_vm; | ||
1827 | lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; | 1828 | lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; |
1828 | locked += len; | 1829 | lock_limit >>= PAGE_SHIFT; |
1829 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) | 1830 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
1830 | return -EAGAIN; | 1831 | return -EAGAIN; |
1831 | } | 1832 | } |
@@ -1848,8 +1849,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) | |||
1848 | } | 1849 | } |
1849 | 1850 | ||
1850 | /* Check against address space limits *after* clearing old maps... */ | 1851 | /* Check against address space limits *after* clearing old maps... */ |
1851 | if ((mm->total_vm << PAGE_SHIFT) + len | 1852 | if (!may_expand_vm(mm, len >> PAGE_SHIFT)) |
1852 | > current->signal->rlim[RLIMIT_AS].rlim_cur) | ||
1853 | return -ENOMEM; | 1853 | return -ENOMEM; |
1854 | 1854 | ||
1855 | if (mm->map_count > sysctl_max_map_count) | 1855 | if (mm->map_count > sysctl_max_map_count) |
@@ -2019,3 +2019,19 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, | |||
2019 | } | 2019 | } |
2020 | return new_vma; | 2020 | return new_vma; |
2021 | } | 2021 | } |
2022 | |||
2023 | /* | ||
2024 | * Return true if the calling process may expand its vm space by the passed | ||
2025 | * number of pages | ||
2026 | */ | ||
2027 | int may_expand_vm(struct mm_struct *mm, unsigned long npages) | ||
2028 | { | ||
2029 | unsigned long cur = mm->total_vm; /* pages */ | ||
2030 | unsigned long lim; | ||
2031 | |||
2032 | lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; | ||
2033 | |||
2034 | if (cur + npages > lim) | ||
2035 | return 0; | ||
2036 | return 1; | ||
2037 | } | ||
diff --git a/mm/mremap.c b/mm/mremap.c index 0d1c1b9c7a0a..0dd7ace94e51 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -347,10 +347,10 @@ unsigned long do_mremap(unsigned long addr, | |||
347 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) | 347 | if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
348 | goto out; | 348 | goto out; |
349 | } | 349 | } |
350 | ret = -ENOMEM; | 350 | if (!may_expand_vm(current->mm, (new_len - old_len) >> PAGE_SHIFT)) { |
351 | if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len) | 351 | ret = -ENOMEM; |
352 | > current->signal->rlim[RLIMIT_AS].rlim_cur) | ||
353 | goto out; | 352 | goto out; |
353 | } | ||
354 | 354 | ||
355 | if (vma->vm_flags & VM_ACCOUNT) { | 355 | if (vma->vm_flags & VM_ACCOUNT) { |
356 | charged = (new_len - old_len) >> PAGE_SHIFT; | 356 | charged = (new_len - old_len) >> PAGE_SHIFT; |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 6ddd6a29c73b..613b99a55917 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -255,7 +255,7 @@ static void balance_dirty_pages(struct address_space *mapping) | |||
255 | 255 | ||
256 | /** | 256 | /** |
257 | * balance_dirty_pages_ratelimited - balance dirty memory state | 257 | * balance_dirty_pages_ratelimited - balance dirty memory state |
258 | * @mapping - address_space which was dirtied | 258 | * @mapping: address_space which was dirtied |
259 | * | 259 | * |
260 | * Processes which are dirtying memory should call in here once for each page | 260 | * Processes which are dirtying memory should call in here once for each page |
261 | * which was newly dirtied. The function will periodically check the system's | 261 | * which was newly dirtied. The function will periodically check the system's |
@@ -562,8 +562,8 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
562 | /** | 562 | /** |
563 | * write_one_page - write out a single page and optionally wait on I/O | 563 | * write_one_page - write out a single page and optionally wait on I/O |
564 | * | 564 | * |
565 | * @page - the page to write | 565 | * @page: the page to write |
566 | * @wait - if true, wait on writeout | 566 | * @wait: if true, wait on writeout |
567 | * | 567 | * |
568 | * The page must be locked by the caller and will be unlocked upon return. | 568 | * The page must be locked by the caller and will be unlocked upon return. |
569 | * | 569 | * |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c73dbbc1cd8f..fc1b1064c505 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -799,14 +799,18 @@ __alloc_pages(unsigned int __nocast gfp_mask, unsigned int order, | |||
799 | } | 799 | } |
800 | 800 | ||
801 | /* This allocation should allow future memory freeing. */ | 801 | /* This allocation should allow future memory freeing. */ |
802 | if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) && !in_interrupt()) { | 802 | |
803 | /* go through the zonelist yet again, ignoring mins */ | 803 | if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) |
804 | for (i = 0; (z = zones[i]) != NULL; i++) { | 804 | && !in_interrupt()) { |
805 | if (!cpuset_zone_allowed(z)) | 805 | if (!(gfp_mask & __GFP_NOMEMALLOC)) { |
806 | continue; | 806 | /* go through the zonelist yet again, ignoring mins */ |
807 | page = buffered_rmqueue(z, order, gfp_mask); | 807 | for (i = 0; (z = zones[i]) != NULL; i++) { |
808 | if (page) | 808 | if (!cpuset_zone_allowed(z)) |
809 | goto got_pg; | 809 | continue; |
810 | page = buffered_rmqueue(z, order, gfp_mask); | ||
811 | if (page) | ||
812 | goto got_pg; | ||
813 | } | ||
810 | } | 814 | } |
811 | goto nopage; | 815 | goto nopage; |
812 | } | 816 | } |
@@ -1351,8 +1355,7 @@ static int __init build_zonelists_node(pg_data_t *pgdat, struct zonelist *zoneli | |||
1351 | #define MAX_NODE_LOAD (num_online_nodes()) | 1355 | #define MAX_NODE_LOAD (num_online_nodes()) |
1352 | static int __initdata node_load[MAX_NUMNODES]; | 1356 | static int __initdata node_load[MAX_NUMNODES]; |
1353 | /** | 1357 | /** |
1354 | * find_next_best_node - find the next node that should appear in a given | 1358 | * find_next_best_node - find the next node that should appear in a given node's fallback list |
1355 | * node's fallback list | ||
1356 | * @node: node whose fallback list we're appending | 1359 | * @node: node whose fallback list we're appending |
1357 | * @used_node_mask: nodemask_t of already used nodes | 1360 | * @used_node_mask: nodemask_t of already used nodes |
1358 | * | 1361 | * |
@@ -1671,6 +1674,18 @@ static void __init free_area_init_core(struct pglist_data *pgdat, | |||
1671 | if (batch < 1) | 1674 | if (batch < 1) |
1672 | batch = 1; | 1675 | batch = 1; |
1673 | 1676 | ||
1677 | /* | ||
1678 | * Clamp the batch to a 2^n - 1 value. Having a power | ||
1679 | * of 2 value was found to be more likely to have | ||
1680 | * suboptimal cache aliasing properties in some cases. | ||
1681 | * | ||
1682 | * For example if 2 tasks are alternately allocating | ||
1683 | * batches of pages, one task can end up with a lot | ||
1684 | * of pages of one half of the possible page colors | ||
1685 | * and the other with pages of the other colors. | ||
1686 | */ | ||
1687 | batch = (1 << fls(batch + batch/2)) - 1; | ||
1688 | |||
1674 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 1689 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
1675 | struct per_cpu_pages *pcp; | 1690 | struct per_cpu_pages *pcp; |
1676 | 1691 | ||
@@ -1881,6 +1896,7 @@ static char *vmstat_text[] = { | |||
1881 | "allocstall", | 1896 | "allocstall", |
1882 | 1897 | ||
1883 | "pgrotated", | 1898 | "pgrotated", |
1899 | "nr_bounce", | ||
1884 | }; | 1900 | }; |
1885 | 1901 | ||
1886 | static void *vmstat_start(struct seq_file *m, loff_t *pos) | 1902 | static void *vmstat_start(struct seq_file *m, loff_t *pos) |
@@ -243,6 +243,42 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | /* | 245 | /* |
246 | * Check that @page is mapped at @address into @mm. | ||
247 | * | ||
248 | * On success returns with mapped pte and locked mm->page_table_lock. | ||
249 | */ | ||
250 | static pte_t *page_check_address(struct page *page, struct mm_struct *mm, | ||
251 | unsigned long address) | ||
252 | { | ||
253 | pgd_t *pgd; | ||
254 | pud_t *pud; | ||
255 | pmd_t *pmd; | ||
256 | pte_t *pte; | ||
257 | |||
258 | /* | ||
259 | * We need the page_table_lock to protect us from page faults, | ||
260 | * munmap, fork, etc... | ||
261 | */ | ||
262 | spin_lock(&mm->page_table_lock); | ||
263 | pgd = pgd_offset(mm, address); | ||
264 | if (likely(pgd_present(*pgd))) { | ||
265 | pud = pud_offset(pgd, address); | ||
266 | if (likely(pud_present(*pud))) { | ||
267 | pmd = pmd_offset(pud, address); | ||
268 | if (likely(pmd_present(*pmd))) { | ||
269 | pte = pte_offset_map(pmd, address); | ||
270 | if (likely(pte_present(*pte) && | ||
271 | page_to_pfn(page) == pte_pfn(*pte))) | ||
272 | return pte; | ||
273 | pte_unmap(pte); | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | spin_unlock(&mm->page_table_lock); | ||
278 | return ERR_PTR(-ENOENT); | ||
279 | } | ||
280 | |||
281 | /* | ||
246 | * Subfunctions of page_referenced: page_referenced_one called | 282 | * Subfunctions of page_referenced: page_referenced_one called |
247 | * repeatedly from either page_referenced_anon or page_referenced_file. | 283 | * repeatedly from either page_referenced_anon or page_referenced_file. |
248 | */ | 284 | */ |
@@ -251,9 +287,6 @@ static int page_referenced_one(struct page *page, | |||
251 | { | 287 | { |
252 | struct mm_struct *mm = vma->vm_mm; | 288 | struct mm_struct *mm = vma->vm_mm; |
253 | unsigned long address; | 289 | unsigned long address; |
254 | pgd_t *pgd; | ||
255 | pud_t *pud; | ||
256 | pmd_t *pmd; | ||
257 | pte_t *pte; | 290 | pte_t *pte; |
258 | int referenced = 0; | 291 | int referenced = 0; |
259 | 292 | ||
@@ -263,39 +296,18 @@ static int page_referenced_one(struct page *page, | |||
263 | if (address == -EFAULT) | 296 | if (address == -EFAULT) |
264 | goto out; | 297 | goto out; |
265 | 298 | ||
266 | spin_lock(&mm->page_table_lock); | 299 | pte = page_check_address(page, mm, address); |
267 | 300 | if (!IS_ERR(pte)) { | |
268 | pgd = pgd_offset(mm, address); | 301 | if (ptep_clear_flush_young(vma, address, pte)) |
269 | if (!pgd_present(*pgd)) | 302 | referenced++; |
270 | goto out_unlock; | ||
271 | |||
272 | pud = pud_offset(pgd, address); | ||
273 | if (!pud_present(*pud)) | ||
274 | goto out_unlock; | ||
275 | |||
276 | pmd = pmd_offset(pud, address); | ||
277 | if (!pmd_present(*pmd)) | ||
278 | goto out_unlock; | ||
279 | |||
280 | pte = pte_offset_map(pmd, address); | ||
281 | if (!pte_present(*pte)) | ||
282 | goto out_unmap; | ||
283 | |||
284 | if (page_to_pfn(page) != pte_pfn(*pte)) | ||
285 | goto out_unmap; | ||
286 | |||
287 | if (ptep_clear_flush_young(vma, address, pte)) | ||
288 | referenced++; | ||
289 | |||
290 | if (mm != current->mm && !ignore_token && has_swap_token(mm)) | ||
291 | referenced++; | ||
292 | 303 | ||
293 | (*mapcount)--; | 304 | if (mm != current->mm && !ignore_token && has_swap_token(mm)) |
305 | referenced++; | ||
294 | 306 | ||
295 | out_unmap: | 307 | (*mapcount)--; |
296 | pte_unmap(pte); | 308 | pte_unmap(pte); |
297 | out_unlock: | 309 | spin_unlock(&mm->page_table_lock); |
298 | spin_unlock(&mm->page_table_lock); | 310 | } |
299 | out: | 311 | out: |
300 | return referenced; | 312 | return referenced; |
301 | } | 313 | } |
@@ -502,9 +514,6 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) | |||
502 | { | 514 | { |
503 | struct mm_struct *mm = vma->vm_mm; | 515 | struct mm_struct *mm = vma->vm_mm; |
504 | unsigned long address; | 516 | unsigned long address; |
505 | pgd_t *pgd; | ||
506 | pud_t *pud; | ||
507 | pmd_t *pmd; | ||
508 | pte_t *pte; | 517 | pte_t *pte; |
509 | pte_t pteval; | 518 | pte_t pteval; |
510 | int ret = SWAP_AGAIN; | 519 | int ret = SWAP_AGAIN; |
@@ -515,30 +524,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) | |||
515 | if (address == -EFAULT) | 524 | if (address == -EFAULT) |
516 | goto out; | 525 | goto out; |
517 | 526 | ||
518 | /* | 527 | pte = page_check_address(page, mm, address); |
519 | * We need the page_table_lock to protect us from page faults, | 528 | if (IS_ERR(pte)) |
520 | * munmap, fork, etc... | 529 | goto out; |
521 | */ | ||
522 | spin_lock(&mm->page_table_lock); | ||
523 | |||
524 | pgd = pgd_offset(mm, address); | ||
525 | if (!pgd_present(*pgd)) | ||
526 | goto out_unlock; | ||
527 | |||
528 | pud = pud_offset(pgd, address); | ||
529 | if (!pud_present(*pud)) | ||
530 | goto out_unlock; | ||
531 | |||
532 | pmd = pmd_offset(pud, address); | ||
533 | if (!pmd_present(*pmd)) | ||
534 | goto out_unlock; | ||
535 | |||
536 | pte = pte_offset_map(pmd, address); | ||
537 | if (!pte_present(*pte)) | ||
538 | goto out_unmap; | ||
539 | |||
540 | if (page_to_pfn(page) != pte_pfn(*pte)) | ||
541 | goto out_unmap; | ||
542 | 530 | ||
543 | /* | 531 | /* |
544 | * If the page is mlock()d, we cannot swap it out. | 532 | * If the page is mlock()d, we cannot swap it out. |
@@ -604,7 +592,6 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) | |||
604 | 592 | ||
605 | out_unmap: | 593 | out_unmap: |
606 | pte_unmap(pte); | 594 | pte_unmap(pte); |
607 | out_unlock: | ||
608 | spin_unlock(&mm->page_table_lock); | 595 | spin_unlock(&mm->page_table_lock); |
609 | out: | 596 | out: |
610 | return ret; | 597 | return ret; |
@@ -708,7 +695,6 @@ static void try_to_unmap_cluster(unsigned long cursor, | |||
708 | } | 695 | } |
709 | 696 | ||
710 | pte_unmap(pte); | 697 | pte_unmap(pte); |
711 | |||
712 | out_unlock: | 698 | out_unlock: |
713 | spin_unlock(&mm->page_table_lock); | 699 | spin_unlock(&mm->page_table_lock); |
714 | } | 700 | } |
@@ -860,3 +846,4 @@ int try_to_unmap(struct page *page) | |||
860 | ret = SWAP_SUCCESS; | 846 | ret = SWAP_SUCCESS; |
861 | return ret; | 847 | return ret; |
862 | } | 848 | } |
849 | |||
@@ -583,7 +583,7 @@ static inline struct array_cache *ac_data(kmem_cache_t *cachep) | |||
583 | return cachep->array[smp_processor_id()]; | 583 | return cachep->array[smp_processor_id()]; |
584 | } | 584 | } |
585 | 585 | ||
586 | static inline kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags) | 586 | static inline kmem_cache_t *__find_general_cachep(size_t size, int gfpflags) |
587 | { | 587 | { |
588 | struct cache_sizes *csizep = malloc_sizes; | 588 | struct cache_sizes *csizep = malloc_sizes; |
589 | 589 | ||
@@ -607,6 +607,12 @@ static inline kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags) | |||
607 | return csizep->cs_cachep; | 607 | return csizep->cs_cachep; |
608 | } | 608 | } |
609 | 609 | ||
610 | kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags) | ||
611 | { | ||
612 | return __find_general_cachep(size, gfpflags); | ||
613 | } | ||
614 | EXPORT_SYMBOL(kmem_find_general_cachep); | ||
615 | |||
610 | /* Cal the num objs, wastage, and bytes left over for a given slab size. */ | 616 | /* Cal the num objs, wastage, and bytes left over for a given slab size. */ |
611 | static void cache_estimate(unsigned long gfporder, size_t size, size_t align, | 617 | static void cache_estimate(unsigned long gfporder, size_t size, size_t align, |
612 | int flags, size_t *left_over, unsigned int *num) | 618 | int flags, size_t *left_over, unsigned int *num) |
@@ -672,14 +678,11 @@ static struct array_cache *alloc_arraycache(int cpu, int entries, | |||
672 | int memsize = sizeof(void*)*entries+sizeof(struct array_cache); | 678 | int memsize = sizeof(void*)*entries+sizeof(struct array_cache); |
673 | struct array_cache *nc = NULL; | 679 | struct array_cache *nc = NULL; |
674 | 680 | ||
675 | if (cpu != -1) { | 681 | if (cpu == -1) |
676 | kmem_cache_t *cachep; | ||
677 | cachep = kmem_find_general_cachep(memsize, GFP_KERNEL); | ||
678 | if (cachep) | ||
679 | nc = kmem_cache_alloc_node(cachep, cpu_to_node(cpu)); | ||
680 | } | ||
681 | if (!nc) | ||
682 | nc = kmalloc(memsize, GFP_KERNEL); | 682 | nc = kmalloc(memsize, GFP_KERNEL); |
683 | else | ||
684 | nc = kmalloc_node(memsize, GFP_KERNEL, cpu_to_node(cpu)); | ||
685 | |||
683 | if (nc) { | 686 | if (nc) { |
684 | nc->avail = 0; | 687 | nc->avail = 0; |
685 | nc->limit = entries; | 688 | nc->limit = entries; |
@@ -1663,7 +1666,7 @@ int kmem_cache_destroy(kmem_cache_t * cachep) | |||
1663 | } | 1666 | } |
1664 | 1667 | ||
1665 | if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) | 1668 | if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) |
1666 | synchronize_kernel(); | 1669 | synchronize_rcu(); |
1667 | 1670 | ||
1668 | /* no cpu_online check required here since we clear the percpu | 1671 | /* no cpu_online check required here since we clear the percpu |
1669 | * array on cpu offline and set this to NULL. | 1672 | * array on cpu offline and set this to NULL. |
@@ -2361,7 +2364,7 @@ out: | |||
2361 | * and can sleep. And it will allocate memory on the given node, which | 2364 | * and can sleep. And it will allocate memory on the given node, which |
2362 | * can improve the performance for cpu bound structures. | 2365 | * can improve the performance for cpu bound structures. |
2363 | */ | 2366 | */ |
2364 | void *kmem_cache_alloc_node(kmem_cache_t *cachep, int nodeid) | 2367 | void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid) |
2365 | { | 2368 | { |
2366 | int loop; | 2369 | int loop; |
2367 | void *objp; | 2370 | void *objp; |
@@ -2393,7 +2396,7 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, int nodeid) | |||
2393 | spin_unlock_irq(&cachep->spinlock); | 2396 | spin_unlock_irq(&cachep->spinlock); |
2394 | 2397 | ||
2395 | local_irq_disable(); | 2398 | local_irq_disable(); |
2396 | if (!cache_grow(cachep, GFP_KERNEL, nodeid)) { | 2399 | if (!cache_grow(cachep, flags, nodeid)) { |
2397 | local_irq_enable(); | 2400 | local_irq_enable(); |
2398 | return NULL; | 2401 | return NULL; |
2399 | } | 2402 | } |
@@ -2435,6 +2438,16 @@ got_slabp: | |||
2435 | } | 2438 | } |
2436 | EXPORT_SYMBOL(kmem_cache_alloc_node); | 2439 | EXPORT_SYMBOL(kmem_cache_alloc_node); |
2437 | 2440 | ||
2441 | void *kmalloc_node(size_t size, int flags, int node) | ||
2442 | { | ||
2443 | kmem_cache_t *cachep; | ||
2444 | |||
2445 | cachep = kmem_find_general_cachep(size, flags); | ||
2446 | if (unlikely(cachep == NULL)) | ||
2447 | return NULL; | ||
2448 | return kmem_cache_alloc_node(cachep, flags, node); | ||
2449 | } | ||
2450 | EXPORT_SYMBOL(kmalloc_node); | ||
2438 | #endif | 2451 | #endif |
2439 | 2452 | ||
2440 | /** | 2453 | /** |
@@ -2462,7 +2475,12 @@ void *__kmalloc(size_t size, unsigned int __nocast flags) | |||
2462 | { | 2475 | { |
2463 | kmem_cache_t *cachep; | 2476 | kmem_cache_t *cachep; |
2464 | 2477 | ||
2465 | cachep = kmem_find_general_cachep(size, flags); | 2478 | /* If you want to save a few bytes .text space: replace |
2479 | * __ with kmem_. | ||
2480 | * Then kmalloc uses the uninlined functions instead of the inline | ||
2481 | * functions. | ||
2482 | */ | ||
2483 | cachep = __find_general_cachep(size, flags); | ||
2466 | if (unlikely(cachep == NULL)) | 2484 | if (unlikely(cachep == NULL)) |
2467 | return NULL; | 2485 | return NULL; |
2468 | return __cache_alloc(cachep, flags); | 2486 | return __cache_alloc(cachep, flags); |
@@ -2489,9 +2507,8 @@ void *__alloc_percpu(size_t size, size_t align) | |||
2489 | for (i = 0; i < NR_CPUS; i++) { | 2507 | for (i = 0; i < NR_CPUS; i++) { |
2490 | if (!cpu_possible(i)) | 2508 | if (!cpu_possible(i)) |
2491 | continue; | 2509 | continue; |
2492 | pdata->ptrs[i] = kmem_cache_alloc_node( | 2510 | pdata->ptrs[i] = kmalloc_node(size, GFP_KERNEL, |
2493 | kmem_find_general_cachep(size, GFP_KERNEL), | 2511 | cpu_to_node(i)); |
2494 | cpu_to_node(i)); | ||
2495 | 2512 | ||
2496 | if (!pdata->ptrs[i]) | 2513 | if (!pdata->ptrs[i]) |
2497 | goto unwind_oom; | 2514 | goto unwind_oom; |
diff --git a/mm/swap_state.c b/mm/swap_state.c index a063a902ed03..4f251775ef90 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c | |||
@@ -143,7 +143,6 @@ void __delete_from_swap_cache(struct page *page) | |||
143 | int add_to_swap(struct page * page) | 143 | int add_to_swap(struct page * page) |
144 | { | 144 | { |
145 | swp_entry_t entry; | 145 | swp_entry_t entry; |
146 | int pf_flags; | ||
147 | int err; | 146 | int err; |
148 | 147 | ||
149 | if (!PageLocked(page)) | 148 | if (!PageLocked(page)) |
@@ -154,29 +153,19 @@ int add_to_swap(struct page * page) | |||
154 | if (!entry.val) | 153 | if (!entry.val) |
155 | return 0; | 154 | return 0; |
156 | 155 | ||
157 | /* Radix-tree node allocations are performing | 156 | /* |
158 | * GFP_ATOMIC allocations under PF_MEMALLOC. | 157 | * Radix-tree node allocations from PF_MEMALLOC contexts could |
159 | * They can completely exhaust the page allocator. | 158 | * completely exhaust the page allocator. __GFP_NOMEMALLOC |
160 | * | 159 | * stops emergency reserves from being allocated. |
161 | * So PF_MEMALLOC is dropped here. This causes the slab | ||
162 | * allocations to fail earlier, so radix-tree nodes will | ||
163 | * then be allocated from the mempool reserves. | ||
164 | * | 160 | * |
165 | * We're still using __GFP_HIGH for radix-tree node | 161 | * TODO: this could cause a theoretical memory reclaim |
166 | * allocations, so some of the emergency pools are available, | 162 | * deadlock in the swap out path. |
167 | * just not all of them. | ||
168 | */ | 163 | */ |
169 | |||
170 | pf_flags = current->flags; | ||
171 | current->flags &= ~PF_MEMALLOC; | ||
172 | |||
173 | /* | 164 | /* |
174 | * Add it to the swap cache and mark it dirty | 165 | * Add it to the swap cache and mark it dirty |
175 | */ | 166 | */ |
176 | err = __add_to_swap_cache(page, entry, GFP_ATOMIC|__GFP_NOWARN); | 167 | err = __add_to_swap_cache(page, entry, |
177 | 168 | GFP_ATOMIC|__GFP_NOMEMALLOC|__GFP_NOWARN); | |
178 | if (pf_flags & PF_MEMALLOC) | ||
179 | current->flags |= PF_MEMALLOC; | ||
180 | 169 | ||
181 | switch (err) { | 170 | switch (err) { |
182 | case 0: /* Success */ | 171 | case 0: /* Success */ |
diff --git a/mm/truncate.c b/mm/truncate.c index c9a63f0b69a2..60c8764bfac2 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -242,7 +242,7 @@ EXPORT_SYMBOL(invalidate_inode_pages); | |||
242 | 242 | ||
243 | /** | 243 | /** |
244 | * invalidate_inode_pages2_range - remove range of pages from an address_space | 244 | * invalidate_inode_pages2_range - remove range of pages from an address_space |
245 | * @mapping - the address_space | 245 | * @mapping: the address_space |
246 | * @start: the page offset 'from' which to invalidate | 246 | * @start: the page offset 'from' which to invalidate |
247 | * @end: the page offset 'to' which to invalidate (inclusive) | 247 | * @end: the page offset 'to' which to invalidate (inclusive) |
248 | * | 248 | * |
@@ -322,7 +322,7 @@ EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range); | |||
322 | 322 | ||
323 | /** | 323 | /** |
324 | * invalidate_inode_pages2 - remove all pages from an address_space | 324 | * invalidate_inode_pages2 - remove all pages from an address_space |
325 | * @mapping - the address_space | 325 | * @mapping: the address_space |
326 | * | 326 | * |
327 | * Any pages which are found to be mapped into pagetables are unmapped prior to | 327 | * Any pages which are found to be mapped into pagetables are unmapped prior to |
328 | * invalidation. | 328 | * invalidation. |
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index c6182f6f1305..2bd83e5c2bbf 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -475,6 +475,10 @@ void *vmalloc(unsigned long size) | |||
475 | 475 | ||
476 | EXPORT_SYMBOL(vmalloc); | 476 | EXPORT_SYMBOL(vmalloc); |
477 | 477 | ||
478 | #ifndef PAGE_KERNEL_EXEC | ||
479 | # define PAGE_KERNEL_EXEC PAGE_KERNEL | ||
480 | #endif | ||
481 | |||
478 | /** | 482 | /** |
479 | * vmalloc_exec - allocate virtually contiguous, executable memory | 483 | * vmalloc_exec - allocate virtually contiguous, executable memory |
480 | * | 484 | * |
@@ -488,10 +492,6 @@ EXPORT_SYMBOL(vmalloc); | |||
488 | * use __vmalloc() instead. | 492 | * use __vmalloc() instead. |
489 | */ | 493 | */ |
490 | 494 | ||
491 | #ifndef PAGE_KERNEL_EXEC | ||
492 | # define PAGE_KERNEL_EXEC PAGE_KERNEL | ||
493 | #endif | ||
494 | |||
495 | void *vmalloc_exec(unsigned long size) | 495 | void *vmalloc_exec(unsigned long size) |
496 | { | 496 | { |
497 | return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC); | 497 | return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC); |
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index c32d27af0a3f..7b214cffc956 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/errno.h> /* return codes */ | 23 | #include <linux/errno.h> /* return codes */ |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/slab.h> /* kmalloc(), kfree() */ | 25 | #include <linux/slab.h> /* kmalloc(), kfree() */ |
26 | #include <linux/mm.h> /* verify_area(), etc. */ | 26 | #include <linux/mm.h> |
27 | #include <linux/string.h> /* inline mem*, str* functions */ | 27 | #include <linux/string.h> /* inline mem*, str* functions */ |
28 | #include <linux/init.h> /* __initfunc et al. */ | 28 | #include <linux/init.h> /* __initfunc et al. */ |
29 | #include <asm/byteorder.h> /* htons(), etc. */ | 29 | #include <asm/byteorder.h> /* htons(), etc. */ |
diff --git a/net/atm/common.c b/net/atm/common.c index 6d16be334ea0..e93e838069e8 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/socket.h> /* SOL_SOCKET */ | 12 | #include <linux/socket.h> /* SOL_SOCKET */ |
13 | #include <linux/errno.h> /* error codes */ | 13 | #include <linux/errno.h> /* error codes */ |
14 | #include <linux/capability.h> | 14 | #include <linux/capability.h> |
15 | #include <linux/mm.h> /* verify_area */ | 15 | #include <linux/mm.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/time.h> /* struct timeval */ | 17 | #include <linux/time.h> /* struct timeval */ |
18 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
@@ -540,7 +540,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
540 | error = -EMSGSIZE; | 540 | error = -EMSGSIZE; |
541 | goto out; | 541 | goto out; |
542 | } | 542 | } |
543 | /* verify_area is done by net/socket.c */ | 543 | |
544 | eff = (size+3) & ~3; /* align to word boundary */ | 544 | eff = (size+3) & ~3; /* align to word boundary */ |
545 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 545 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
546 | error = 0; | 546 | error = 0; |
diff --git a/net/core/datagram.c b/net/core/datagram.c index d1bfd279cc1a..fcee054b6f75 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -115,10 +115,10 @@ out_noerr: | |||
115 | 115 | ||
116 | /** | 116 | /** |
117 | * skb_recv_datagram - Receive a datagram skbuff | 117 | * skb_recv_datagram - Receive a datagram skbuff |
118 | * @sk - socket | 118 | * @sk: socket |
119 | * @flags - MSG_ flags | 119 | * @flags: MSG_ flags |
120 | * @noblock - blocking operation? | 120 | * @noblock: blocking operation? |
121 | * @err - error code returned | 121 | * @err: error code returned |
122 | * | 122 | * |
123 | * Get a datagram skbuff, understands the peeking, nonblocking wakeups | 123 | * Get a datagram skbuff, understands the peeking, nonblocking wakeups |
124 | * and possible races. This replaces identical code in packet, raw and | 124 | * and possible races. This replaces identical code in packet, raw and |
@@ -201,10 +201,10 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb) | |||
201 | 201 | ||
202 | /** | 202 | /** |
203 | * skb_copy_datagram_iovec - Copy a datagram to an iovec. | 203 | * skb_copy_datagram_iovec - Copy a datagram to an iovec. |
204 | * @skb - buffer to copy | 204 | * @skb: buffer to copy |
205 | * @offset - offset in the buffer to start copying from | 205 | * @offset: offset in the buffer to start copying from |
206 | * @iovec - io vector to copy to | 206 | * @to: io vector to copy to |
207 | * @len - amount of data to copy from buffer to iovec | 207 | * @len: amount of data to copy from buffer to iovec |
208 | * | 208 | * |
209 | * Note: the iovec is modified during the copy. | 209 | * Note: the iovec is modified during the copy. |
210 | */ | 210 | */ |
@@ -377,9 +377,9 @@ fault: | |||
377 | 377 | ||
378 | /** | 378 | /** |
379 | * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec. | 379 | * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec. |
380 | * @skb - skbuff | 380 | * @skb: skbuff |
381 | * @hlen - hardware length | 381 | * @hlen: hardware length |
382 | * @iovec - io vector | 382 | * @iov: io vector |
383 | * | 383 | * |
384 | * Caller _must_ check that skb will fit to this iovec. | 384 | * Caller _must_ check that skb will fit to this iovec. |
385 | * | 385 | * |
@@ -425,9 +425,9 @@ fault: | |||
425 | 425 | ||
426 | /** | 426 | /** |
427 | * datagram_poll - generic datagram poll | 427 | * datagram_poll - generic datagram poll |
428 | * @file - file struct | 428 | * @file: file struct |
429 | * @sock - socket | 429 | * @sock: socket |
430 | * @wait - poll table | 430 | * @wait: poll table |
431 | * | 431 | * |
432 | * Datagram poll: Again totally generic. This also handles | 432 | * Datagram poll: Again totally generic. This also handles |
433 | * sequenced packet sockets providing the socket receive queue | 433 | * sequenced packet sockets providing the socket receive queue |
diff --git a/net/core/dev.c b/net/core/dev.c index 7bd4cd4502c4..f5f005846fe1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3091,7 +3091,7 @@ void free_netdev(struct net_device *dev) | |||
3091 | void synchronize_net(void) | 3091 | void synchronize_net(void) |
3092 | { | 3092 | { |
3093 | might_sleep(); | 3093 | might_sleep(); |
3094 | synchronize_kernel(); | 3094 | synchronize_rcu(); |
3095 | } | 3095 | } |
3096 | 3096 | ||
3097 | /** | 3097 | /** |
diff --git a/net/core/iovec.c b/net/core/iovec.c index d57ace949ab8..65e4b56fbc77 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * Verify iovec. The caller must ensure that the iovec is big enough | 33 | * Verify iovec. The caller must ensure that the iovec is big enough |
34 | * to hold the message iovec. | 34 | * to hold the message iovec. |
35 | * | 35 | * |
36 | * Save time not doing verify_area. copy_*_user will make this work | 36 | * Save time not doing access_ok. copy_*_user will make this work |
37 | * in any case. | 37 | * in any case. |
38 | */ | 38 | */ |
39 | 39 | ||
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index 4859b7446c6f..d43d1201275c 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
17 | #include <linux/if.h> | 17 | #include <linux/if.h> |
18 | #include <net/sock.h> | 18 | #include <net/sock.h> |
19 | #include <net/pkt_sched.h> | ||
19 | #include <linux/rtnetlink.h> | 20 | #include <linux/rtnetlink.h> |
20 | #include <linux/jiffies.h> | 21 | #include <linux/jiffies.h> |
21 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
@@ -74,6 +75,12 @@ void linkwatch_run_queue(void) | |||
74 | clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); | 75 | clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); |
75 | 76 | ||
76 | if (dev->flags & IFF_UP) { | 77 | if (dev->flags & IFF_UP) { |
78 | if (netif_carrier_ok(dev)) { | ||
79 | WARN_ON(dev->qdisc_sleeping == &noop_qdisc); | ||
80 | dev_activate(dev); | ||
81 | } else | ||
82 | dev_deactivate(dev); | ||
83 | |||
77 | netdev_state_change(dev); | 84 | netdev_state_change(dev); |
78 | } | 85 | } |
79 | 86 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 0a2f67bbef2e..43bdc521e20d 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1953,7 +1953,7 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v) | |||
1953 | struct neigh_statistics *st = v; | 1953 | struct neigh_statistics *st = v; |
1954 | 1954 | ||
1955 | if (v == SEQ_START_TOKEN) { | 1955 | if (v == SEQ_START_TOKEN) { |
1956 | seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs forced_gc_goal_miss\n"); | 1956 | seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs\n"); |
1957 | return 0; | 1957 | return 0; |
1958 | } | 1958 | } |
1959 | 1959 | ||
diff --git a/net/core/netfilter.c b/net/core/netfilter.c index e51cfa46950c..22a8f127c4aa 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c | |||
@@ -217,21 +217,10 @@ void nf_debug_ip_local_deliver(struct sk_buff *skb) | |||
217 | * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */ | 217 | * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */ |
218 | if (!skb->dev) { | 218 | if (!skb->dev) { |
219 | printk("ip_local_deliver: skb->dev is NULL.\n"); | 219 | printk("ip_local_deliver: skb->dev is NULL.\n"); |
220 | } | 220 | } else { |
221 | else if (strcmp(skb->dev->name, "lo") == 0) { | ||
222 | if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT) | ||
223 | | (1 << NF_IP_POST_ROUTING) | ||
224 | | (1 << NF_IP_PRE_ROUTING) | ||
225 | | (1 << NF_IP_LOCAL_IN))) { | ||
226 | printk("ip_local_deliver: bad loopback skb: "); | ||
227 | debug_print_hooks_ip(skb->nf_debug); | ||
228 | nf_dump_skb(PF_INET, skb); | ||
229 | } | ||
230 | } | ||
231 | else { | ||
232 | if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING) | 221 | if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING) |
233 | | (1<<NF_IP_LOCAL_IN))) { | 222 | | (1<<NF_IP_LOCAL_IN))) { |
234 | printk("ip_local_deliver: bad non-lo skb: "); | 223 | printk("ip_local_deliver: bad skb: "); |
235 | debug_print_hooks_ip(skb->nf_debug); | 224 | debug_print_hooks_ip(skb->nf_debug); |
236 | nf_dump_skb(PF_INET, skb); | 225 | nf_dump_skb(PF_INET, skb); |
237 | } | 226 | } |
@@ -247,8 +236,6 @@ void nf_debug_ip_loopback_xmit(struct sk_buff *newskb) | |||
247 | debug_print_hooks_ip(newskb->nf_debug); | 236 | debug_print_hooks_ip(newskb->nf_debug); |
248 | nf_dump_skb(PF_INET, newskb); | 237 | nf_dump_skb(PF_INET, newskb); |
249 | } | 238 | } |
250 | /* Clear to avoid confusing input check */ | ||
251 | newskb->nf_debug = 0; | ||
252 | } | 239 | } |
253 | 240 | ||
254 | void nf_debug_ip_finish_output2(struct sk_buff *skb) | 241 | void nf_debug_ip_finish_output2(struct sk_buff *skb) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d8c198e42f90..00caf4b318b2 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -86,30 +86,33 @@ struct sock *rtnl; | |||
86 | 86 | ||
87 | struct rtnetlink_link * rtnetlink_links[NPROTO]; | 87 | struct rtnetlink_link * rtnetlink_links[NPROTO]; |
88 | 88 | ||
89 | static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = | 89 | static const int rtm_min[RTM_NR_FAMILIES] = |
90 | { | 90 | { |
91 | NLMSG_LENGTH(sizeof(struct ifinfomsg)), | 91 | [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), |
92 | NLMSG_LENGTH(sizeof(struct ifaddrmsg)), | 92 | [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), |
93 | NLMSG_LENGTH(sizeof(struct rtmsg)), | 93 | [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), |
94 | NLMSG_LENGTH(sizeof(struct ndmsg)), | 94 | [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)), |
95 | NLMSG_LENGTH(sizeof(struct rtmsg)), | 95 | [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), |
96 | NLMSG_LENGTH(sizeof(struct tcmsg)), | 96 | [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
97 | NLMSG_LENGTH(sizeof(struct tcmsg)), | 97 | [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
98 | NLMSG_LENGTH(sizeof(struct tcmsg)), | 98 | [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
99 | NLMSG_LENGTH(sizeof(struct tcamsg)) | 99 | [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), |
100 | [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
101 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
102 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
100 | }; | 103 | }; |
101 | 104 | ||
102 | static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = | 105 | static const int rta_max[RTM_NR_FAMILIES] = |
103 | { | 106 | { |
104 | IFLA_MAX, | 107 | [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, |
105 | IFA_MAX, | 108 | [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, |
106 | RTA_MAX, | 109 | [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, |
107 | NDA_MAX, | 110 | [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX, |
108 | RTA_MAX, | 111 | [RTM_FAM(RTM_NEWRULE)] = RTA_MAX, |
109 | TCA_MAX, | 112 | [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, |
110 | TCA_MAX, | 113 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, |
111 | TCA_MAX, | 114 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, |
112 | TCAA_MAX | 115 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, |
113 | }; | 116 | }; |
114 | 117 | ||
115 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) | 118 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) |
@@ -606,27 +609,33 @@ static inline int rtnetlink_rcv_skb(struct sk_buff *skb) | |||
606 | 609 | ||
607 | /* | 610 | /* |
608 | * rtnetlink input queue processing routine: | 611 | * rtnetlink input queue processing routine: |
609 | * - try to acquire shared lock. If it is failed, defer processing. | 612 | * - process as much as there was in the queue upon entry. |
610 | * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, | 613 | * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, |
611 | * that will occur, when a dump started and/or acquisition of | 614 | * that will occur, when a dump started. |
612 | * exclusive lock failed. | ||
613 | */ | 615 | */ |
614 | 616 | ||
615 | static void rtnetlink_rcv(struct sock *sk, int len) | 617 | static void rtnetlink_rcv(struct sock *sk, int len) |
616 | { | 618 | { |
619 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
620 | |||
617 | do { | 621 | do { |
618 | struct sk_buff *skb; | 622 | struct sk_buff *skb; |
619 | 623 | ||
620 | if (rtnl_shlock_nowait()) | 624 | rtnl_lock(); |
621 | return; | 625 | |
626 | if (qlen > skb_queue_len(&sk->sk_receive_queue)) | ||
627 | qlen = skb_queue_len(&sk->sk_receive_queue); | ||
622 | 628 | ||
623 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 629 | for (; qlen; qlen--) { |
630 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
624 | if (rtnetlink_rcv_skb(skb)) { | 631 | if (rtnetlink_rcv_skb(skb)) { |
625 | if (skb->len) | 632 | if (skb->len) |
626 | skb_queue_head(&sk->sk_receive_queue, | 633 | skb_queue_head(&sk->sk_receive_queue, |
627 | skb); | 634 | skb); |
628 | else | 635 | else { |
629 | kfree_skb(skb); | 636 | kfree_skb(skb); |
637 | qlen--; | ||
638 | } | ||
630 | break; | 639 | break; |
631 | } | 640 | } |
632 | kfree_skb(skb); | 641 | kfree_skb(skb); |
@@ -635,10 +644,10 @@ static void rtnetlink_rcv(struct sock *sk, int len) | |||
635 | up(&rtnl_sem); | 644 | up(&rtnl_sem); |
636 | 645 | ||
637 | netdev_run_todo(); | 646 | netdev_run_todo(); |
638 | } while (rtnl && rtnl->sk_receive_queue.qlen); | 647 | } while (qlen); |
639 | } | 648 | } |
640 | 649 | ||
641 | static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] = | 650 | static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = |
642 | { | 651 | { |
643 | [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, | 652 | [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, |
644 | [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, | 653 | [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, |
diff --git a/net/core/sock.c b/net/core/sock.c index 5c2f72fa1013..98171ddd7e7d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -616,10 +616,10 @@ lenout: | |||
616 | 616 | ||
617 | /** | 617 | /** |
618 | * sk_alloc - All socket objects are allocated here | 618 | * sk_alloc - All socket objects are allocated here |
619 | * @family - protocol family | 619 | * @family: protocol family |
620 | * @priority - for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) | 620 | * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) |
621 | * @prot - struct proto associated with this new sock instance | 621 | * @prot: struct proto associated with this new sock instance |
622 | * @zero_it - if we should zero the newly allocated sock | 622 | * @zero_it: if we should zero the newly allocated sock |
623 | */ | 623 | */ |
624 | struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) | 624 | struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) |
625 | { | 625 | { |
@@ -970,8 +970,8 @@ static void __release_sock(struct sock *sk) | |||
970 | 970 | ||
971 | /** | 971 | /** |
972 | * sk_wait_data - wait for data to arrive at sk_receive_queue | 972 | * sk_wait_data - wait for data to arrive at sk_receive_queue |
973 | * sk - sock to wait on | 973 | * @sk: sock to wait on |
974 | * timeo - for how long | 974 | * @timeo: for how long |
975 | * | 975 | * |
976 | * Now socket state including sk->sk_err is changed only under lock, | 976 | * Now socket state including sk->sk_err is changed only under lock, |
977 | * hence we may omit checks after joining wait queue. | 977 | * hence we may omit checks after joining wait queue. |
diff --git a/net/core/stream.c b/net/core/stream.c index 1e27a57b5a97..ac9edfdf8742 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | /** | 22 | /** |
23 | * sk_stream_write_space - stream socket write_space callback. | 23 | * sk_stream_write_space - stream socket write_space callback. |
24 | * sk - socket | 24 | * @sk: socket |
25 | * | 25 | * |
26 | * FIXME: write proper description | 26 | * FIXME: write proper description |
27 | */ | 27 | */ |
@@ -43,8 +43,8 @@ EXPORT_SYMBOL(sk_stream_write_space); | |||
43 | 43 | ||
44 | /** | 44 | /** |
45 | * sk_stream_wait_connect - Wait for a socket to get into the connected state | 45 | * sk_stream_wait_connect - Wait for a socket to get into the connected state |
46 | * @sk - sock to wait on | 46 | * @sk: sock to wait on |
47 | * @timeo_p - for how long to wait | 47 | * @timeo_p: for how long to wait |
48 | * | 48 | * |
49 | * Must be called with the socket locked. | 49 | * Must be called with the socket locked. |
50 | */ | 50 | */ |
@@ -79,7 +79,7 @@ EXPORT_SYMBOL(sk_stream_wait_connect); | |||
79 | 79 | ||
80 | /** | 80 | /** |
81 | * sk_stream_closing - Return 1 if we still have things to send in our buffers. | 81 | * sk_stream_closing - Return 1 if we still have things to send in our buffers. |
82 | * @sk - socket to verify | 82 | * @sk: socket to verify |
83 | */ | 83 | */ |
84 | static inline int sk_stream_closing(struct sock *sk) | 84 | static inline int sk_stream_closing(struct sock *sk) |
85 | { | 85 | { |
@@ -107,8 +107,8 @@ EXPORT_SYMBOL(sk_stream_wait_close); | |||
107 | 107 | ||
108 | /** | 108 | /** |
109 | * sk_stream_wait_memory - Wait for more memory for a socket | 109 | * sk_stream_wait_memory - Wait for more memory for a socket |
110 | * @sk - socket to wait for memory | 110 | * @sk: socket to wait for memory |
111 | * @timeo_p - for how long | 111 | * @timeo_p: for how long |
112 | */ | 112 | */ |
113 | int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | 113 | int sk_stream_wait_memory(struct sock *sk, long *timeo_p) |
114 | { | 114 | { |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index c2a0346f423b..e6e23eb14428 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -1411,21 +1411,22 @@ static struct file_operations dn_dev_seq_fops = { | |||
1411 | 1411 | ||
1412 | #endif /* CONFIG_PROC_FS */ | 1412 | #endif /* CONFIG_PROC_FS */ |
1413 | 1413 | ||
1414 | static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] = | 1414 | static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = |
1415 | { | 1415 | { |
1416 | [4] = { .doit = dn_dev_rtm_newaddr, }, | 1416 | [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, }, |
1417 | [5] = { .doit = dn_dev_rtm_deladdr, }, | 1417 | [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, }, |
1418 | [6] = { .dumpit = dn_dev_dump_ifaddr, }, | 1418 | [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, }, |
1419 | |||
1420 | #ifdef CONFIG_DECNET_ROUTER | 1419 | #ifdef CONFIG_DECNET_ROUTER |
1421 | [8] = { .doit = dn_fib_rtm_newroute, }, | 1420 | [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, |
1422 | [9] = { .doit = dn_fib_rtm_delroute, }, | 1421 | [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, |
1423 | [10] = { .doit = dn_cache_getroute, .dumpit = dn_fib_dump, }, | 1422 | [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, |
1424 | [16] = { .doit = dn_fib_rtm_newrule, }, | 1423 | .dumpit = dn_fib_dump, }, |
1425 | [17] = { .doit = dn_fib_rtm_delrule, }, | 1424 | [RTM_NEWRULE - RTM_BASE] = { .doit = dn_fib_rtm_newrule, }, |
1426 | [18] = { .dumpit = dn_fib_dump_rules, }, | 1425 | [RTM_DELRULE - RTM_BASE] = { .doit = dn_fib_rtm_delrule, }, |
1426 | [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, }, | ||
1427 | #else | 1427 | #else |
1428 | [10] = { .doit = dn_cache_getroute, .dumpit = dn_cache_dump, }, | 1428 | [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, |
1429 | .dumpit = dn_cache_dump, | ||
1429 | #endif | 1430 | #endif |
1430 | 1431 | ||
1431 | }; | 1432 | }; |
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index f86a6259fd12..284a9998e53d 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c | |||
@@ -119,8 +119,9 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) | |||
119 | static void dnrmg_receive_user_sk(struct sock *sk, int len) | 119 | static void dnrmg_receive_user_sk(struct sock *sk, int len) |
120 | { | 120 | { |
121 | struct sk_buff *skb; | 121 | struct sk_buff *skb; |
122 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
122 | 123 | ||
123 | while((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 124 | for (; qlen && (skb = skb_dequeue(&sk->sk_receive_queue)); qlen--) { |
124 | dnrmg_receive_user_skb(skb); | 125 | dnrmg_receive_user_skb(skb); |
125 | kfree_skb(skb); | 126 | kfree_skb(skb); |
126 | } | 127 | } |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index eea7ef010776..abbc6d5c183e 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1107,17 +1107,18 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa) | |||
1107 | } | 1107 | } |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { | 1110 | static struct rtnetlink_link inet_rtnetlink_table[RTM_NR_MSGTYPES] = { |
1111 | [4] = { .doit = inet_rtm_newaddr, }, | 1111 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet_rtm_newaddr, }, |
1112 | [5] = { .doit = inet_rtm_deladdr, }, | 1112 | [RTM_DELADDR - RTM_BASE] = { .doit = inet_rtm_deladdr, }, |
1113 | [6] = { .dumpit = inet_dump_ifaddr, }, | 1113 | [RTM_GETADDR - RTM_BASE] = { .dumpit = inet_dump_ifaddr, }, |
1114 | [8] = { .doit = inet_rtm_newroute, }, | 1114 | [RTM_NEWROUTE - RTM_BASE] = { .doit = inet_rtm_newroute, }, |
1115 | [9] = { .doit = inet_rtm_delroute, }, | 1115 | [RTM_DELROUTE - RTM_BASE] = { .doit = inet_rtm_delroute, }, |
1116 | [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, }, | 1116 | [RTM_GETROUTE - RTM_BASE] = { .doit = inet_rtm_getroute, |
1117 | .dumpit = inet_dump_fib, }, | ||
1117 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1118 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
1118 | [16] = { .doit = inet_rtm_newrule, }, | 1119 | [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, }, |
1119 | [17] = { .doit = inet_rtm_delrule, }, | 1120 | [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, }, |
1120 | [18] = { .dumpit = inet_dump_rules, }, | 1121 | [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, }, |
1121 | #endif | 1122 | #endif |
1122 | }; | 1123 | }; |
1123 | 1124 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 38f69532a029..24fe3e00b42b 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -111,6 +111,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
111 | #ifdef CONFIG_NETFILTER_DEBUG | 111 | #ifdef CONFIG_NETFILTER_DEBUG |
112 | nf_debug_ip_loopback_xmit(newskb); | 112 | nf_debug_ip_loopback_xmit(newskb); |
113 | #endif | 113 | #endif |
114 | nf_reset(newskb); | ||
114 | netif_rx(newskb); | 115 | netif_rx(newskb); |
115 | return 0; | 116 | return 0; |
116 | } | 117 | } |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 2b87c1974be6..721ddbf522b4 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -819,6 +819,7 @@ static int tcp_error(struct sk_buff *skb, | |||
819 | */ | 819 | */ |
820 | /* FIXME: Source route IP option packets --RR */ | 820 | /* FIXME: Source route IP option packets --RR */ |
821 | if (hooknum == NF_IP_PRE_ROUTING | 821 | if (hooknum == NF_IP_PRE_ROUTING |
822 | && skb->ip_summed != CHECKSUM_UNNECESSARY | ||
822 | && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, | 823 | && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, |
823 | skb->ip_summed == CHECKSUM_HW ? skb->csum | 824 | skb->ip_summed == CHECKSUM_HW ? skb->csum |
824 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { | 825 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 9e40dffc204f..e5746b674413 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -546,20 +546,18 @@ ipq_rcv_skb(struct sk_buff *skb) | |||
546 | static void | 546 | static void |
547 | ipq_rcv_sk(struct sock *sk, int len) | 547 | ipq_rcv_sk(struct sock *sk, int len) |
548 | { | 548 | { |
549 | do { | 549 | struct sk_buff *skb; |
550 | struct sk_buff *skb; | 550 | unsigned int qlen; |
551 | 551 | ||
552 | if (down_trylock(&ipqnl_sem)) | 552 | down(&ipqnl_sem); |
553 | return; | ||
554 | 553 | ||
555 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 554 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
556 | ipq_rcv_skb(skb); | 555 | skb = skb_dequeue(&sk->sk_receive_queue); |
557 | kfree_skb(skb); | 556 | ipq_rcv_skb(skb); |
558 | } | 557 | kfree_skb(skb); |
558 | } | ||
559 | 559 | ||
560 | up(&ipqnl_sem); | 560 | up(&ipqnl_sem); |
561 | |||
562 | } while (ipqnl && ipqnl->sk_receive_queue.qlen); | ||
563 | } | 561 | } |
564 | 562 | ||
565 | static int | 563 | static int |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 01b4a3c814d3..47449ba83eb9 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -103,13 +103,15 @@ static struct nf_hook_ops ipt_ops[] = { | |||
103 | .hook = ipt_hook, | 103 | .hook = ipt_hook, |
104 | .pf = PF_INET, | 104 | .pf = PF_INET, |
105 | .hooknum = NF_IP_PRE_ROUTING, | 105 | .hooknum = NF_IP_PRE_ROUTING, |
106 | .priority = NF_IP_PRI_RAW | 106 | .priority = NF_IP_PRI_RAW, |
107 | .owner = THIS_MODULE, | ||
107 | }, | 108 | }, |
108 | { | 109 | { |
109 | .hook = ipt_hook, | 110 | .hook = ipt_hook, |
110 | .pf = PF_INET, | 111 | .pf = PF_INET, |
111 | .hooknum = NF_IP_LOCAL_OUT, | 112 | .hooknum = NF_IP_LOCAL_OUT, |
112 | .priority = NF_IP_PRI_RAW | 113 | .priority = NF_IP_PRI_RAW, |
114 | .owner = THIS_MODULE, | ||
113 | }, | 115 | }, |
114 | }; | 116 | }; |
115 | 117 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index bb90a0c3a91e..199311746932 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -397,7 +397,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v) | |||
397 | struct rt_cache_stat *st = v; | 397 | struct rt_cache_stat *st = v; |
398 | 398 | ||
399 | if (v == SEQ_START_TOKEN) { | 399 | if (v == SEQ_START_TOKEN) { |
400 | seq_printf(seq, "entries in_hit in_slow_tot in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n"); | 400 | seq_printf(seq, "entries in_hit in_slow_tot in_slow_mc in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n"); |
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
@@ -2843,7 +2843,7 @@ ctl_table ipv4_route_table[] = { | |||
2843 | .procname = "flush", | 2843 | .procname = "flush", |
2844 | .data = &flush_delay, | 2844 | .data = &flush_delay, |
2845 | .maxlen = sizeof(int), | 2845 | .maxlen = sizeof(int), |
2846 | .mode = 0644, | 2846 | .mode = 0200, |
2847 | .proc_handler = &ipv4_sysctl_rtcache_flush, | 2847 | .proc_handler = &ipv4_sysctl_rtcache_flush, |
2848 | .strategy = &ipv4_sysctl_rtcache_flush_strategy, | 2848 | .strategy = &ipv4_sysctl_rtcache_flush_strategy, |
2849 | }, | 2849 | }, |
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 313c1408da33..8faa8948f75c 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c | |||
@@ -777,8 +777,9 @@ static inline void tcpdiag_rcv_skb(struct sk_buff *skb) | |||
777 | static void tcpdiag_rcv(struct sock *sk, int len) | 777 | static void tcpdiag_rcv(struct sock *sk, int len) |
778 | { | 778 | { |
779 | struct sk_buff *skb; | 779 | struct sk_buff *skb; |
780 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
780 | 781 | ||
781 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 782 | while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) { |
782 | tcpdiag_rcv_skb(skb); | 783 | tcpdiag_rcv_skb(skb); |
783 | kfree_skb(skb); | 784 | kfree_skb(skb); |
784 | } | 785 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3ac6659869c4..dad98e4a5043 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -222,10 +222,13 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum) | |||
222 | int rover; | 222 | int rover; |
223 | 223 | ||
224 | spin_lock(&tcp_portalloc_lock); | 224 | spin_lock(&tcp_portalloc_lock); |
225 | rover = tcp_port_rover; | 225 | if (tcp_port_rover < low) |
226 | rover = low; | ||
227 | else | ||
228 | rover = tcp_port_rover; | ||
226 | do { | 229 | do { |
227 | rover++; | 230 | rover++; |
228 | if (rover < low || rover > high) | 231 | if (rover > high) |
229 | rover = low; | 232 | rover = low; |
230 | head = &tcp_bhash[tcp_bhashfn(rover)]; | 233 | head = &tcp_bhash[tcp_bhashfn(rover)]; |
231 | spin_lock(&head->lock); | 234 | spin_lock(&head->lock); |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 7fe2afd2e669..b2b60f3e9cdd 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -8,7 +8,10 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <asm/bug.h> | ||
12 | #include <linux/compiler.h> | ||
11 | #include <linux/config.h> | 13 | #include <linux/config.h> |
14 | #include <linux/inetdevice.h> | ||
12 | #include <net/xfrm.h> | 15 | #include <net/xfrm.h> |
13 | #include <net/ip.h> | 16 | #include <net/ip.h> |
14 | 17 | ||
@@ -152,6 +155,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
152 | x->u.rt.rt_dst = rt0->rt_dst; | 155 | x->u.rt.rt_dst = rt0->rt_dst; |
153 | x->u.rt.rt_gateway = rt->rt_gateway; | 156 | x->u.rt.rt_gateway = rt->rt_gateway; |
154 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; | 157 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; |
158 | x->u.rt.idev = rt0->idev; | ||
159 | in_dev_hold(rt0->idev); | ||
155 | header_len -= x->u.dst.xfrm->props.header_len; | 160 | header_len -= x->u.dst.xfrm->props.header_len; |
156 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 161 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
157 | } | 162 | } |
@@ -243,11 +248,48 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
243 | path->ops->update_pmtu(path, mtu); | 248 | path->ops->update_pmtu(path, mtu); |
244 | } | 249 | } |
245 | 250 | ||
251 | static void xfrm4_dst_destroy(struct dst_entry *dst) | ||
252 | { | ||
253 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
254 | |||
255 | if (likely(xdst->u.rt.idev)) | ||
256 | in_dev_put(xdst->u.rt.idev); | ||
257 | xfrm_dst_destroy(xdst); | ||
258 | } | ||
259 | |||
260 | static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
261 | int unregister) | ||
262 | { | ||
263 | struct xfrm_dst *xdst; | ||
264 | |||
265 | if (!unregister) | ||
266 | return; | ||
267 | |||
268 | xdst = (struct xfrm_dst *)dst; | ||
269 | if (xdst->u.rt.idev->dev == dev) { | ||
270 | struct in_device *loopback_idev = in_dev_get(&loopback_dev); | ||
271 | BUG_ON(!loopback_idev); | ||
272 | |||
273 | do { | ||
274 | in_dev_put(xdst->u.rt.idev); | ||
275 | xdst->u.rt.idev = loopback_idev; | ||
276 | in_dev_hold(loopback_idev); | ||
277 | xdst = (struct xfrm_dst *)xdst->u.dst.child; | ||
278 | } while (xdst->u.dst.xfrm); | ||
279 | |||
280 | __in_dev_put(loopback_idev); | ||
281 | } | ||
282 | |||
283 | xfrm_dst_ifdown(dst, dev); | ||
284 | } | ||
285 | |||
246 | static struct dst_ops xfrm4_dst_ops = { | 286 | static struct dst_ops xfrm4_dst_ops = { |
247 | .family = AF_INET, | 287 | .family = AF_INET, |
248 | .protocol = __constant_htons(ETH_P_IP), | 288 | .protocol = __constant_htons(ETH_P_IP), |
249 | .gc = xfrm4_garbage_collect, | 289 | .gc = xfrm4_garbage_collect, |
250 | .update_pmtu = xfrm4_update_pmtu, | 290 | .update_pmtu = xfrm4_update_pmtu, |
291 | .destroy = xfrm4_dst_destroy, | ||
292 | .ifdown = xfrm4_dst_ifdown, | ||
251 | .gc_thresh = 1024, | 293 | .gc_thresh = 1024, |
252 | .entry_size = sizeof(struct xfrm_dst), | 294 | .entry_size = sizeof(struct xfrm_dst), |
253 | }; | 295 | }; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7196ac2f2d16..7744a2592693 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3076,7 +3076,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3076 | netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); | 3076 | netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); |
3077 | } | 3077 | } |
3078 | 3078 | ||
3079 | static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { | 3079 | static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { |
3080 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, | 3080 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, |
3081 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, | 3081 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, |
3082 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, | 3082 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index c54830b89593..750943e2d34e 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -549,20 +549,18 @@ ipq_rcv_skb(struct sk_buff *skb) | |||
549 | static void | 549 | static void |
550 | ipq_rcv_sk(struct sock *sk, int len) | 550 | ipq_rcv_sk(struct sock *sk, int len) |
551 | { | 551 | { |
552 | do { | 552 | struct sk_buff *skb; |
553 | struct sk_buff *skb; | 553 | unsigned int qlen; |
554 | 554 | ||
555 | if (down_trylock(&ipqnl_sem)) | 555 | down(&ipqnl_sem); |
556 | return; | ||
557 | 556 | ||
558 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 557 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
559 | ipq_rcv_skb(skb); | 558 | skb = skb_dequeue(&sk->sk_receive_queue); |
560 | kfree_skb(skb); | 559 | ipq_rcv_skb(skb); |
561 | } | 560 | kfree_skb(skb); |
561 | } | ||
562 | 562 | ||
563 | up(&ipqnl_sem); | 563 | up(&ipqnl_sem); |
564 | |||
565 | } while (ipqnl && ipqnl->sk_receive_queue.qlen); | ||
566 | } | 564 | } |
567 | 565 | ||
568 | static int | 566 | static int |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 1352c1d9bf4d..617645bc5ed6 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -455,11 +455,11 @@ csum_copy_err: | |||
455 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | 455 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, |
456 | struct raw6_sock *rp) | 456 | struct raw6_sock *rp) |
457 | { | 457 | { |
458 | struct inet_sock *inet = inet_sk(sk); | ||
459 | struct sk_buff *skb; | 458 | struct sk_buff *skb; |
460 | int err = 0; | 459 | int err = 0; |
461 | int offset; | 460 | int offset; |
462 | int len; | 461 | int len; |
462 | int total_len; | ||
463 | u32 tmp_csum; | 463 | u32 tmp_csum; |
464 | u16 csum; | 464 | u16 csum; |
465 | 465 | ||
@@ -470,7 +470,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | |||
470 | goto out; | 470 | goto out; |
471 | 471 | ||
472 | offset = rp->offset; | 472 | offset = rp->offset; |
473 | if (offset >= inet->cork.length - 1) { | 473 | total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data); |
474 | if (offset >= total_len - 1) { | ||
474 | err = -EINVAL; | 475 | err = -EINVAL; |
475 | ip6_flush_pending_frames(sk); | 476 | ip6_flush_pending_frames(sk); |
476 | goto out; | 477 | goto out; |
@@ -514,7 +515,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | |||
514 | 515 | ||
515 | tmp_csum = csum_ipv6_magic(&fl->fl6_src, | 516 | tmp_csum = csum_ipv6_magic(&fl->fl6_src, |
516 | &fl->fl6_dst, | 517 | &fl->fl6_dst, |
517 | inet->cork.length, fl->proto, tmp_csum); | 518 | total_len, fl->proto, tmp_csum); |
518 | 519 | ||
519 | if (tmp_csum == 0) | 520 | if (tmp_csum == 0) |
520 | tmp_csum = -1; | 521 | tmp_csum = -1; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 183802902c02..3bf8a0254f81 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2005,7 +2005,7 @@ ctl_table ipv6_route_table[] = { | |||
2005 | .procname = "flush", | 2005 | .procname = "flush", |
2006 | .data = &flush_delay, | 2006 | .data = &flush_delay, |
2007 | .maxlen = sizeof(int), | 2007 | .maxlen = sizeof(int), |
2008 | .mode = 0644, | 2008 | .mode = 0200, |
2009 | .proc_handler = &ipv6_sysctl_rtcache_flush | 2009 | .proc_handler = &ipv6_sysctl_rtcache_flush |
2010 | }, | 2010 | }, |
2011 | { | 2011 | { |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 4760c85e19db..0f69e800a0ad 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -139,9 +139,12 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | |||
139 | int rover; | 139 | int rover; |
140 | 140 | ||
141 | spin_lock(&tcp_portalloc_lock); | 141 | spin_lock(&tcp_portalloc_lock); |
142 | rover = tcp_port_rover; | 142 | if (tcp_port_rover < low) |
143 | rover = low; | ||
144 | else | ||
145 | rover = tcp_port_rover; | ||
143 | do { rover++; | 146 | do { rover++; |
144 | if ((rover < low) || (rover > high)) | 147 | if (rover > high) |
145 | rover = low; | 148 | rover = low; |
146 | head = &tcp_bhash[tcp_bhashfn(rover)]; | 149 | head = &tcp_bhash[tcp_bhashfn(rover)]; |
147 | spin_lock(&head->lock); | 150 | spin_lock(&head->lock); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8a4f37de4d2d..4429b1a1fe5f 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -11,7 +11,11 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <asm/bug.h> | ||
15 | #include <linux/compiler.h> | ||
14 | #include <linux/config.h> | 16 | #include <linux/config.h> |
17 | #include <linux/netdevice.h> | ||
18 | #include <net/addrconf.h> | ||
15 | #include <net/xfrm.h> | 19 | #include <net/xfrm.h> |
16 | #include <net/ip.h> | 20 | #include <net/ip.h> |
17 | #include <net/ipv6.h> | 21 | #include <net/ipv6.h> |
@@ -166,6 +170,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
166 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); | 170 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); |
167 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; | 171 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; |
168 | x->u.rt6.rt6i_src = rt0->rt6i_src; | 172 | x->u.rt6.rt6i_src = rt0->rt6i_src; |
173 | x->u.rt6.rt6i_idev = rt0->rt6i_idev; | ||
174 | in6_dev_hold(rt0->rt6i_idev); | ||
169 | header_len -= x->u.dst.xfrm->props.header_len; | 175 | header_len -= x->u.dst.xfrm->props.header_len; |
170 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 176 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
171 | } | 177 | } |
@@ -251,11 +257,48 @@ static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
251 | path->ops->update_pmtu(path, mtu); | 257 | path->ops->update_pmtu(path, mtu); |
252 | } | 258 | } |
253 | 259 | ||
260 | static void xfrm6_dst_destroy(struct dst_entry *dst) | ||
261 | { | ||
262 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
263 | |||
264 | if (likely(xdst->u.rt6.rt6i_idev)) | ||
265 | in6_dev_put(xdst->u.rt6.rt6i_idev); | ||
266 | xfrm_dst_destroy(xdst); | ||
267 | } | ||
268 | |||
269 | static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
270 | int unregister) | ||
271 | { | ||
272 | struct xfrm_dst *xdst; | ||
273 | |||
274 | if (!unregister) | ||
275 | return; | ||
276 | |||
277 | xdst = (struct xfrm_dst *)dst; | ||
278 | if (xdst->u.rt6.rt6i_idev->dev == dev) { | ||
279 | struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev); | ||
280 | BUG_ON(!loopback_idev); | ||
281 | |||
282 | do { | ||
283 | in6_dev_put(xdst->u.rt6.rt6i_idev); | ||
284 | xdst->u.rt6.rt6i_idev = loopback_idev; | ||
285 | in6_dev_hold(loopback_idev); | ||
286 | xdst = (struct xfrm_dst *)xdst->u.dst.child; | ||
287 | } while (xdst->u.dst.xfrm); | ||
288 | |||
289 | __in6_dev_put(loopback_idev); | ||
290 | } | ||
291 | |||
292 | xfrm_dst_ifdown(dst, dev); | ||
293 | } | ||
294 | |||
254 | static struct dst_ops xfrm6_dst_ops = { | 295 | static struct dst_ops xfrm6_dst_ops = { |
255 | .family = AF_INET6, | 296 | .family = AF_INET6, |
256 | .protocol = __constant_htons(ETH_P_IPV6), | 297 | .protocol = __constant_htons(ETH_P_IPV6), |
257 | .gc = xfrm6_garbage_collect, | 298 | .gc = xfrm6_garbage_collect, |
258 | .update_pmtu = xfrm6_update_pmtu, | 299 | .update_pmtu = xfrm6_update_pmtu, |
300 | .destroy = xfrm6_dst_destroy, | ||
301 | .ifdown = xfrm6_dst_ifdown, | ||
259 | .gc_thresh = 1024, | 302 | .gc_thresh = 1024, |
260 | .entry_size = sizeof(struct xfrm_dst), | 303 | .entry_size = sizeof(struct xfrm_dst), |
261 | }; | 304 | }; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 29a5fd231eac..4ee392066148 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -373,7 +373,6 @@ static int netlink_release(struct socket *sock) | |||
373 | nlk->cb->done(nlk->cb); | 373 | nlk->cb->done(nlk->cb); |
374 | netlink_destroy_callback(nlk->cb); | 374 | netlink_destroy_callback(nlk->cb); |
375 | nlk->cb = NULL; | 375 | nlk->cb = NULL; |
376 | __sock_put(sk); | ||
377 | } | 376 | } |
378 | spin_unlock(&nlk->cb_lock); | 377 | spin_unlock(&nlk->cb_lock); |
379 | 378 | ||
@@ -1099,7 +1098,6 @@ static int netlink_dump(struct sock *sk) | |||
1099 | spin_unlock(&nlk->cb_lock); | 1098 | spin_unlock(&nlk->cb_lock); |
1100 | 1099 | ||
1101 | netlink_destroy_callback(cb); | 1100 | netlink_destroy_callback(cb); |
1102 | __sock_put(sk); | ||
1103 | return 0; | 1101 | return 0; |
1104 | } | 1102 | } |
1105 | 1103 | ||
@@ -1138,7 +1136,6 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1138 | return -EBUSY; | 1136 | return -EBUSY; |
1139 | } | 1137 | } |
1140 | nlk->cb = cb; | 1138 | nlk->cb = cb; |
1141 | sock_hold(sk); | ||
1142 | spin_unlock(&nlk->cb_lock); | 1139 | spin_unlock(&nlk->cb_lock); |
1143 | 1140 | ||
1144 | netlink_dump(sk); | 1141 | netlink_dump(sk); |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 9c118baed9dc..b0941186f867 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -185,7 +185,7 @@ config NET_SCH_GRED | |||
185 | depends on NET_SCHED | 185 | depends on NET_SCHED |
186 | help | 186 | help |
187 | Say Y here if you want to use the Generic Random Early Detection | 187 | Say Y here if you want to use the Generic Random Early Detection |
188 | (RED) packet scheduling algorithm for some of your network devices | 188 | (GRED) packet scheduling algorithm for some of your network devices |
189 | (see the top of <file:net/sched/sch_red.c> for details and | 189 | (see the top of <file:net/sched/sch_red.c> for details and |
190 | references about the algorithm). | 190 | references about the algorithm). |
191 | 191 | ||
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 5e6cc371b39e..cafcb084098d 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -171,10 +171,10 @@ repeat: | |||
171 | skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); | 171 | skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); |
172 | skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); | 172 | skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); |
173 | } | 173 | } |
174 | if (ret != TC_ACT_PIPE) | ||
175 | goto exec_done; | ||
176 | if (ret == TC_ACT_REPEAT) | 174 | if (ret == TC_ACT_REPEAT) |
177 | goto repeat; /* we need a ttl - JHS */ | 175 | goto repeat; /* we need a ttl - JHS */ |
176 | if (ret != TC_ACT_PIPE) | ||
177 | goto exec_done; | ||
178 | } | 178 | } |
179 | act = a->next; | 179 | act = a->next; |
180 | } | 180 | } |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 4323a74eea30..07977f8f2679 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -1289,6 +1289,7 @@ static int __init pktsched_init(void) | |||
1289 | 1289 | ||
1290 | subsys_initcall(pktsched_init); | 1290 | subsys_initcall(pktsched_init); |
1291 | 1291 | ||
1292 | EXPORT_SYMBOL(qdisc_lookup); | ||
1292 | EXPORT_SYMBOL(qdisc_get_rtab); | 1293 | EXPORT_SYMBOL(qdisc_get_rtab); |
1293 | EXPORT_SYMBOL(qdisc_put_rtab); | 1294 | EXPORT_SYMBOL(qdisc_put_rtab); |
1294 | EXPORT_SYMBOL(register_qdisc); | 1295 | EXPORT_SYMBOL(register_qdisc); |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 8c01e023f02e..87e48a4e1051 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -179,6 +179,7 @@ requeue: | |||
179 | netif_schedule(dev); | 179 | netif_schedule(dev); |
180 | return 1; | 180 | return 1; |
181 | } | 181 | } |
182 | BUG_ON((int) q->q.qlen < 0); | ||
182 | return q->q.qlen; | 183 | return q->q.qlen; |
183 | } | 184 | } |
184 | 185 | ||
@@ -539,6 +540,10 @@ void dev_activate(struct net_device *dev) | |||
539 | write_unlock_bh(&qdisc_tree_lock); | 540 | write_unlock_bh(&qdisc_tree_lock); |
540 | } | 541 | } |
541 | 542 | ||
543 | if (!netif_carrier_ok(dev)) | ||
544 | /* Delay activation until next carrier-on event */ | ||
545 | return; | ||
546 | |||
542 | spin_lock_bh(&dev->queue_lock); | 547 | spin_lock_bh(&dev->queue_lock); |
543 | rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); | 548 | rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); |
544 | if (dev->qdisc != &noqueue_qdisc) { | 549 | if (dev->qdisc != &noqueue_qdisc) { |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index a85935e7d53d..558cc087e602 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -717,6 +717,10 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
717 | if (q->direct_queue.qlen < q->direct_qlen) { | 717 | if (q->direct_queue.qlen < q->direct_qlen) { |
718 | __skb_queue_tail(&q->direct_queue, skb); | 718 | __skb_queue_tail(&q->direct_queue, skb); |
719 | q->direct_pkts++; | 719 | q->direct_pkts++; |
720 | } else { | ||
721 | kfree_skb(skb); | ||
722 | sch->qstats.drops++; | ||
723 | return NET_XMIT_DROP; | ||
720 | } | 724 | } |
721 | #ifdef CONFIG_NET_CLS_ACT | 725 | #ifdef CONFIG_NET_CLS_ACT |
722 | } else if (!cl) { | 726 | } else if (!cl) { |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 31c29deb139d..e0c9fbe73b15 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -138,38 +138,77 @@ static long tabledist(unsigned long mu, long sigma, | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /* Put skb in the private delayed queue. */ | 140 | /* Put skb in the private delayed queue. */ |
141 | static int delay_skb(struct Qdisc *sch, struct sk_buff *skb) | 141 | static int netem_delay(struct Qdisc *sch, struct sk_buff *skb) |
142 | { | 142 | { |
143 | struct netem_sched_data *q = qdisc_priv(sch); | 143 | struct netem_sched_data *q = qdisc_priv(sch); |
144 | struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; | ||
145 | psched_tdiff_t td; | 144 | psched_tdiff_t td; |
146 | psched_time_t now; | 145 | psched_time_t now; |
147 | 146 | ||
148 | PSCHED_GET_TIME(now); | 147 | PSCHED_GET_TIME(now); |
149 | td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist); | 148 | td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist); |
150 | PSCHED_TADD2(now, td, cb->time_to_send); | ||
151 | 149 | ||
152 | /* Always queue at tail to keep packets in order */ | 150 | /* Always queue at tail to keep packets in order */ |
153 | if (likely(q->delayed.qlen < q->limit)) { | 151 | if (likely(q->delayed.qlen < q->limit)) { |
152 | struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; | ||
153 | |||
154 | PSCHED_TADD2(now, td, cb->time_to_send); | ||
155 | |||
156 | pr_debug("netem_delay: skb=%p now=%llu tosend=%llu\n", skb, | ||
157 | now, cb->time_to_send); | ||
158 | |||
154 | __skb_queue_tail(&q->delayed, skb); | 159 | __skb_queue_tail(&q->delayed, skb); |
155 | if (!timer_pending(&q->timer)) { | ||
156 | q->timer.expires = jiffies + PSCHED_US2JIFFIE(td); | ||
157 | add_timer(&q->timer); | ||
158 | } | ||
159 | return NET_XMIT_SUCCESS; | 160 | return NET_XMIT_SUCCESS; |
160 | } | 161 | } |
161 | 162 | ||
163 | pr_debug("netem_delay: queue over limit %d\n", q->limit); | ||
164 | sch->qstats.overlimits++; | ||
162 | kfree_skb(skb); | 165 | kfree_skb(skb); |
163 | return NET_XMIT_DROP; | 166 | return NET_XMIT_DROP; |
164 | } | 167 | } |
165 | 168 | ||
169 | /* | ||
170 | * Move a packet that is ready to send from the delay holding | ||
171 | * list to the underlying qdisc. | ||
172 | */ | ||
173 | static int netem_run(struct Qdisc *sch) | ||
174 | { | ||
175 | struct netem_sched_data *q = qdisc_priv(sch); | ||
176 | struct sk_buff *skb; | ||
177 | psched_time_t now; | ||
178 | |||
179 | PSCHED_GET_TIME(now); | ||
180 | |||
181 | skb = skb_peek(&q->delayed); | ||
182 | if (skb) { | ||
183 | const struct netem_skb_cb *cb | ||
184 | = (const struct netem_skb_cb *)skb->cb; | ||
185 | long delay | ||
186 | = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now)); | ||
187 | pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay); | ||
188 | |||
189 | /* if more time remaining? */ | ||
190 | if (delay > 0) { | ||
191 | mod_timer(&q->timer, jiffies + delay); | ||
192 | return 1; | ||
193 | } | ||
194 | |||
195 | __skb_unlink(skb, &q->delayed); | ||
196 | |||
197 | if (q->qdisc->enqueue(skb, q->qdisc)) { | ||
198 | sch->q.qlen--; | ||
199 | sch->qstats.drops++; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
166 | static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | 206 | static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) |
167 | { | 207 | { |
168 | struct netem_sched_data *q = qdisc_priv(sch); | 208 | struct netem_sched_data *q = qdisc_priv(sch); |
169 | struct sk_buff *skb2; | ||
170 | int ret; | 209 | int ret; |
171 | 210 | ||
172 | pr_debug("netem_enqueue skb=%p @%lu\n", skb, jiffies); | 211 | pr_debug("netem_enqueue skb=%p\n", skb); |
173 | 212 | ||
174 | /* Random packet drop 0 => none, ~0 => all */ | 213 | /* Random packet drop 0 => none, ~0 => all */ |
175 | if (q->loss && q->loss >= get_crandom(&q->loss_cor)) { | 214 | if (q->loss && q->loss >= get_crandom(&q->loss_cor)) { |
@@ -180,11 +219,21 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
180 | } | 219 | } |
181 | 220 | ||
182 | /* Random duplication */ | 221 | /* Random duplication */ |
183 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor) | 222 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) { |
184 | && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { | 223 | struct sk_buff *skb2; |
185 | pr_debug("netem_enqueue: dup %p\n", skb2); | 224 | |
225 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
226 | if (skb2 && netem_delay(sch, skb2) == NET_XMIT_SUCCESS) { | ||
227 | struct Qdisc *qp; | ||
228 | |||
229 | /* Since one packet can generate two packets in the | ||
230 | * queue, the parent's qlen accounting gets confused, | ||
231 | * so fix it. | ||
232 | */ | ||
233 | qp = qdisc_lookup(sch->dev, TC_H_MAJ(sch->parent)); | ||
234 | if (qp) | ||
235 | qp->q.qlen++; | ||
186 | 236 | ||
187 | if (delay_skb(sch, skb2)) { | ||
188 | sch->q.qlen++; | 237 | sch->q.qlen++; |
189 | sch->bstats.bytes += skb2->len; | 238 | sch->bstats.bytes += skb2->len; |
190 | sch->bstats.packets++; | 239 | sch->bstats.packets++; |
@@ -202,7 +251,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
202 | ret = q->qdisc->enqueue(skb, q->qdisc); | 251 | ret = q->qdisc->enqueue(skb, q->qdisc); |
203 | } else { | 252 | } else { |
204 | q->counter = 0; | 253 | q->counter = 0; |
205 | ret = delay_skb(sch, skb); | 254 | ret = netem_delay(sch, skb); |
255 | netem_run(sch); | ||
206 | } | 256 | } |
207 | 257 | ||
208 | if (likely(ret == NET_XMIT_SUCCESS)) { | 258 | if (likely(ret == NET_XMIT_SUCCESS)) { |
@@ -212,6 +262,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
212 | } else | 262 | } else |
213 | sch->qstats.drops++; | 263 | sch->qstats.drops++; |
214 | 264 | ||
265 | pr_debug("netem: enqueue ret %d\n", ret); | ||
215 | return ret; | 266 | return ret; |
216 | } | 267 | } |
217 | 268 | ||
@@ -241,56 +292,35 @@ static unsigned int netem_drop(struct Qdisc* sch) | |||
241 | return len; | 292 | return len; |
242 | } | 293 | } |
243 | 294 | ||
244 | /* Dequeue packet. | ||
245 | * Move all packets that are ready to send from the delay holding | ||
246 | * list to the underlying qdisc, then just call dequeue | ||
247 | */ | ||
248 | static struct sk_buff *netem_dequeue(struct Qdisc *sch) | 295 | static struct sk_buff *netem_dequeue(struct Qdisc *sch) |
249 | { | 296 | { |
250 | struct netem_sched_data *q = qdisc_priv(sch); | 297 | struct netem_sched_data *q = qdisc_priv(sch); |
251 | struct sk_buff *skb; | 298 | struct sk_buff *skb; |
299 | int pending; | ||
300 | |||
301 | pending = netem_run(sch); | ||
252 | 302 | ||
253 | skb = q->qdisc->dequeue(q->qdisc); | 303 | skb = q->qdisc->dequeue(q->qdisc); |
254 | if (skb) | 304 | if (skb) { |
305 | pr_debug("netem_dequeue: return skb=%p\n", skb); | ||
255 | sch->q.qlen--; | 306 | sch->q.qlen--; |
307 | sch->flags &= ~TCQ_F_THROTTLED; | ||
308 | } | ||
309 | else if (pending) { | ||
310 | pr_debug("netem_dequeue: throttling\n"); | ||
311 | sch->flags |= TCQ_F_THROTTLED; | ||
312 | } | ||
313 | |||
256 | return skb; | 314 | return skb; |
257 | } | 315 | } |
258 | 316 | ||
259 | static void netem_watchdog(unsigned long arg) | 317 | static void netem_watchdog(unsigned long arg) |
260 | { | 318 | { |
261 | struct Qdisc *sch = (struct Qdisc *)arg; | 319 | struct Qdisc *sch = (struct Qdisc *)arg; |
262 | struct netem_sched_data *q = qdisc_priv(sch); | ||
263 | struct net_device *dev = sch->dev; | ||
264 | struct sk_buff *skb; | ||
265 | psched_time_t now; | ||
266 | |||
267 | pr_debug("netem_watchdog: fired @%lu\n", jiffies); | ||
268 | |||
269 | spin_lock_bh(&dev->queue_lock); | ||
270 | PSCHED_GET_TIME(now); | ||
271 | |||
272 | while ((skb = skb_peek(&q->delayed)) != NULL) { | ||
273 | const struct netem_skb_cb *cb | ||
274 | = (const struct netem_skb_cb *)skb->cb; | ||
275 | long delay | ||
276 | = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now)); | ||
277 | pr_debug("netem_watchdog: skb %p@%lu %ld\n", | ||
278 | skb, jiffies, delay); | ||
279 | 320 | ||
280 | /* if more time remaining? */ | 321 | pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen); |
281 | if (delay > 0) { | 322 | sch->flags &= ~TCQ_F_THROTTLED; |
282 | mod_timer(&q->timer, jiffies + delay); | 323 | netif_schedule(sch->dev); |
283 | break; | ||
284 | } | ||
285 | __skb_unlink(skb, &q->delayed); | ||
286 | |||
287 | if (q->qdisc->enqueue(skb, q->qdisc)) { | ||
288 | sch->q.qlen--; | ||
289 | sch->qstats.drops++; | ||
290 | } | ||
291 | } | ||
292 | qdisc_run(dev); | ||
293 | spin_unlock_bh(&dev->queue_lock); | ||
294 | } | 324 | } |
295 | 325 | ||
296 | static void netem_reset(struct Qdisc *sch) | 326 | static void netem_reset(struct Qdisc *sch) |
@@ -301,6 +331,7 @@ static void netem_reset(struct Qdisc *sch) | |||
301 | skb_queue_purge(&q->delayed); | 331 | skb_queue_purge(&q->delayed); |
302 | 332 | ||
303 | sch->q.qlen = 0; | 333 | sch->q.qlen = 0; |
334 | sch->flags &= ~TCQ_F_THROTTLED; | ||
304 | del_timer_sync(&q->timer); | 335 | del_timer_sync(&q->timer); |
305 | } | 336 | } |
306 | 337 | ||
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 544b75077dbd..334f61773e6d 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -125,6 +125,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
125 | sp->autoclose * HZ; | 125 | sp->autoclose * HZ; |
126 | 126 | ||
127 | /* Use SCTP specific send buffer space queues. */ | 127 | /* Use SCTP specific send buffer space queues. */ |
128 | ep->sndbuf_policy = sctp_sndbuf_policy; | ||
128 | sk->sk_write_space = sctp_write_space; | 129 | sk->sk_write_space = sctp_write_space; |
129 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 130 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
130 | 131 | ||
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index e42c74e3ec1e..c9d9ea064734 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -496,9 +496,7 @@ static void sctp_v6_inaddr_any(union sctp_addr *addr, unsigned short port) | |||
496 | /* Is this a wildcard address? */ | 496 | /* Is this a wildcard address? */ |
497 | static int sctp_v6_is_any(const union sctp_addr *addr) | 497 | static int sctp_v6_is_any(const union sctp_addr *addr) |
498 | { | 498 | { |
499 | int type; | 499 | return ipv6_addr_any(&addr->v6.sin6_addr); |
500 | type = ipv6_addr_type((struct in6_addr *)&addr->v6.sin6_addr); | ||
501 | return IPV6_ADDR_ANY == type; | ||
502 | } | 500 | } |
503 | 501 | ||
504 | /* Should this be available for binding? */ | 502 | /* Should this be available for binding? */ |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 9013f64f5219..84b5b370b09d 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -313,12 +313,12 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
313 | sk = chunk->skb->sk; | 313 | sk = chunk->skb->sk; |
314 | 314 | ||
315 | /* Allocate the new skb. */ | 315 | /* Allocate the new skb. */ |
316 | nskb = dev_alloc_skb(packet->size); | 316 | nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC); |
317 | if (!nskb) | 317 | if (!nskb) |
318 | goto nomem; | 318 | goto nomem; |
319 | 319 | ||
320 | /* Make sure the outbound skb has enough header room reserved. */ | 320 | /* Make sure the outbound skb has enough header room reserved. */ |
321 | skb_reserve(nskb, packet->overhead); | 321 | skb_reserve(nskb, packet->overhead + LL_MAX_HEADER); |
322 | 322 | ||
323 | /* Set the owning socket so that we know where to get the | 323 | /* Set the owning socket so that we know where to get the |
324 | * destination IP address. | 324 | * destination IP address. |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index b9813cf3d91c..2e1f9c3556f5 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1043,6 +1043,9 @@ SCTP_STATIC __init int sctp_init(void) | |||
1043 | sctp_max_retrans_path = 5; | 1043 | sctp_max_retrans_path = 5; |
1044 | sctp_max_retrans_init = 8; | 1044 | sctp_max_retrans_init = 8; |
1045 | 1045 | ||
1046 | /* Sendbuffer growth - do per-socket accounting */ | ||
1047 | sctp_sndbuf_policy = 0; | ||
1048 | |||
1046 | /* HB.interval - 30 seconds */ | 1049 | /* HB.interval - 30 seconds */ |
1047 | sctp_hb_interval = 30 * HZ; | 1050 | sctp_hb_interval = 30 * HZ; |
1048 | 1051 | ||
@@ -1159,8 +1162,6 @@ SCTP_STATIC __init int sctp_init(void) | |||
1159 | status = 0; | 1162 | status = 0; |
1160 | out: | 1163 | out: |
1161 | return status; | 1164 | return status; |
1162 | err_add_protocol: | ||
1163 | proto_unregister(&sctp_prot); | ||
1164 | err_ctl_sock_init: | 1165 | err_ctl_sock_init: |
1165 | sctp_v6_exit(); | 1166 | sctp_v6_exit(); |
1166 | err_v6_init: | 1167 | err_v6_init: |
@@ -1188,6 +1189,8 @@ err_bucket_cachep: | |||
1188 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); | 1189 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); |
1189 | inet_unregister_protosw(&sctp_seqpacket_protosw); | 1190 | inet_unregister_protosw(&sctp_seqpacket_protosw); |
1190 | inet_unregister_protosw(&sctp_stream_protosw); | 1191 | inet_unregister_protosw(&sctp_stream_protosw); |
1192 | err_add_protocol: | ||
1193 | proto_unregister(&sctp_prot); | ||
1191 | goto out; | 1194 | goto out; |
1192 | } | 1195 | } |
1193 | 1196 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 1db12cc18cf7..33ac8bf47b0e 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -710,7 +710,9 @@ struct sctp_chunk *sctp_make_shutdown_complete( | |||
710 | struct sctp_chunk *retval; | 710 | struct sctp_chunk *retval; |
711 | __u8 flags = 0; | 711 | __u8 flags = 0; |
712 | 712 | ||
713 | /* Maybe set the T-bit if we have no association. */ | 713 | /* Set the T-bit if we have no association (vtag will be |
714 | * reflected) | ||
715 | */ | ||
714 | flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; | 716 | flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; |
715 | 717 | ||
716 | retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); | 718 | retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); |
@@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete( | |||
732 | } | 734 | } |
733 | 735 | ||
734 | /* Create an ABORT. Note that we set the T bit if we have no | 736 | /* Create an ABORT. Note that we set the T bit if we have no |
735 | * association. | 737 | * association, except when responding to an INIT (sctpimpguide 2.41). |
736 | */ | 738 | */ |
737 | struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, | 739 | struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, |
738 | const struct sctp_chunk *chunk, | 740 | const struct sctp_chunk *chunk, |
@@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, | |||
741 | struct sctp_chunk *retval; | 743 | struct sctp_chunk *retval; |
742 | __u8 flags = 0; | 744 | __u8 flags = 0; |
743 | 745 | ||
744 | /* Maybe set the T-bit if we have no association. */ | 746 | /* Set the T-bit if we have no association and 'chunk' is not |
745 | flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; | 747 | * an INIT (vtag will be reflected). |
748 | */ | ||
749 | if (!asoc) { | ||
750 | if (chunk && chunk->chunk_hdr && | ||
751 | chunk->chunk_hdr->type == SCTP_CID_INIT) | ||
752 | flags = 0; | ||
753 | else | ||
754 | flags = SCTP_CHUNK_FLAG_T; | ||
755 | } | ||
746 | 756 | ||
747 | retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); | 757 | retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); |
748 | 758 | ||
@@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, | |||
2744 | 2754 | ||
2745 | hint = (nstreams + 1) * sizeof(__u32); | 2755 | hint = (nstreams + 1) * sizeof(__u32); |
2746 | 2756 | ||
2747 | /* Maybe set the T-bit if we have no association. */ | ||
2748 | retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); | 2757 | retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); |
2749 | 2758 | ||
2750 | if (!retval) | 2759 | if (!retval) |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 278c56a2d076..8e01b8f09ac2 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -126,15 +126,18 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, | |||
126 | * should stop the T2-shutdown timer and remove all knowledge of the | 126 | * should stop the T2-shutdown timer and remove all knowledge of the |
127 | * association (and thus the association enters the CLOSED state). | 127 | * association (and thus the association enters the CLOSED state). |
128 | * | 128 | * |
129 | * Verification Tag: 8.5.1(C) | 129 | * Verification Tag: 8.5.1(C), sctpimpguide 2.41. |
130 | * C) Rules for packet carrying SHUTDOWN COMPLETE: | 130 | * C) Rules for packet carrying SHUTDOWN COMPLETE: |
131 | * ... | 131 | * ... |
132 | * - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the | 132 | * - The receiver of a SHUTDOWN COMPLETE shall accept the packet |
133 | * Verification Tag field of the packet matches its own tag OR it is | 133 | * if the Verification Tag field of the packet matches its own tag and |
134 | * set to its peer's tag and the T bit is set in the Chunk Flags. | 134 | * the T bit is not set |
135 | * Otherwise, the receiver MUST silently discard the packet and take | 135 | * OR |
136 | * no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if | 136 | * it is set to its peer's tag and the T bit is set in the Chunk |
137 | * it is not in the SHUTDOWN-ACK-SENT state. | 137 | * Flags. |
138 | * Otherwise, the receiver MUST silently discard the packet | ||
139 | * and take no further action. An endpoint MUST ignore the | ||
140 | * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state. | ||
138 | * | 141 | * |
139 | * Inputs | 142 | * Inputs |
140 | * (endpoint, asoc, chunk) | 143 | * (endpoint, asoc, chunk) |
@@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, | |||
2858 | /* | 2861 | /* |
2859 | * Generate an ABORT in response to a packet. | 2862 | * Generate an ABORT in response to a packet. |
2860 | * | 2863 | * |
2861 | * Section: 8.4 Handle "Out of the blue" Packets | 2864 | * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41 |
2862 | * | 2865 | * |
2863 | * 8) The receiver should respond to the sender of the OOTB packet | 2866 | * 8) The receiver should respond to the sender of the OOTB packet with |
2864 | * with an ABORT. When sending the ABORT, the receiver of the | 2867 | * an ABORT. When sending the ABORT, the receiver of the OOTB packet |
2865 | * OOTB packet MUST fill in the Verification Tag field of the | 2868 | * MUST fill in the Verification Tag field of the outbound packet |
2866 | * outbound packet with the value found in the Verification Tag | 2869 | * with the value found in the Verification Tag field of the OOTB |
2867 | * field of the OOTB packet and set the T-bit in the Chunk Flags | 2870 | * packet and set the T-bit in the Chunk Flags to indicate that the |
2868 | * to indicate that no TCB was found. After sending this ABORT, | 2871 | * Verification Tag is reflected. After sending this ABORT, the |
2869 | * the receiver of the OOTB packet shall discard the OOTB packet | 2872 | * receiver of the OOTB packet shall discard the OOTB packet and take |
2870 | * and take no further action. | 2873 | * no further action. |
2871 | * | 2874 | * |
2872 | * Verification Tag: | 2875 | * Verification Tag: |
2873 | * | 2876 | * |
@@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, | |||
2895 | return SCTP_DISPOSITION_NOMEM; | 2898 | return SCTP_DISPOSITION_NOMEM; |
2896 | } | 2899 | } |
2897 | 2900 | ||
2901 | /* Reflect vtag if T-Bit is set */ | ||
2902 | if (sctp_test_T_bit(abort)) | ||
2903 | packet->vtag = ntohl(chunk->sctp_hdr->vtag); | ||
2904 | |||
2898 | /* Set the skb to the belonging sock for accounting. */ | 2905 | /* Set the skb to the belonging sock for accounting. */ |
2899 | abort->skb->sk = ep->base.sk; | 2906 | abort->skb->sk = ep->base.sk; |
2900 | 2907 | ||
@@ -3026,22 +3033,24 @@ nomem: | |||
3026 | } | 3033 | } |
3027 | 3034 | ||
3028 | /* | 3035 | /* |
3029 | * RFC 2960, 8.4 - Handle "Out of the blue" Packets | 3036 | * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41. |
3037 | * | ||
3030 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should | 3038 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should |
3031 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. | 3039 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. |
3032 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB | 3040 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB |
3033 | * packet must fill in the Verification Tag field of the outbound | 3041 | * packet must fill in the Verification Tag field of the outbound |
3034 | * packet with the Verification Tag received in the SHUTDOWN ACK and | 3042 | * packet with the Verification Tag received in the SHUTDOWN ACK and |
3035 | * set the T-bit in the Chunk Flags to indicate that no TCB was | 3043 | * set the T-bit in the Chunk Flags to indicate that the Verification |
3036 | * found. Otherwise, | 3044 | * Tag is reflected. |
3037 | * | 3045 | * |
3038 | * 8) The receiver should respond to the sender of the OOTB packet with | 3046 | * 8) The receiver should respond to the sender of the OOTB packet with |
3039 | * an ABORT. When sending the ABORT, the receiver of the OOTB packet | 3047 | * an ABORT. When sending the ABORT, the receiver of the OOTB packet |
3040 | * MUST fill in the Verification Tag field of the outbound packet | 3048 | * MUST fill in the Verification Tag field of the outbound packet |
3041 | * with the value found in the Verification Tag field of the OOTB | 3049 | * with the value found in the Verification Tag field of the OOTB |
3042 | * packet and set the T-bit in the Chunk Flags to indicate that no | 3050 | * packet and set the T-bit in the Chunk Flags to indicate that the |
3043 | * TCB was found. After sending this ABORT, the receiver of the OOTB | 3051 | * Verification Tag is reflected. After sending this ABORT, the |
3044 | * packet shall discard the OOTB packet and take no further action. | 3052 | * receiver of the OOTB packet shall discard the OOTB packet and take |
3053 | * no further action. | ||
3045 | */ | 3054 | */ |
3046 | sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | 3055 | sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, |
3047 | const struct sctp_association *asoc, | 3056 | const struct sctp_association *asoc, |
@@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3090 | /* | 3099 | /* |
3091 | * Handle an "Out of the blue" SHUTDOWN ACK. | 3100 | * Handle an "Out of the blue" SHUTDOWN ACK. |
3092 | * | 3101 | * |
3093 | * Section: 8.4 5) | 3102 | * Section: 8.4 5, sctpimpguide 2.41. |
3103 | * | ||
3094 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should | 3104 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should |
3095 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. | 3105 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. |
3096 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet | 3106 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB |
3097 | * must fill in the Verification Tag field of the outbound packet with | 3107 | * packet must fill in the Verification Tag field of the outbound |
3098 | * the Verification Tag received in the SHUTDOWN ACK and set the | 3108 | * packet with the Verification Tag received in the SHUTDOWN ACK and |
3099 | * T-bit in the Chunk Flags to indicate that no TCB was found. | 3109 | * set the T-bit in the Chunk Flags to indicate that the Verification |
3110 | * Tag is reflected. | ||
3100 | * | 3111 | * |
3101 | * Inputs | 3112 | * Inputs |
3102 | * (endpoint, asoc, type, arg, commands) | 3113 | * (endpoint, asoc, type, arg, commands) |
@@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, | |||
3128 | return SCTP_DISPOSITION_NOMEM; | 3139 | return SCTP_DISPOSITION_NOMEM; |
3129 | } | 3140 | } |
3130 | 3141 | ||
3142 | /* Reflect vtag if T-Bit is set */ | ||
3143 | if (sctp_test_T_bit(shut)) | ||
3144 | packet->vtag = ntohl(chunk->sctp_hdr->vtag); | ||
3145 | |||
3131 | /* Set the skb to the belonging sock for accounting. */ | 3146 | /* Set the skb to the belonging sock for accounting. */ |
3132 | shut->skb->sk = ep->base.sk; | 3147 | shut->skb->sk = ep->base.sk; |
3133 | 3148 | ||
@@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep, | |||
3591 | * | 3606 | * |
3592 | * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST | 3607 | * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST |
3593 | * silently discard the OOTB packet and take no further action. | 3608 | * silently discard the OOTB packet and take no further action. |
3594 | * Otherwise, | ||
3595 | * | 3609 | * |
3596 | * Verification Tag: No verification necessary | 3610 | * Verification Tag: No verification necessary |
3597 | * | 3611 | * |
@@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, | |||
4961 | sctp_ootb_pkt_free(packet); | 4975 | sctp_ootb_pkt_free(packet); |
4962 | return NULL; | 4976 | return NULL; |
4963 | } | 4977 | } |
4978 | |||
4979 | /* Reflect vtag if T-Bit is set */ | ||
4980 | if (sctp_test_T_bit(abort)) | ||
4981 | packet->vtag = ntohl(chunk->sctp_hdr->vtag); | ||
4982 | |||
4964 | /* Add specified error causes, i.e., payload, to the | 4983 | /* Add specified error causes, i.e., payload, to the |
4965 | * end of the chunk. | 4984 | * end of the chunk. |
4966 | */ | 4985 | */ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index e8c210182571..0b338eca6dc0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -115,9 +115,17 @@ static inline int sctp_wspace(struct sctp_association *asoc) | |||
115 | struct sock *sk = asoc->base.sk; | 115 | struct sock *sk = asoc->base.sk; |
116 | int amt = 0; | 116 | int amt = 0; |
117 | 117 | ||
118 | amt = sk->sk_sndbuf - asoc->sndbuf_used; | 118 | if (asoc->ep->sndbuf_policy) { |
119 | /* make sure that no association uses more than sk_sndbuf */ | ||
120 | amt = sk->sk_sndbuf - asoc->sndbuf_used; | ||
121 | } else { | ||
122 | /* do socket level accounting */ | ||
123 | amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | ||
124 | } | ||
125 | |||
119 | if (amt < 0) | 126 | if (amt < 0) |
120 | amt = 0; | 127 | amt = 0; |
128 | |||
121 | return amt; | 129 | return amt; |
122 | } | 130 | } |
123 | 131 | ||
@@ -138,12 +146,21 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk) | |||
138 | /* The sndbuf space is tracked per association. */ | 146 | /* The sndbuf space is tracked per association. */ |
139 | sctp_association_hold(asoc); | 147 | sctp_association_hold(asoc); |
140 | 148 | ||
149 | skb_set_owner_w(chunk->skb, sk); | ||
150 | |||
141 | chunk->skb->destructor = sctp_wfree; | 151 | chunk->skb->destructor = sctp_wfree; |
142 | /* Save the chunk pointer in skb for sctp_wfree to use later. */ | 152 | /* Save the chunk pointer in skb for sctp_wfree to use later. */ |
143 | *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; | 153 | *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; |
144 | 154 | ||
145 | asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk); | 155 | asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) + |
146 | sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk); | 156 | sizeof(struct sk_buff) + |
157 | sizeof(struct sctp_chunk); | ||
158 | |||
159 | sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) + | ||
160 | sizeof(struct sk_buff) + | ||
161 | sizeof(struct sctp_chunk); | ||
162 | |||
163 | atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | ||
147 | } | 164 | } |
148 | 165 | ||
149 | /* Verify that this is a valid address. */ | 166 | /* Verify that this is a valid address. */ |
@@ -3473,7 +3490,7 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len, | |||
3473 | return -EINVAL; | 3490 | return -EINVAL; |
3474 | 3491 | ||
3475 | /* Values correspoinding to the specific association */ | 3492 | /* Values correspoinding to the specific association */ |
3476 | if (assocparams.sasoc_assoc_id != 0) { | 3493 | if (asoc) { |
3477 | assocparams.sasoc_asocmaxrxt = asoc->max_retrans; | 3494 | assocparams.sasoc_asocmaxrxt = asoc->max_retrans; |
3478 | assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; | 3495 | assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; |
3479 | assocparams.sasoc_local_rwnd = asoc->a_rwnd; | 3496 | assocparams.sasoc_local_rwnd = asoc->a_rwnd; |
@@ -4422,8 +4439,17 @@ static void sctp_wfree(struct sk_buff *skb) | |||
4422 | chunk = *((struct sctp_chunk **)(skb->cb)); | 4439 | chunk = *((struct sctp_chunk **)(skb->cb)); |
4423 | asoc = chunk->asoc; | 4440 | asoc = chunk->asoc; |
4424 | sk = asoc->base.sk; | 4441 | sk = asoc->base.sk; |
4425 | asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk); | 4442 | asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) + |
4426 | sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk); | 4443 | sizeof(struct sk_buff) + |
4444 | sizeof(struct sctp_chunk); | ||
4445 | |||
4446 | sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) + | ||
4447 | sizeof(struct sk_buff) + | ||
4448 | sizeof(struct sctp_chunk); | ||
4449 | |||
4450 | atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | ||
4451 | |||
4452 | sock_wfree(skb); | ||
4427 | __sctp_write_space(asoc); | 4453 | __sctp_write_space(asoc); |
4428 | 4454 | ||
4429 | sctp_association_put(asoc); | 4455 | sctp_association_put(asoc); |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 89fa20c73a5c..7fc31849312b 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -110,6 +110,14 @@ static ctl_table sctp_table[] = { | |||
110 | .proc_handler = &proc_dointvec | 110 | .proc_handler = &proc_dointvec |
111 | }, | 111 | }, |
112 | { | 112 | { |
113 | .ctl_name = NET_SCTP_SNDBUF_POLICY, | ||
114 | .procname = "sndbuf_policy", | ||
115 | .data = &sctp_sndbuf_policy, | ||
116 | .maxlen = sizeof(int), | ||
117 | .mode = 0644, | ||
118 | .proc_handler = &proc_dointvec | ||
119 | }, | ||
120 | { | ||
113 | .ctl_name = NET_SCTP_PATH_MAX_RETRANS, | 121 | .ctl_name = NET_SCTP_PATH_MAX_RETRANS, |
114 | .procname = "path_max_retrans", | 122 | .procname = "path_max_retrans", |
115 | .data = &sctp_max_retrans_path, | 123 | .data = &sctp_max_retrans_path, |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4484931018eb..67b9f035ba86 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -46,9 +46,9 @@ xdr_decode_netobj(u32 *p, struct xdr_netobj *obj) | |||
46 | 46 | ||
47 | /** | 47 | /** |
48 | * xdr_encode_opaque_fixed - Encode fixed length opaque data | 48 | * xdr_encode_opaque_fixed - Encode fixed length opaque data |
49 | * @p - pointer to current position in XDR buffer. | 49 | * @p: pointer to current position in XDR buffer. |
50 | * @ptr - pointer to data to encode (or NULL) | 50 | * @ptr: pointer to data to encode (or NULL) |
51 | * @nbytes - size of data. | 51 | * @nbytes: size of data. |
52 | * | 52 | * |
53 | * Copy the array of data of length nbytes at ptr to the XDR buffer | 53 | * Copy the array of data of length nbytes at ptr to the XDR buffer |
54 | * at position p, then align to the next 32-bit boundary by padding | 54 | * at position p, then align to the next 32-bit boundary by padding |
@@ -76,9 +76,9 @@ EXPORT_SYMBOL(xdr_encode_opaque_fixed); | |||
76 | 76 | ||
77 | /** | 77 | /** |
78 | * xdr_encode_opaque - Encode variable length opaque data | 78 | * xdr_encode_opaque - Encode variable length opaque data |
79 | * @p - pointer to current position in XDR buffer. | 79 | * @p: pointer to current position in XDR buffer. |
80 | * @ptr - pointer to data to encode (or NULL) | 80 | * @ptr: pointer to data to encode (or NULL) |
81 | * @nbytes - size of data. | 81 | * @nbytes: size of data. |
82 | * | 82 | * |
83 | * Returns the updated current XDR buffer position | 83 | * Returns the updated current XDR buffer position |
84 | */ | 84 | */ |
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index 956c17f6c548..d6844ac226f5 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c | |||
@@ -48,8 +48,8 @@ | |||
48 | #include <linux/kernel.h> | 48 | #include <linux/kernel.h> |
49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
50 | #include <linux/module.h> /* support for loadable modules */ | 50 | #include <linux/module.h> /* support for loadable modules */ |
51 | #include <linux/slab.h> /* kmalloc(), kfree() */ | 51 | #include <linux/slab.h> /* kmalloc(), kfree() */ |
52 | #include <linux/mm.h> /* verify_area(), etc. */ | 52 | #include <linux/mm.h> |
53 | #include <linux/string.h> /* inline mem*, str* functions */ | 53 | #include <linux/string.h> /* inline mem*, str* functions */ |
54 | 54 | ||
55 | #include <asm/byteorder.h> /* htons(), etc. */ | 55 | #include <asm/byteorder.h> /* htons(), etc. */ |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 80828078733d..55ed979db144 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1028,30 +1028,15 @@ static int stale_bundle(struct dst_entry *dst) | |||
1028 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); | 1028 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | static void xfrm_dst_destroy(struct dst_entry *dst) | 1031 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) |
1032 | { | 1032 | { |
1033 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
1034 | |||
1035 | dst_release(xdst->route); | ||
1036 | |||
1037 | if (!dst->xfrm) | ||
1038 | return; | ||
1039 | xfrm_state_put(dst->xfrm); | ||
1040 | dst->xfrm = NULL; | ||
1041 | } | ||
1042 | |||
1043 | static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
1044 | int unregister) | ||
1045 | { | ||
1046 | if (!unregister) | ||
1047 | return; | ||
1048 | |||
1049 | while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { | 1033 | while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { |
1050 | dst->dev = &loopback_dev; | 1034 | dst->dev = &loopback_dev; |
1051 | dev_hold(&loopback_dev); | 1035 | dev_hold(&loopback_dev); |
1052 | dev_put(dev); | 1036 | dev_put(dev); |
1053 | } | 1037 | } |
1054 | } | 1038 | } |
1039 | EXPORT_SYMBOL(xfrm_dst_ifdown); | ||
1055 | 1040 | ||
1056 | static void xfrm_link_failure(struct sk_buff *skb) | 1041 | static void xfrm_link_failure(struct sk_buff *skb) |
1057 | { | 1042 | { |
@@ -1262,10 +1247,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
1262 | dst_ops->kmem_cachep = xfrm_dst_cache; | 1247 | dst_ops->kmem_cachep = xfrm_dst_cache; |
1263 | if (likely(dst_ops->check == NULL)) | 1248 | if (likely(dst_ops->check == NULL)) |
1264 | dst_ops->check = xfrm_dst_check; | 1249 | dst_ops->check = xfrm_dst_check; |
1265 | if (likely(dst_ops->destroy == NULL)) | ||
1266 | dst_ops->destroy = xfrm_dst_destroy; | ||
1267 | if (likely(dst_ops->ifdown == NULL)) | ||
1268 | dst_ops->ifdown = xfrm_dst_ifdown; | ||
1269 | if (likely(dst_ops->negative_advice == NULL)) | 1250 | if (likely(dst_ops->negative_advice == NULL)) |
1270 | dst_ops->negative_advice = xfrm_negative_advice; | 1251 | dst_ops->negative_advice = xfrm_negative_advice; |
1271 | if (likely(dst_ops->link_failure == NULL)) | 1252 | if (likely(dst_ops->link_failure == NULL)) |
@@ -1297,8 +1278,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
1297 | xfrm_policy_afinfo[afinfo->family] = NULL; | 1278 | xfrm_policy_afinfo[afinfo->family] = NULL; |
1298 | dst_ops->kmem_cachep = NULL; | 1279 | dst_ops->kmem_cachep = NULL; |
1299 | dst_ops->check = NULL; | 1280 | dst_ops->check = NULL; |
1300 | dst_ops->destroy = NULL; | ||
1301 | dst_ops->ifdown = NULL; | ||
1302 | dst_ops->negative_advice = NULL; | 1281 | dst_ops->negative_advice = NULL; |
1303 | dst_ops->link_failure = NULL; | 1282 | dst_ops->link_failure = NULL; |
1304 | dst_ops->get_mss = NULL; | 1283 | dst_ops->get_mss = NULL; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 63661b0fd736..5ddda2c98af9 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -855,47 +855,44 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x | |||
855 | return 0; | 855 | return 0; |
856 | } | 856 | } |
857 | 857 | ||
858 | static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = { | 858 | #define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) |
859 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* NEW SA */ | 859 | |
860 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* DEL SA */ | 860 | static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { |
861 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* GET SA */ | 861 | [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), |
862 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* NEW POLICY */ | 862 | [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), |
863 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* DEL POLICY */ | 863 | [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), |
864 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* GET POLICY */ | 864 | [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), |
865 | NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)), /* ALLOC SPI */ | 865 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
866 | NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */ | 866 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
867 | NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */ | 867 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info), |
868 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */ | 868 | [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), |
869 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */ | 869 | [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire), |
870 | NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */ | 870 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), |
871 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */ | 871 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), |
872 | NLMSG_LENGTH(0), /* FLUSH POLICY */ | 872 | [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), |
873 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), | ||
874 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0), | ||
873 | }; | 875 | }; |
874 | 876 | ||
877 | #undef XMSGSIZE | ||
878 | |||
875 | static struct xfrm_link { | 879 | static struct xfrm_link { |
876 | int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); | 880 | int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); |
877 | int (*dump)(struct sk_buff *, struct netlink_callback *); | 881 | int (*dump)(struct sk_buff *, struct netlink_callback *); |
878 | } xfrm_dispatch[] = { | 882 | } xfrm_dispatch[XFRM_NR_MSGTYPES] = { |
879 | { .doit = xfrm_add_sa, }, | 883 | [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, |
880 | { .doit = xfrm_del_sa, }, | 884 | [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa }, |
881 | { | 885 | [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa, |
882 | .doit = xfrm_get_sa, | 886 | .dump = xfrm_dump_sa }, |
883 | .dump = xfrm_dump_sa, | 887 | [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, |
884 | }, | 888 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, |
885 | { .doit = xfrm_add_policy }, | 889 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, |
886 | { .doit = xfrm_get_policy }, | 890 | .dump = xfrm_dump_policy }, |
887 | { | 891 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, |
888 | .doit = xfrm_get_policy, | 892 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, |
889 | .dump = xfrm_dump_policy, | 893 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, |
890 | }, | 894 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, |
891 | { .doit = xfrm_alloc_userspi }, | 895 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, |
892 | {}, | ||
893 | {}, | ||
894 | { .doit = xfrm_add_policy }, | ||
895 | { .doit = xfrm_add_sa, }, | ||
896 | {}, | ||
897 | { .doit = xfrm_flush_sa }, | ||
898 | { .doit = xfrm_flush_policy }, | ||
899 | }; | 896 | }; |
900 | 897 | ||
901 | static int xfrm_done(struct netlink_callback *cb) | 898 | static int xfrm_done(struct netlink_callback *cb) |
@@ -931,7 +928,9 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
931 | return -1; | 928 | return -1; |
932 | } | 929 | } |
933 | 930 | ||
934 | if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) { | 931 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
932 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | ||
933 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | ||
935 | u32 rlen; | 934 | u32 rlen; |
936 | 935 | ||
937 | if (link->dump == NULL) | 936 | if (link->dump == NULL) |
@@ -1009,18 +1008,26 @@ static int xfrm_user_rcv_skb(struct sk_buff *skb) | |||
1009 | 1008 | ||
1010 | static void xfrm_netlink_rcv(struct sock *sk, int len) | 1009 | static void xfrm_netlink_rcv(struct sock *sk, int len) |
1011 | { | 1010 | { |
1011 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
1012 | |||
1012 | do { | 1013 | do { |
1013 | struct sk_buff *skb; | 1014 | struct sk_buff *skb; |
1014 | 1015 | ||
1015 | down(&xfrm_cfg_sem); | 1016 | down(&xfrm_cfg_sem); |
1016 | 1017 | ||
1017 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 1018 | if (qlen > skb_queue_len(&sk->sk_receive_queue)) |
1019 | qlen = skb_queue_len(&sk->sk_receive_queue); | ||
1020 | |||
1021 | for (; qlen; qlen--) { | ||
1022 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
1018 | if (xfrm_user_rcv_skb(skb)) { | 1023 | if (xfrm_user_rcv_skb(skb)) { |
1019 | if (skb->len) | 1024 | if (skb->len) |
1020 | skb_queue_head(&sk->sk_receive_queue, | 1025 | skb_queue_head(&sk->sk_receive_queue, |
1021 | skb); | 1026 | skb); |
1022 | else | 1027 | else { |
1023 | kfree_skb(skb); | 1028 | kfree_skb(skb); |
1029 | qlen--; | ||
1030 | } | ||
1024 | break; | 1031 | break; |
1025 | } | 1032 | } |
1026 | kfree_skb(skb); | 1033 | kfree_skb(skb); |
@@ -1028,7 +1035,7 @@ static void xfrm_netlink_rcv(struct sock *sk, int len) | |||
1028 | 1035 | ||
1029 | up(&xfrm_cfg_sem); | 1036 | up(&xfrm_cfg_sem); |
1030 | 1037 | ||
1031 | } while (xfrm_nl && xfrm_nl->sk_receive_queue.qlen); | 1038 | } while (qlen); |
1032 | } | 1039 | } |
1033 | 1040 | ||
1034 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) | 1041 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) |
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 090ffda4adbc..fe11df83d1fc 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
@@ -69,6 +69,7 @@ static struct sym_entry *table; | |||
69 | static int size, cnt; | 69 | static int size, cnt; |
70 | static unsigned long long _stext, _etext, _sinittext, _einittext; | 70 | static unsigned long long _stext, _etext, _sinittext, _einittext; |
71 | static int all_symbols = 0; | 71 | static int all_symbols = 0; |
72 | static char symbol_prefix_char = '\0'; | ||
72 | 73 | ||
73 | struct token { | 74 | struct token { |
74 | unsigned char data[MAX_TOK_SIZE]; | 75 | unsigned char data[MAX_TOK_SIZE]; |
@@ -93,7 +94,7 @@ unsigned char best_table_len[256]; | |||
93 | static void | 94 | static void |
94 | usage(void) | 95 | usage(void) |
95 | { | 96 | { |
96 | fprintf(stderr, "Usage: kallsyms [--all-symbols] < in.map > out.S\n"); | 97 | fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n"); |
97 | exit(1); | 98 | exit(1); |
98 | } | 99 | } |
99 | 100 | ||
@@ -112,6 +113,7 @@ static int | |||
112 | read_symbol(FILE *in, struct sym_entry *s) | 113 | read_symbol(FILE *in, struct sym_entry *s) |
113 | { | 114 | { |
114 | char str[500]; | 115 | char str[500]; |
116 | char *sym; | ||
115 | int rc; | 117 | int rc; |
116 | 118 | ||
117 | rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str); | 119 | rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str); |
@@ -123,27 +125,32 @@ read_symbol(FILE *in, struct sym_entry *s) | |||
123 | return -1; | 125 | return -1; |
124 | } | 126 | } |
125 | 127 | ||
128 | sym = str; | ||
129 | /* skip prefix char */ | ||
130 | if (symbol_prefix_char && str[0] == symbol_prefix_char) | ||
131 | sym++; | ||
132 | |||
126 | /* Ignore most absolute/undefined (?) symbols. */ | 133 | /* Ignore most absolute/undefined (?) symbols. */ |
127 | if (strcmp(str, "_stext") == 0) | 134 | if (strcmp(sym, "_stext") == 0) |
128 | _stext = s->addr; | 135 | _stext = s->addr; |
129 | else if (strcmp(str, "_etext") == 0) | 136 | else if (strcmp(sym, "_etext") == 0) |
130 | _etext = s->addr; | 137 | _etext = s->addr; |
131 | else if (strcmp(str, "_sinittext") == 0) | 138 | else if (strcmp(sym, "_sinittext") == 0) |
132 | _sinittext = s->addr; | 139 | _sinittext = s->addr; |
133 | else if (strcmp(str, "_einittext") == 0) | 140 | else if (strcmp(sym, "_einittext") == 0) |
134 | _einittext = s->addr; | 141 | _einittext = s->addr; |
135 | else if (toupper(s->type) == 'A') | 142 | else if (toupper(s->type) == 'A') |
136 | { | 143 | { |
137 | /* Keep these useful absolute symbols */ | 144 | /* Keep these useful absolute symbols */ |
138 | if (strcmp(str, "__kernel_syscall_via_break") && | 145 | if (strcmp(sym, "__kernel_syscall_via_break") && |
139 | strcmp(str, "__kernel_syscall_via_epc") && | 146 | strcmp(sym, "__kernel_syscall_via_epc") && |
140 | strcmp(str, "__kernel_sigtramp") && | 147 | strcmp(sym, "__kernel_sigtramp") && |
141 | strcmp(str, "__gp")) | 148 | strcmp(sym, "__gp")) |
142 | return -1; | 149 | return -1; |
143 | 150 | ||
144 | } | 151 | } |
145 | else if (toupper(s->type) == 'U' || | 152 | else if (toupper(s->type) == 'U' || |
146 | is_arm_mapping_symbol(str)) | 153 | is_arm_mapping_symbol(sym)) |
147 | return -1; | 154 | return -1; |
148 | 155 | ||
149 | /* include the type field in the symbol name, so that it gets | 156 | /* include the type field in the symbol name, so that it gets |
@@ -177,6 +184,11 @@ symbol_valid(struct sym_entry *s) | |||
177 | "_SDA2_BASE_", /* ppc */ | 184 | "_SDA2_BASE_", /* ppc */ |
178 | NULL }; | 185 | NULL }; |
179 | int i; | 186 | int i; |
187 | int offset = 1; | ||
188 | |||
189 | /* skip prefix char */ | ||
190 | if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char) | ||
191 | offset++; | ||
180 | 192 | ||
181 | /* if --all-symbols is not specified, then symbols outside the text | 193 | /* if --all-symbols is not specified, then symbols outside the text |
182 | * and inittext sections are discarded */ | 194 | * and inittext sections are discarded */ |
@@ -190,17 +202,17 @@ symbol_valid(struct sym_entry *s) | |||
190 | * they may get dropped in pass 2, which breaks the kallsyms | 202 | * they may get dropped in pass 2, which breaks the kallsyms |
191 | * rules. | 203 | * rules. |
192 | */ | 204 | */ |
193 | if ((s->addr == _etext && strcmp(s->sym + 1, "_etext")) || | 205 | if ((s->addr == _etext && strcmp(s->sym + offset, "_etext")) || |
194 | (s->addr == _einittext && strcmp(s->sym + 1, "_einittext"))) | 206 | (s->addr == _einittext && strcmp(s->sym + offset, "_einittext"))) |
195 | return 0; | 207 | return 0; |
196 | } | 208 | } |
197 | 209 | ||
198 | /* Exclude symbols which vary between passes. */ | 210 | /* Exclude symbols which vary between passes. */ |
199 | if (strstr(s->sym + 1, "_compiled.")) | 211 | if (strstr(s->sym + offset, "_compiled.")) |
200 | return 0; | 212 | return 0; |
201 | 213 | ||
202 | for (i = 0; special_symbols[i]; i++) | 214 | for (i = 0; special_symbols[i]; i++) |
203 | if( strcmp(s->sym + 1, special_symbols[i]) == 0 ) | 215 | if( strcmp(s->sym + offset, special_symbols[i]) == 0 ) |
204 | return 0; | 216 | return 0; |
205 | 217 | ||
206 | return 1; | 218 | return 1; |
@@ -225,9 +237,15 @@ read_map(FILE *in) | |||
225 | 237 | ||
226 | static void output_label(char *label) | 238 | static void output_label(char *label) |
227 | { | 239 | { |
228 | printf(".globl %s\n",label); | 240 | if (symbol_prefix_char) |
241 | printf(".globl %c%s\n", symbol_prefix_char, label); | ||
242 | else | ||
243 | printf(".globl %s\n", label); | ||
229 | printf("\tALGN\n"); | 244 | printf("\tALGN\n"); |
230 | printf("%s:\n",label); | 245 | if (symbol_prefix_char) |
246 | printf("%c%s:\n", symbol_prefix_char, label); | ||
247 | else | ||
248 | printf("%s:\n", label); | ||
231 | } | 249 | } |
232 | 250 | ||
233 | /* uncompress a compressed symbol. When this function is called, the best table | 251 | /* uncompress a compressed symbol. When this function is called, the best table |
@@ -665,6 +683,13 @@ static void optimize_token_table(void) | |||
665 | 683 | ||
666 | insert_real_symbols_in_table(); | 684 | insert_real_symbols_in_table(); |
667 | 685 | ||
686 | /* When valid symbol is not registered, exit to error */ | ||
687 | if (good_head.left == good_head.right && | ||
688 | bad_head.left == bad_head.right) { | ||
689 | fprintf(stderr, "No valid symbol.\n"); | ||
690 | exit(1); | ||
691 | } | ||
692 | |||
668 | optimize_result(); | 693 | optimize_result(); |
669 | } | 694 | } |
670 | 695 | ||
@@ -672,9 +697,21 @@ static void optimize_token_table(void) | |||
672 | int | 697 | int |
673 | main(int argc, char **argv) | 698 | main(int argc, char **argv) |
674 | { | 699 | { |
675 | if (argc == 2 && strcmp(argv[1], "--all-symbols") == 0) | 700 | if (argc >= 2) { |
676 | all_symbols = 1; | 701 | int i; |
677 | else if (argc != 1) | 702 | for (i = 1; i < argc; i++) { |
703 | if(strcmp(argv[i], "--all-symbols") == 0) | ||
704 | all_symbols = 1; | ||
705 | else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) { | ||
706 | char *p = &argv[i][16]; | ||
707 | /* skip quote */ | ||
708 | if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\'')) | ||
709 | p++; | ||
710 | symbol_prefix_char = *p; | ||
711 | } else | ||
712 | usage(); | ||
713 | } | ||
714 | } else if (argc != 1) | ||
678 | usage(); | 715 | usage(); |
679 | 716 | ||
680 | read_map(stdin); | 717 | read_map(stdin); |
@@ -683,4 +720,3 @@ main(int argc, char **argv) | |||
683 | 720 | ||
684 | return 0; | 721 | return 0; |
685 | } | 722 | } |
686 | |||
diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 8b1dab63f11c..0835dc2a8aa9 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc | |||
@@ -553,15 +553,20 @@ sub output_section_xml(%) { | |||
553 | # print out each section | 553 | # print out each section |
554 | $lineprefix=" "; | 554 | $lineprefix=" "; |
555 | foreach $section (@{$args{'sectionlist'}}) { | 555 | foreach $section (@{$args{'sectionlist'}}) { |
556 | print "<refsect1>\n <title>$section</title>\n <para>\n"; | 556 | print "<refsect1>\n"; |
557 | print "<title>$section</title>\n"; | ||
557 | if ($section =~ m/EXAMPLE/i) { | 558 | if ($section =~ m/EXAMPLE/i) { |
558 | print "<example><para>\n"; | 559 | print "<informalexample><programlisting>\n"; |
560 | } else { | ||
561 | print "<para>\n"; | ||
559 | } | 562 | } |
560 | output_highlight($args{'sections'}{$section}); | 563 | output_highlight($args{'sections'}{$section}); |
561 | if ($section =~ m/EXAMPLE/i) { | 564 | if ($section =~ m/EXAMPLE/i) { |
562 | print "</para></example>\n"; | 565 | print "</programlisting></informalexample>\n"; |
566 | } else { | ||
567 | print "</para>\n"; | ||
563 | } | 568 | } |
564 | print " </para>\n</refsect1>\n"; | 569 | print "</refsect1>\n"; |
565 | } | 570 | } |
566 | } | 571 | } |
567 | 572 | ||
@@ -576,8 +581,14 @@ sub output_function_xml(%) { | |||
576 | $id =~ s/[^A-Za-z0-9]/-/g; | 581 | $id =~ s/[^A-Za-z0-9]/-/g; |
577 | 582 | ||
578 | print "<refentry>\n"; | 583 | print "<refentry>\n"; |
584 | print "<refentryinfo>\n"; | ||
585 | print " <title>LINUX</title>\n"; | ||
586 | print " <productname>Kernel Hackers Manual</productname>\n"; | ||
587 | print " <date>$man_date</date>\n"; | ||
588 | print "</refentryinfo>\n"; | ||
579 | print "<refmeta>\n"; | 589 | print "<refmeta>\n"; |
580 | print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n"; | 590 | print " <refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n"; |
591 | print " <manvolnum>9</manvolnum>\n"; | ||
581 | print "</refmeta>\n"; | 592 | print "</refmeta>\n"; |
582 | print "<refnamediv>\n"; | 593 | print "<refnamediv>\n"; |
583 | print " <refname>".$args{'function'}."</refname>\n"; | 594 | print " <refname>".$args{'function'}."</refname>\n"; |
@@ -607,7 +618,7 @@ sub output_function_xml(%) { | |||
607 | } | 618 | } |
608 | } | 619 | } |
609 | } else { | 620 | } else { |
610 | print " <void>\n"; | 621 | print " <void/>\n"; |
611 | } | 622 | } |
612 | print " </funcprototype></funcsynopsis>\n"; | 623 | print " </funcprototype></funcsynopsis>\n"; |
613 | print "</refsynopsisdiv>\n"; | 624 | print "</refsynopsisdiv>\n"; |
@@ -646,8 +657,14 @@ sub output_struct_xml(%) { | |||
646 | $id =~ s/[^A-Za-z0-9]/-/g; | 657 | $id =~ s/[^A-Za-z0-9]/-/g; |
647 | 658 | ||
648 | print "<refentry>\n"; | 659 | print "<refentry>\n"; |
660 | print "<refentryinfo>\n"; | ||
661 | print " <title>LINUX</title>\n"; | ||
662 | print " <productname>Kernel Hackers Manual</productname>\n"; | ||
663 | print " <date>$man_date</date>\n"; | ||
664 | print "</refentryinfo>\n"; | ||
649 | print "<refmeta>\n"; | 665 | print "<refmeta>\n"; |
650 | print "<refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n"; | 666 | print " <refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n"; |
667 | print " <manvolnum>9</manvolnum>\n"; | ||
651 | print "</refmeta>\n"; | 668 | print "</refmeta>\n"; |
652 | print "<refnamediv>\n"; | 669 | print "<refnamediv>\n"; |
653 | print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n"; | 670 | print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n"; |
@@ -724,8 +741,14 @@ sub output_enum_xml(%) { | |||
724 | $id =~ s/[^A-Za-z0-9]/-/g; | 741 | $id =~ s/[^A-Za-z0-9]/-/g; |
725 | 742 | ||
726 | print "<refentry>\n"; | 743 | print "<refentry>\n"; |
744 | print "<refentryinfo>\n"; | ||
745 | print " <title>LINUX</title>\n"; | ||
746 | print " <productname>Kernel Hackers Manual</productname>\n"; | ||
747 | print " <date>$man_date</date>\n"; | ||
748 | print "</refentryinfo>\n"; | ||
727 | print "<refmeta>\n"; | 749 | print "<refmeta>\n"; |
728 | print "<refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n"; | 750 | print " <refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n"; |
751 | print " <manvolnum>9</manvolnum>\n"; | ||
729 | print "</refmeta>\n"; | 752 | print "</refmeta>\n"; |
730 | print "<refnamediv>\n"; | 753 | print "<refnamediv>\n"; |
731 | print " <refname>enum ".$args{'enum'}."</refname>\n"; | 754 | print " <refname>enum ".$args{'enum'}."</refname>\n"; |
@@ -784,8 +807,14 @@ sub output_typedef_xml(%) { | |||
784 | $id =~ s/[^A-Za-z0-9]/-/g; | 807 | $id =~ s/[^A-Za-z0-9]/-/g; |
785 | 808 | ||
786 | print "<refentry>\n"; | 809 | print "<refentry>\n"; |
810 | print "<refentryinfo>\n"; | ||
811 | print " <title>LINUX</title>\n"; | ||
812 | print " <productname>Kernel Hackers Manual</productname>\n"; | ||
813 | print " <date>$man_date</date>\n"; | ||
814 | print "</refentryinfo>\n"; | ||
787 | print "<refmeta>\n"; | 815 | print "<refmeta>\n"; |
788 | print "<refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n"; | 816 | print " <refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n"; |
817 | print " <manvolnum>9</manvolnum>\n"; | ||
789 | print "</refmeta>\n"; | 818 | print "</refmeta>\n"; |
790 | print "<refnamediv>\n"; | 819 | print "<refnamediv>\n"; |
791 | print " <refname>typedef ".$args{'typedef'}."</refname>\n"; | 820 | print " <refname>typedef ".$args{'typedef'}."</refname>\n"; |
@@ -1465,6 +1494,8 @@ sub dump_function($$) { | |||
1465 | 1494 | ||
1466 | $prototype =~ s/^static +//; | 1495 | $prototype =~ s/^static +//; |
1467 | $prototype =~ s/^extern +//; | 1496 | $prototype =~ s/^extern +//; |
1497 | $prototype =~ s/^fastcall +//; | ||
1498 | $prototype =~ s/^asmlinkage +//; | ||
1468 | $prototype =~ s/^inline +//; | 1499 | $prototype =~ s/^inline +//; |
1469 | $prototype =~ s/^__inline__ +//; | 1500 | $prototype =~ s/^__inline__ +//; |
1470 | $prototype =~ s/^#define +//; #ak added | 1501 | $prototype =~ s/^#define +//; #ak added |
diff --git a/scripts/makeman b/scripts/makeman deleted file mode 100755 index db3af647ee17..000000000000 --- a/scripts/makeman +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | #!/usr/bin/perl | ||
2 | |||
3 | use strict; | ||
4 | |||
5 | ## Copyright (C) Michael Still (mikal@stillhq.com) | ||
6 | ## Released under the terms of the GNU GPL | ||
7 | ## | ||
8 | ## A script to make or install the manpages extracted by split-man | ||
9 | ## | ||
10 | ## Arguements: $1 -- the word "convert" or "install" | ||
11 | ## $2 -- the directory containing the SGML files for the manpages | ||
12 | ## $3 -- the filename which contained the sgmldoc output | ||
13 | ## (I need this so I know which manpages to convert) | ||
14 | |||
15 | my($LISTING, $GENERATED, $INPUT, $OUTPUT, $front, $mode, $filename, $tmpdir); | ||
16 | |||
17 | if($ARGV[0] eq ""){ | ||
18 | die "Usage: makeman [convert | install] <dir> <file>\n"; | ||
19 | } | ||
20 | |||
21 | if( ! -d "$ARGV[1]" ){ | ||
22 | die "Output directory \"$ARGV[1]\" does not exist\n"; | ||
23 | } | ||
24 | |||
25 | if($ENV{"TMPDIR"} ne ""){ | ||
26 | $tmpdir = $ENV{"TMPDIR"}; | ||
27 | } | ||
28 | else{ | ||
29 | $tmpdir = "/tmp"; | ||
30 | } | ||
31 | |||
32 | if($ARGV[0] eq "convert"){ | ||
33 | open LISTING, "grep \"<refentrytitle>\" $ARGV[2] |"; | ||
34 | while(<LISTING>){ | ||
35 | s/<\/.*$//; | ||
36 | s/^.*>//; | ||
37 | s/\.sgml//; | ||
38 | s/struct //; | ||
39 | s/typedef //; | ||
40 | |||
41 | chomp; | ||
42 | $filename = $_; | ||
43 | print "Processing $filename\n"; | ||
44 | |||
45 | # Open the input file to extract the front matter, generate the man page, | ||
46 | # and open it, and the rearrange everything until it is happy | ||
47 | open INPUT, "< $ARGV[1]/$filename.sgml"; | ||
48 | $front = ""; | ||
49 | $mode = 0; | ||
50 | |||
51 | # The modes used here are: | ||
52 | # mode = 0 | ||
53 | # <!-- BEGINFRONTTAG --> | ||
54 | # <!-- <bookinfo> mode = 1 | ||
55 | # <!-- <legalnotice> mode = 2 | ||
56 | # <!-- ...GPL or whatever... | ||
57 | # <!-- </legalnotice> mode = 4 | ||
58 | # <!-- </bookinfo> mode = 3 | ||
59 | # <!-- ENDFRONTTAG --> | ||
60 | # | ||
61 | # ...doco... | ||
62 | |||
63 | # I know that some of the if statements in this while loop are in a funny | ||
64 | # order, but that is deliberate... | ||
65 | while(<INPUT>){ | ||
66 | if($mode > 0){ | ||
67 | s/<!-- //; | ||
68 | s/ -->//; | ||
69 | s/<docinfo>//i; | ||
70 | s<\/docinfo>//i; | ||
71 | s/^[ \t]*//i; | ||
72 | } | ||
73 | |||
74 | if($mode == 2){ | ||
75 | if(/<para>/i){ | ||
76 | } | ||
77 | elsif(/<\/para>/i){ | ||
78 | $front = "$front.\\\" \n"; | ||
79 | } | ||
80 | elsif(/<\/legalnotice>/i){ | ||
81 | $mode = 4; | ||
82 | } | ||
83 | elsif(/^[ \t]*$/){ | ||
84 | } | ||
85 | else{ | ||
86 | $front = "$front.\\\" $_"; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | if($mode == 1){ | ||
91 | if(/<title>(.*)<\/title>/i){ | ||
92 | $front = "$front.\\\" This documentation was generated from the book titled \"$1\", which is part of the Linux kernel source.\n.\\\" \n"; | ||
93 | } | ||
94 | elsif(/<legalnotice>/i){ | ||
95 | $front = "$front.\\\" This documentation comes with the following legal notice:\n.\\\" \n"; | ||
96 | $mode = 2; | ||
97 | } | ||
98 | |||
99 | elsif(/<author>/i){ | ||
100 | $front = "$front.\\\" Documentation by: "; | ||
101 | } | ||
102 | elsif(/<firstname>(.*)<\/firstname>/i){ | ||
103 | $front = "$front$1 "; | ||
104 | } | ||
105 | elsif(/<surname>(.*)<\/surname>/i){ | ||
106 | $front = "$front$1 "; | ||
107 | } | ||
108 | elsif(/<email>(.*)<\/email>/i){ | ||
109 | $front = "$front($1)"; | ||
110 | } | ||
111 | elsif(/\/author>/i){ | ||
112 | $front = "$front\n"; | ||
113 | } | ||
114 | |||
115 | elsif(/<copyright>/i){ | ||
116 | $front = "$front.\\\" Documentation copyright: "; | ||
117 | } | ||
118 | elsif(/<holder>(.*)<\/holder>/i){ | ||
119 | $front = "$front$1 "; | ||
120 | } | ||
121 | elsif(/<year>(.*)<\/year>/i){ | ||
122 | $front = "$front$1 "; | ||
123 | } | ||
124 | elsif(/\/copyright>/i){ | ||
125 | $front = "$front\n"; | ||
126 | } | ||
127 | |||
128 | elsif(/^[ \t]*$/ | ||
129 | || /<affiliation>/i | ||
130 | || /<\/affiliation>/i | ||
131 | || /<address>/i | ||
132 | || /<\/address>/i | ||
133 | || /<authorgroup>/i | ||
134 | || /<\/authorgroup>/i | ||
135 | || /<\/legalnotice>/i | ||
136 | || /<date>/i | ||
137 | || /<\/date>/i | ||
138 | || /<edition>/i | ||
139 | || /<\/edition>/i | ||
140 | || /<pubdate>/i | ||
141 | || /<\/pubdate>/i){ | ||
142 | } | ||
143 | else{ | ||
144 | print "Unknown tag in manpage conversion: $_"; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | if($mode == 0){ | ||
149 | if(/<bookinfo>/i){ | ||
150 | $mode = 1; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | if($mode == 4){ | ||
155 | if(/<\/bookinfo>/i){ | ||
156 | $mode = 3; | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | close INPUT; | ||
161 | |||
162 | system("cd $ARGV[1]; docbook2man $filename.sgml; mv $filename.9 $tmpdir/$$.9\n"); | ||
163 | open GENERATED, "< $tmpdir/$$.9"; | ||
164 | open OUTPUT, "> $ARGV[1]/$filename.9"; | ||
165 | |||
166 | print OUTPUT "$front"; | ||
167 | print OUTPUT ".\\\" For comments on the formatting of this manpage, please contact Michael Still <mikal\@stillhq.com>\n\n"; | ||
168 | while(<GENERATED>){ | ||
169 | print OUTPUT "$_"; | ||
170 | } | ||
171 | close OUTPUT; | ||
172 | close GENERATED; | ||
173 | |||
174 | system("gzip -f $ARGV[1]/$filename.9\n"); | ||
175 | unlink("$tmpdir/$$.9"); | ||
176 | } | ||
177 | } | ||
178 | elsif($ARGV[0] eq "install"){ | ||
179 | system("mkdir -p /usr/local/man/man9/; install $ARGV[1]/*.9.gz /usr/local/man/man9/"); | ||
180 | } | ||
181 | else{ | ||
182 | die "Usage: makeman [convert | install] <dir> <file>\n"; | ||
183 | } | ||
184 | |||
185 | print "Done\n"; | ||
diff --git a/scripts/split-man b/scripts/split-man deleted file mode 100755 index 03897fe6a75d..000000000000 --- a/scripts/split-man +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
1 | #!/usr/bin/perl | ||
2 | |||
3 | use strict; | ||
4 | |||
5 | ## Copyright (C) Michael Still (mikal@stillhq.com) | ||
6 | ## Released under the terms of the GNU GPL | ||
7 | ## | ||
8 | ## Hoon through the specified DocBook SGML file, and split out the | ||
9 | ## man pages. These can then be processed into groff format, and | ||
10 | ## installed if desired... | ||
11 | ## | ||
12 | ## Arguements: $1 -- the name of the sgml file | ||
13 | ## $2 -- the directory to put the generated SGML files in | ||
14 | ## $3 -- kernel version | ||
15 | |||
16 | my($SGML, $REF, $front, $refdata, $mode, $filename); | ||
17 | |||
18 | if(($ARGV[0] eq "") || ($ARGV[1] eq "") || ($ARGV[2] eq "")){ | ||
19 | die "Usage: split-man <sgml file> <output dir> <kernel version>\n"; | ||
20 | } | ||
21 | |||
22 | open SGML, "< $ARGV[0]" or die "Could not open input file \"$ARGV[0]\"\n"; | ||
23 | if( ! -d "$ARGV[1]" ){ | ||
24 | die "Output directory \"$ARGV[1]\" does not exist\n"; | ||
25 | } | ||
26 | |||
27 | # Possible modes: | ||
28 | # 0: Looking for input I care about | ||
29 | # 1: Inside book front matter | ||
30 | # 2: Inside a refentry | ||
31 | # 3: Inside a refentry, and we know the filename | ||
32 | |||
33 | $mode = 0; | ||
34 | $refdata = ""; | ||
35 | $front = ""; | ||
36 | while(<SGML>){ | ||
37 | # Starting modes | ||
38 | if(/<bookinfo>/ || /<docinfo>/){ | ||
39 | $mode = 1; | ||
40 | } | ||
41 | elsif(/<refentry>/){ | ||
42 | $mode = 2; | ||
43 | } | ||
44 | elsif(/<refentrytitle><phrase[^>]*>([^<]*)<.*$/){ | ||
45 | $mode = 3; | ||
46 | $filename = $1; | ||
47 | |||
48 | $filename =~ s/struct //; | ||
49 | $filename =~ s/typedef //; | ||
50 | |||
51 | print "Found manpage for $filename\n"; | ||
52 | open REF, "> $ARGV[1]/$filename.sgml" or | ||
53 | die "Couldn't open output file \"$ARGV[1]/$filename.sgml\": $!\n"; | ||
54 | print REF <<EOF; | ||
55 | <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN"> | ||
56 | |||
57 | <!-- BEGINFRONTTAG: The following is front matter for the parent book --> | ||
58 | $front | ||
59 | <!-- ENDFRONTTAG: End front matter --> | ||
60 | |||
61 | $refdata | ||
62 | EOF | ||
63 | $refdata = ""; | ||
64 | } | ||
65 | |||
66 | # Extraction | ||
67 | if($mode == 1){ | ||
68 | chomp $_; | ||
69 | $front = "$front<!-- $_ -->\n"; | ||
70 | } | ||
71 | elsif($mode == 2){ | ||
72 | $refdata = "$refdata$_"; | ||
73 | } | ||
74 | elsif($mode == 3){ | ||
75 | # There are some fixups which need to be applied | ||
76 | if(/<\/refmeta>/){ | ||
77 | print REF "<manvolnum>9</manvolnum>\n"; | ||
78 | } | ||
79 | if(/<\/refentry>/){ | ||
80 | print REF <<EOF; | ||
81 | <refsect1><title>About this document</title> | ||
82 | <para> | ||
83 | This documentation was generated with kernel version $ARGV[2]. | ||
84 | </para> | ||
85 | </refsect1> | ||
86 | EOF | ||
87 | } | ||
88 | |||
89 | # For some reason, we title the synopsis twice in the main DocBook | ||
90 | if(! /<title>Synopsis<\/title>/){ | ||
91 | if(/<refentrytitle>/){ | ||
92 | s/struct //; | ||
93 | s/typedef //; | ||
94 | } | ||
95 | |||
96 | print REF "$_"; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | # Ending modes | ||
101 | if(/<\/bookinfo>/ || /<\/docinfo>/){ | ||
102 | $mode = 0; | ||
103 | } | ||
104 | elsif(/<\/refentry>/){ | ||
105 | $mode = 0; | ||
106 | close REF; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | # And make sure we don't process this unnessesarily | ||
111 | $ARGV[0] =~ s/\.sgml/.9/; | ||
112 | `touch $ARGV[0]`; | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0d378141c95a..aae1e794fe48 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3667,7 +3667,7 @@ static void msg_msg_free_security(struct msg_msg *msg) | |||
3667 | } | 3667 | } |
3668 | 3668 | ||
3669 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | 3669 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, |
3670 | u16 sclass, u32 perms) | 3670 | u32 perms) |
3671 | { | 3671 | { |
3672 | struct task_security_struct *tsec; | 3672 | struct task_security_struct *tsec; |
3673 | struct ipc_security_struct *isec; | 3673 | struct ipc_security_struct *isec; |
@@ -3679,7 +3679,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
3679 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 3679 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
3680 | ad.u.ipc_id = ipc_perms->key; | 3680 | ad.u.ipc_id = ipc_perms->key; |
3681 | 3681 | ||
3682 | return avc_has_perm(tsec->sid, isec->sid, sclass, perms, &ad); | 3682 | return avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad); |
3683 | } | 3683 | } |
3684 | 3684 | ||
3685 | static int selinux_msg_msg_alloc_security(struct msg_msg *msg) | 3685 | static int selinux_msg_msg_alloc_security(struct msg_msg *msg) |
@@ -3764,7 +3764,7 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
3764 | return 0; | 3764 | return 0; |
3765 | } | 3765 | } |
3766 | 3766 | ||
3767 | err = ipc_has_perm(&msq->q_perm, SECCLASS_MSGQ, perms); | 3767 | err = ipc_has_perm(&msq->q_perm, perms); |
3768 | return err; | 3768 | return err; |
3769 | } | 3769 | } |
3770 | 3770 | ||
@@ -3916,7 +3916,7 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd) | |||
3916 | return 0; | 3916 | return 0; |
3917 | } | 3917 | } |
3918 | 3918 | ||
3919 | err = ipc_has_perm(&shp->shm_perm, SECCLASS_SHM, perms); | 3919 | err = ipc_has_perm(&shp->shm_perm, perms); |
3920 | return err; | 3920 | return err; |
3921 | } | 3921 | } |
3922 | 3922 | ||
@@ -3935,7 +3935,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, | |||
3935 | else | 3935 | else |
3936 | perms = SHM__READ | SHM__WRITE; | 3936 | perms = SHM__READ | SHM__WRITE; |
3937 | 3937 | ||
3938 | return ipc_has_perm(&shp->shm_perm, SECCLASS_SHM, perms); | 3938 | return ipc_has_perm(&shp->shm_perm, perms); |
3939 | } | 3939 | } |
3940 | 3940 | ||
3941 | /* Semaphore security operations */ | 3941 | /* Semaphore security operations */ |
@@ -4024,7 +4024,7 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd) | |||
4024 | return 0; | 4024 | return 0; |
4025 | } | 4025 | } |
4026 | 4026 | ||
4027 | err = ipc_has_perm(&sma->sem_perm, SECCLASS_SEM, perms); | 4027 | err = ipc_has_perm(&sma->sem_perm, perms); |
4028 | return err; | 4028 | return err; |
4029 | } | 4029 | } |
4030 | 4030 | ||
@@ -4038,18 +4038,13 @@ static int selinux_sem_semop(struct sem_array *sma, | |||
4038 | else | 4038 | else |
4039 | perms = SEM__READ; | 4039 | perms = SEM__READ; |
4040 | 4040 | ||
4041 | return ipc_has_perm(&sma->sem_perm, SECCLASS_SEM, perms); | 4041 | return ipc_has_perm(&sma->sem_perm, perms); |
4042 | } | 4042 | } |
4043 | 4043 | ||
4044 | static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | 4044 | static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) |
4045 | { | 4045 | { |
4046 | struct ipc_security_struct *isec = ipcp->security; | ||
4047 | u16 sclass = SECCLASS_IPC; | ||
4048 | u32 av = 0; | 4046 | u32 av = 0; |
4049 | 4047 | ||
4050 | if (isec && isec->magic == SELINUX_MAGIC) | ||
4051 | sclass = isec->sclass; | ||
4052 | |||
4053 | av = 0; | 4048 | av = 0; |
4054 | if (flag & S_IRUGO) | 4049 | if (flag & S_IRUGO) |
4055 | av |= IPC__UNIX_READ; | 4050 | av |= IPC__UNIX_READ; |
@@ -4059,7 +4054,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
4059 | if (av == 0) | 4054 | if (av == 0) |
4060 | return 0; | 4055 | return 0; |
4061 | 4056 | ||
4062 | return ipc_has_perm(ipcp, sclass, av); | 4057 | return ipc_has_perm(ipcp, av); |
4063 | } | 4058 | } |
4064 | 4059 | ||
4065 | /* module stacking operations */ | 4060 | /* module stacking operations */ |
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index eb340b45bc6f..8928bb4d3c53 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -220,6 +220,8 @@ | |||
220 | S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write") | 220 | S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write") |
221 | S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read") | 221 | S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read") |
222 | S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write") | 222 | S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write") |
223 | S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_RELAY, "nlmsg_relay") | ||
224 | S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV, "nlmsg_readpriv") | ||
223 | S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read") | 225 | S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read") |
224 | S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write") | 226 | S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write") |
225 | S_(SECCLASS_DBUS, DBUS__ACQUIRE_SVC, "acquire_svc") | 227 | S_(SECCLASS_DBUS, DBUS__ACQUIRE_SVC, "acquire_svc") |
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index f9de0f966559..bdfce4ca8f8e 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -840,6 +840,8 @@ | |||
840 | 840 | ||
841 | #define NETLINK_AUDIT_SOCKET__NLMSG_READ 0x00400000UL | 841 | #define NETLINK_AUDIT_SOCKET__NLMSG_READ 0x00400000UL |
842 | #define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL | 842 | #define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL |
843 | #define NETLINK_AUDIT_SOCKET__NLMSG_RELAY 0x01000000UL | ||
844 | #define NETLINK_AUDIT_SOCKET__NLMSG_READPRIV 0x02000000UL | ||
843 | 845 | ||
844 | #define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL | 846 | #define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL |
845 | #define NETLINK_IP6FW_SOCKET__READ 0x00000002UL | 847 | #define NETLINK_IP6FW_SOCKET__READ 0x00000002UL |
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index f79408252730..b3adb481bc25 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c | |||
@@ -91,13 +91,12 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] = | |||
91 | 91 | ||
92 | static struct nlmsg_perm nlmsg_audit_perms[] = | 92 | static struct nlmsg_perm nlmsg_audit_perms[] = |
93 | { | 93 | { |
94 | { AUDIT_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ }, | 94 | { AUDIT_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ }, |
95 | { AUDIT_SET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, | 95 | { AUDIT_SET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, |
96 | { AUDIT_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READ }, | 96 | { AUDIT_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV }, |
97 | { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, | 97 | { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, |
98 | { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, | 98 | { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, |
99 | { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, | 99 | { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY }, |
100 | { AUDIT_LOGIN, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, | ||
101 | }; | 100 | }; |
102 | 101 | ||
103 | 102 | ||
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c index e1d69611a257..06047e7979af 100644 --- a/sound/oss/sonicvibes.c +++ b/sound/oss/sonicvibes.c | |||
@@ -1149,7 +1149,7 @@ static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg) | |||
1149 | if (mixtable[i].rec) | 1149 | if (mixtable[i].rec) |
1150 | break; | 1150 | break; |
1151 | } | 1151 | } |
1152 | if (!mixtable[i].rec) | 1152 | if (i == SOUND_MIXER_NRDEVICES) |
1153 | return 0; | 1153 | return 0; |
1154 | spin_lock_irqsave(&s->lock, flags); | 1154 | spin_lock_irqsave(&s->lock, flags); |
1155 | frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5); | 1155 | frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d89647a3d449..959953ca320a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -64,7 +64,8 @@ MODULE_PARM_DESC(model, "Use the given board model."); | |||
64 | MODULE_LICENSE("GPL"); | 64 | MODULE_LICENSE("GPL"); |
65 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | 65 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," |
66 | "{Intel, ICH6M}," | 66 | "{Intel, ICH6M}," |
67 | "{Intel, ICH7}}"); | 67 | "{Intel, ICH7}," |
68 | "{Intel, ESB2}}"); | ||
68 | MODULE_DESCRIPTION("Intel HDA driver"); | 69 | MODULE_DESCRIPTION("Intel HDA driver"); |
69 | 70 | ||
70 | #define SFX "hda-intel: " | 71 | #define SFX "hda-intel: " |
@@ -1422,6 +1423,7 @@ static void __devexit azx_remove(struct pci_dev *pci) | |||
1422 | static struct pci_device_id azx_ids[] = { | 1423 | static struct pci_device_id azx_ids[] = { |
1423 | { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH6 */ | 1424 | { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH6 */ |
1424 | { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH7 */ | 1425 | { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH7 */ |
1426 | { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ESB2 */ | ||
1425 | { 0, } | 1427 | { 0, } |
1426 | }; | 1428 | }; |
1427 | MODULE_DEVICE_TABLE(pci, azx_ids); | 1429 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile index 4d95c652c8ca..d6ba9959097b 100644 --- a/sound/ppc/Makefile +++ b/sound/ppc/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> | 3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> |
4 | # | 4 | # |
5 | 5 | ||
6 | snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o | 6 | snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o toonie.o keywest.o beep.o |
7 | 7 | ||
8 | # Toplevel Module Dependency | 8 | # Toplevel Module Dependency |
9 | obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o | 9 | obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 3bf5f069a03d..32d94754acf8 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -986,7 +986,13 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
986 | chip->num_freqs = ARRAY_SIZE(tumbler_freqs); | 986 | chip->num_freqs = ARRAY_SIZE(tumbler_freqs); |
987 | chip->model = PMAC_SNAPPER; | 987 | chip->model = PMAC_SNAPPER; |
988 | chip->can_byte_swap = 0; /* FIXME: check this */ | 988 | chip->can_byte_swap = 0; /* FIXME: check this */ |
989 | chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ | 989 | chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */ |
990 | break; | ||
991 | case 0x3a: | ||
992 | chip->num_freqs = ARRAY_SIZE(tumbler_freqs); | ||
993 | chip->model = PMAC_TOONIE; | ||
994 | chip->can_byte_swap = 0; /* FIXME: check this */ | ||
995 | chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */ | ||
990 | break; | 996 | break; |
991 | } | 997 | } |
992 | } | 998 | } |
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h index dc6c99dd14e7..0a84c05f714b 100644 --- a/sound/ppc/pmac.h +++ b/sound/ppc/pmac.h | |||
@@ -94,7 +94,8 @@ struct snd_pmac_stream { | |||
94 | */ | 94 | */ |
95 | 95 | ||
96 | enum snd_pmac_model { | 96 | enum snd_pmac_model { |
97 | PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER, PMAC_SNAPPER | 97 | PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER, |
98 | PMAC_SNAPPER, PMAC_TOONIE | ||
98 | }; | 99 | }; |
99 | 100 | ||
100 | struct snd_pmac { | 101 | struct snd_pmac { |
@@ -191,6 +192,7 @@ int snd_pmac_burgundy_init(pmac_t *chip); | |||
191 | int snd_pmac_daca_init(pmac_t *chip); | 192 | int snd_pmac_daca_init(pmac_t *chip); |
192 | int snd_pmac_tumbler_init(pmac_t *chip); | 193 | int snd_pmac_tumbler_init(pmac_t *chip); |
193 | int snd_pmac_tumbler_post_init(void); | 194 | int snd_pmac_tumbler_post_init(void); |
195 | int snd_pmac_toonie_init(pmac_t *chip); | ||
194 | 196 | ||
195 | /* i2c functions */ | 197 | /* i2c functions */ |
196 | typedef struct snd_pmac_keywest { | 198 | typedef struct snd_pmac_keywest { |
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c index 8f1953a8e290..231f6432ea6d 100644 --- a/sound/ppc/powermac.c +++ b/sound/ppc/powermac.c | |||
@@ -95,6 +95,13 @@ static int __init snd_pmac_probe(void) | |||
95 | if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0) | 95 | if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0) |
96 | goto __error; | 96 | goto __error; |
97 | break; | 97 | break; |
98 | case PMAC_TOONIE: | ||
99 | strcpy(card->driver, "PMac Toonie"); | ||
100 | strcpy(card->shortname, "PowerMac Toonie"); | ||
101 | strcpy(card->longname, card->shortname); | ||
102 | if ((err = snd_pmac_toonie_init(chip)) < 0) | ||
103 | goto __error; | ||
104 | break; | ||
98 | case PMAC_AWACS: | 105 | case PMAC_AWACS: |
99 | case PMAC_SCREAMER: | 106 | case PMAC_SCREAMER: |
100 | name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS"; | 107 | name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS"; |
diff --git a/sound/ppc/toonie.c b/sound/ppc/toonie.c new file mode 100644 index 000000000000..082bc4babab5 --- /dev/null +++ b/sound/ppc/toonie.c | |||
@@ -0,0 +1,379 @@ | |||
1 | /* | ||
2 | * Mac Mini "toonie" mixer control | ||
3 | * | ||
4 | * Copyright (c) 2005 by Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <sound/driver.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/i2c-dev.h> | ||
26 | #include <linux/kmod.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <sound/core.h> | ||
30 | #include <asm/io.h> | ||
31 | #include <asm/irq.h> | ||
32 | #include <asm/machdep.h> | ||
33 | #include <asm/pmac_feature.h> | ||
34 | #include "pmac.h" | ||
35 | |||
36 | #undef DEBUG | ||
37 | |||
38 | #ifdef DEBUG | ||
39 | #define DBG(fmt...) printk(fmt) | ||
40 | #else | ||
41 | #define DBG(fmt...) | ||
42 | #endif | ||
43 | |||
44 | struct pmac_gpio { | ||
45 | unsigned int addr; | ||
46 | u8 active_val; | ||
47 | u8 inactive_val; | ||
48 | u8 active_state; | ||
49 | }; | ||
50 | |||
51 | struct pmac_toonie | ||
52 | { | ||
53 | struct pmac_gpio hp_detect_gpio; | ||
54 | struct pmac_gpio hp_mute_gpio; | ||
55 | struct pmac_gpio amp_mute_gpio; | ||
56 | int hp_detect_irq; | ||
57 | int auto_mute_notify; | ||
58 | struct work_struct detect_work; | ||
59 | }; | ||
60 | |||
61 | |||
62 | /* | ||
63 | * gpio access | ||
64 | */ | ||
65 | #define do_gpio_write(gp, val) \ | ||
66 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val) | ||
67 | #define do_gpio_read(gp) \ | ||
68 | pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0) | ||
69 | #define tumbler_gpio_free(gp) /* NOP */ | ||
70 | |||
71 | static void write_audio_gpio(struct pmac_gpio *gp, int active) | ||
72 | { | ||
73 | if (! gp->addr) | ||
74 | return; | ||
75 | active = active ? gp->active_val : gp->inactive_val; | ||
76 | do_gpio_write(gp, active); | ||
77 | DBG("(I) gpio %x write %d\n", gp->addr, active); | ||
78 | } | ||
79 | |||
80 | static int check_audio_gpio(struct pmac_gpio *gp) | ||
81 | { | ||
82 | int ret; | ||
83 | |||
84 | if (! gp->addr) | ||
85 | return 0; | ||
86 | |||
87 | ret = do_gpio_read(gp); | ||
88 | |||
89 | return (ret & 0xd) == (gp->active_val & 0xd); | ||
90 | } | ||
91 | |||
92 | static int read_audio_gpio(struct pmac_gpio *gp) | ||
93 | { | ||
94 | int ret; | ||
95 | if (! gp->addr) | ||
96 | return 0; | ||
97 | ret = ((do_gpio_read(gp) & 0x02) !=0); | ||
98 | return ret == gp->active_state; | ||
99 | } | ||
100 | |||
101 | |||
102 | enum { TOONIE_MUTE_HP, TOONIE_MUTE_AMP }; | ||
103 | |||
104 | static int toonie_get_mute_switch(snd_kcontrol_t *kcontrol, | ||
105 | snd_ctl_elem_value_t *ucontrol) | ||
106 | { | ||
107 | pmac_t *chip = snd_kcontrol_chip(kcontrol); | ||
108 | struct pmac_toonie *mix = chip->mixer_data; | ||
109 | struct pmac_gpio *gp; | ||
110 | |||
111 | if (mix == NULL) | ||
112 | return -ENODEV; | ||
113 | switch(kcontrol->private_value) { | ||
114 | case TOONIE_MUTE_HP: | ||
115 | gp = &mix->hp_mute_gpio; | ||
116 | break; | ||
117 | case TOONIE_MUTE_AMP: | ||
118 | gp = &mix->amp_mute_gpio; | ||
119 | break; | ||
120 | default: | ||
121 | return -EINVAL;; | ||
122 | } | ||
123 | ucontrol->value.integer.value[0] = !check_audio_gpio(gp); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int toonie_put_mute_switch(snd_kcontrol_t *kcontrol, | ||
128 | snd_ctl_elem_value_t *ucontrol) | ||
129 | { | ||
130 | pmac_t *chip = snd_kcontrol_chip(kcontrol); | ||
131 | struct pmac_toonie *mix = chip->mixer_data; | ||
132 | struct pmac_gpio *gp; | ||
133 | int val; | ||
134 | |||
135 | if (chip->update_automute && chip->auto_mute) | ||
136 | return 0; /* don't touch in the auto-mute mode */ | ||
137 | |||
138 | if (mix == NULL) | ||
139 | return -ENODEV; | ||
140 | |||
141 | switch(kcontrol->private_value) { | ||
142 | case TOONIE_MUTE_HP: | ||
143 | gp = &mix->hp_mute_gpio; | ||
144 | break; | ||
145 | case TOONIE_MUTE_AMP: | ||
146 | gp = &mix->amp_mute_gpio; | ||
147 | break; | ||
148 | default: | ||
149 | return -EINVAL;; | ||
150 | } | ||
151 | val = ! check_audio_gpio(gp); | ||
152 | if (val != ucontrol->value.integer.value[0]) { | ||
153 | write_audio_gpio(gp, ! ucontrol->value.integer.value[0]); | ||
154 | return 1; | ||
155 | } | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static snd_kcontrol_new_t toonie_hp_sw __initdata = { | ||
160 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
161 | .name = "Headphone Playback Switch", | ||
162 | .info = snd_pmac_boolean_mono_info, | ||
163 | .get = toonie_get_mute_switch, | ||
164 | .put = toonie_put_mute_switch, | ||
165 | .private_value = TOONIE_MUTE_HP, | ||
166 | }; | ||
167 | static snd_kcontrol_new_t toonie_speaker_sw __initdata = { | ||
168 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
169 | .name = "PC Speaker Playback Switch", | ||
170 | .info = snd_pmac_boolean_mono_info, | ||
171 | .get = toonie_get_mute_switch, | ||
172 | .put = toonie_put_mute_switch, | ||
173 | .private_value = TOONIE_MUTE_AMP, | ||
174 | }; | ||
175 | |||
176 | /* | ||
177 | * auto-mute stuffs | ||
178 | */ | ||
179 | static int toonie_detect_headphone(pmac_t *chip) | ||
180 | { | ||
181 | struct pmac_toonie *mix = chip->mixer_data; | ||
182 | int detect = 0; | ||
183 | |||
184 | if (mix->hp_detect_gpio.addr) | ||
185 | detect |= read_audio_gpio(&mix->hp_detect_gpio); | ||
186 | return detect; | ||
187 | } | ||
188 | |||
189 | static void toonie_check_mute(pmac_t *chip, struct pmac_gpio *gp, int val, | ||
190 | int do_notify, snd_kcontrol_t *sw) | ||
191 | { | ||
192 | if (check_audio_gpio(gp) != val) { | ||
193 | write_audio_gpio(gp, val); | ||
194 | if (do_notify) | ||
195 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
196 | &sw->id); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | static void toonie_detect_handler(void *self) | ||
201 | { | ||
202 | pmac_t *chip = (pmac_t*) self; | ||
203 | struct pmac_toonie *mix; | ||
204 | int headphone; | ||
205 | |||
206 | if (!chip) | ||
207 | return; | ||
208 | |||
209 | mix = chip->mixer_data; | ||
210 | snd_assert(mix, return); | ||
211 | |||
212 | headphone = toonie_detect_headphone(chip); | ||
213 | |||
214 | DBG("headphone: %d, lineout: %d\n", headphone, lineout); | ||
215 | |||
216 | if (headphone) { | ||
217 | /* unmute headphone/lineout & mute speaker */ | ||
218 | toonie_check_mute(chip, &mix->hp_mute_gpio, 0, | ||
219 | mix->auto_mute_notify, chip->master_sw_ctl); | ||
220 | toonie_check_mute(chip, &mix->amp_mute_gpio, 1, | ||
221 | mix->auto_mute_notify, chip->speaker_sw_ctl); | ||
222 | } else { | ||
223 | /* unmute speaker, mute others */ | ||
224 | toonie_check_mute(chip, &mix->amp_mute_gpio, 0, | ||
225 | mix->auto_mute_notify, chip->speaker_sw_ctl); | ||
226 | toonie_check_mute(chip, &mix->hp_mute_gpio, 1, | ||
227 | mix->auto_mute_notify, chip->master_sw_ctl); | ||
228 | } | ||
229 | if (mix->auto_mute_notify) { | ||
230 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
231 | &chip->hp_detect_ctl->id); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | static void toonie_update_automute(pmac_t *chip, int do_notify) | ||
236 | { | ||
237 | if (chip->auto_mute) { | ||
238 | struct pmac_toonie *mix; | ||
239 | mix = chip->mixer_data; | ||
240 | snd_assert(mix, return); | ||
241 | mix->auto_mute_notify = do_notify; | ||
242 | schedule_work(&mix->detect_work); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /* interrupt - headphone plug changed */ | ||
247 | static irqreturn_t toonie_hp_intr(int irq, void *devid, struct pt_regs *regs) | ||
248 | { | ||
249 | pmac_t *chip = devid; | ||
250 | |||
251 | if (chip->update_automute && chip->initialized) { | ||
252 | chip->update_automute(chip, 1); | ||
253 | return IRQ_HANDLED; | ||
254 | } | ||
255 | return IRQ_NONE; | ||
256 | } | ||
257 | |||
258 | /* look for audio gpio device */ | ||
259 | static int find_audio_gpio(const char *name, const char *platform, | ||
260 | struct pmac_gpio *gp) | ||
261 | { | ||
262 | struct device_node *np; | ||
263 | u32 *base, addr; | ||
264 | |||
265 | if (! (np = find_devices("gpio"))) | ||
266 | return -ENODEV; | ||
267 | |||
268 | for (np = np->child; np; np = np->sibling) { | ||
269 | char *property = get_property(np, "audio-gpio", NULL); | ||
270 | if (property && strcmp(property, name) == 0) | ||
271 | break; | ||
272 | if (device_is_compatible(np, name)) | ||
273 | break; | ||
274 | } | ||
275 | if (np == NULL) | ||
276 | return -ENODEV; | ||
277 | |||
278 | base = (u32 *)get_property(np, "AAPL,address", NULL); | ||
279 | if (! base) { | ||
280 | base = (u32 *)get_property(np, "reg", NULL); | ||
281 | if (!base) { | ||
282 | DBG("(E) cannot find address for device %s !\n", name); | ||
283 | return -ENODEV; | ||
284 | } | ||
285 | addr = *base; | ||
286 | if (addr < 0x50) | ||
287 | addr += 0x50; | ||
288 | } else | ||
289 | addr = *base; | ||
290 | |||
291 | gp->addr = addr & 0x0000ffff; | ||
292 | |||
293 | /* Try to find the active state, default to 0 ! */ | ||
294 | base = (u32 *)get_property(np, "audio-gpio-active-state", NULL); | ||
295 | if (base) { | ||
296 | gp->active_state = *base; | ||
297 | gp->active_val = (*base) ? 0x5 : 0x4; | ||
298 | gp->inactive_val = (*base) ? 0x4 : 0x5; | ||
299 | } else { | ||
300 | u32 *prop = NULL; | ||
301 | gp->active_state = 0; | ||
302 | gp->active_val = 0x4; | ||
303 | gp->inactive_val = 0x5; | ||
304 | /* Here are some crude hacks to extract the GPIO polarity and | ||
305 | * open collector informations out of the do-platform script | ||
306 | * as we don't yet have an interpreter for these things | ||
307 | */ | ||
308 | if (platform) | ||
309 | prop = (u32 *)get_property(np, platform, NULL); | ||
310 | if (prop) { | ||
311 | if (prop[3] == 0x9 && prop[4] == 0x9) { | ||
312 | gp->active_val = 0xd; | ||
313 | gp->inactive_val = 0xc; | ||
314 | } | ||
315 | if (prop[3] == 0x1 && prop[4] == 0x1) { | ||
316 | gp->active_val = 0x5; | ||
317 | gp->inactive_val = 0x4; | ||
318 | } | ||
319 | } | ||
320 | } | ||
321 | |||
322 | DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n", | ||
323 | name, gp->addr, gp->active_state); | ||
324 | |||
325 | return (np->n_intrs > 0) ? np->intrs[0].line : 0; | ||
326 | } | ||
327 | |||
328 | static void toonie_cleanup(pmac_t *chip) | ||
329 | { | ||
330 | struct pmac_toonie *mix = chip->mixer_data; | ||
331 | if (! mix) | ||
332 | return; | ||
333 | if (mix->hp_detect_irq >= 0) | ||
334 | free_irq(mix->hp_detect_irq, chip); | ||
335 | kfree(mix); | ||
336 | chip->mixer_data = NULL; | ||
337 | } | ||
338 | |||
339 | int snd_pmac_toonie_init(pmac_t *chip) | ||
340 | { | ||
341 | struct pmac_toonie *mix; | ||
342 | |||
343 | mix = kmalloc(sizeof(*mix), GFP_KERNEL); | ||
344 | if (! mix) | ||
345 | return -ENOMEM; | ||
346 | |||
347 | chip->mixer_data = mix; | ||
348 | chip->mixer_free = toonie_cleanup; | ||
349 | |||
350 | find_audio_gpio("headphone-mute", NULL, &mix->hp_mute_gpio); | ||
351 | find_audio_gpio("amp-mute", NULL, &mix->amp_mute_gpio); | ||
352 | mix->hp_detect_irq = find_audio_gpio("headphone-detect", | ||
353 | NULL, &mix->hp_detect_gpio); | ||
354 | |||
355 | strcpy(chip->card->mixername, "PowerMac Toonie"); | ||
356 | |||
357 | chip->master_sw_ctl = snd_ctl_new1(&toonie_hp_sw, chip); | ||
358 | snd_ctl_add(chip->card, chip->master_sw_ctl); | ||
359 | |||
360 | chip->speaker_sw_ctl = snd_ctl_new1(&toonie_speaker_sw, chip); | ||
361 | snd_ctl_add(chip->card, chip->speaker_sw_ctl); | ||
362 | |||
363 | INIT_WORK(&mix->detect_work, toonie_detect_handler, (void *)chip); | ||
364 | |||
365 | if (mix->hp_detect_irq >= 0) { | ||
366 | snd_pmac_add_automute(chip); | ||
367 | |||
368 | chip->detect_headphone = toonie_detect_headphone; | ||
369 | chip->update_automute = toonie_update_automute; | ||
370 | toonie_update_automute(chip, 0); | ||
371 | |||
372 | if (request_irq(mix->hp_detect_irq, toonie_hp_intr, 0, | ||
373 | "Sound Headphone Detection", chip) < 0) | ||
374 | mix->hp_detect_irq = -1; | ||
375 | } | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index c71807e069ee..9332237cb6a4 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -99,6 +99,7 @@ typedef struct pmac_tumbler_t { | |||
99 | pmac_gpio_t hp_detect; | 99 | pmac_gpio_t hp_detect; |
100 | int headphone_irq; | 100 | int headphone_irq; |
101 | int lineout_irq; | 101 | int lineout_irq; |
102 | unsigned int save_master_vol[2]; | ||
102 | unsigned int master_vol[2]; | 103 | unsigned int master_vol[2]; |
103 | unsigned int save_master_switch[2]; | 104 | unsigned int save_master_switch[2]; |
104 | unsigned int master_switch[2]; | 105 | unsigned int master_switch[2]; |
@@ -177,11 +178,22 @@ static void write_audio_gpio(pmac_gpio_t *gp, int active) | |||
177 | if (! gp->addr) | 178 | if (! gp->addr) |
178 | return; | 179 | return; |
179 | active = active ? gp->active_val : gp->inactive_val; | 180 | active = active ? gp->active_val : gp->inactive_val; |
180 | |||
181 | do_gpio_write(gp, active); | 181 | do_gpio_write(gp, active); |
182 | DBG("(I) gpio %x write %d\n", gp->addr, active); | 182 | DBG("(I) gpio %x write %d\n", gp->addr, active); |
183 | } | 183 | } |
184 | 184 | ||
185 | static int check_audio_gpio(pmac_gpio_t *gp) | ||
186 | { | ||
187 | int ret; | ||
188 | |||
189 | if (! gp->addr) | ||
190 | return 0; | ||
191 | |||
192 | ret = do_gpio_read(gp); | ||
193 | |||
194 | return (ret & 0xd) == (gp->active_val & 0xd); | ||
195 | } | ||
196 | |||
185 | static int read_audio_gpio(pmac_gpio_t *gp) | 197 | static int read_audio_gpio(pmac_gpio_t *gp) |
186 | { | 198 | { |
187 | int ret; | 199 | int ret; |
@@ -683,7 +695,7 @@ static int tumbler_get_mute_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_ | |||
683 | } | 695 | } |
684 | if (gp == NULL) | 696 | if (gp == NULL) |
685 | return -EINVAL; | 697 | return -EINVAL; |
686 | ucontrol->value.integer.value[0] = ! read_audio_gpio(gp); | 698 | ucontrol->value.integer.value[0] = !check_audio_gpio(gp); |
687 | return 0; | 699 | return 0; |
688 | } | 700 | } |
689 | 701 | ||
@@ -711,7 +723,7 @@ static int tumbler_put_mute_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_ | |||
711 | } | 723 | } |
712 | if (gp == NULL) | 724 | if (gp == NULL) |
713 | return -EINVAL; | 725 | return -EINVAL; |
714 | val = ! read_audio_gpio(gp); | 726 | val = ! check_audio_gpio(gp); |
715 | if (val != ucontrol->value.integer.value[0]) { | 727 | if (val != ucontrol->value.integer.value[0]) { |
716 | write_audio_gpio(gp, ! ucontrol->value.integer.value[0]); | 728 | write_audio_gpio(gp, ! ucontrol->value.integer.value[0]); |
717 | return 1; | 729 | return 1; |
@@ -897,11 +909,11 @@ static int tumbler_detect_lineout(pmac_t *chip) | |||
897 | 909 | ||
898 | static void check_mute(pmac_t *chip, pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw) | 910 | static void check_mute(pmac_t *chip, pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw) |
899 | { | 911 | { |
900 | //pmac_tumbler_t *mix = chip->mixer_data; | 912 | if (check_audio_gpio(gp) != val) { |
901 | if (val != read_audio_gpio(gp)) { | ||
902 | write_audio_gpio(gp, val); | 913 | write_audio_gpio(gp, val); |
903 | if (do_notify) | 914 | if (do_notify) |
904 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &sw->id); | 915 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, |
916 | &sw->id); | ||
905 | } | 917 | } |
906 | } | 918 | } |
907 | 919 | ||
@@ -1128,6 +1140,8 @@ static void tumbler_suspend(pmac_t *chip) | |||
1128 | disable_irq(mix->lineout_irq); | 1140 | disable_irq(mix->lineout_irq); |
1129 | mix->save_master_switch[0] = mix->master_switch[0]; | 1141 | mix->save_master_switch[0] = mix->master_switch[0]; |
1130 | mix->save_master_switch[1] = mix->master_switch[1]; | 1142 | mix->save_master_switch[1] = mix->master_switch[1]; |
1143 | mix->save_master_vol[0] = mix->master_vol[0]; | ||
1144 | mix->save_master_vol[1] = mix->master_vol[1]; | ||
1131 | mix->master_switch[0] = mix->master_switch[1] = 0; | 1145 | mix->master_switch[0] = mix->master_switch[1] = 0; |
1132 | tumbler_set_master_volume(mix); | 1146 | tumbler_set_master_volume(mix); |
1133 | if (!mix->anded_reset) { | 1147 | if (!mix->anded_reset) { |
@@ -1155,6 +1169,8 @@ static void tumbler_resume(pmac_t *chip) | |||
1155 | mix->acs &= ~1; | 1169 | mix->acs &= ~1; |
1156 | mix->master_switch[0] = mix->save_master_switch[0]; | 1170 | mix->master_switch[0] = mix->save_master_switch[0]; |
1157 | mix->master_switch[1] = mix->save_master_switch[1]; | 1171 | mix->master_switch[1] = mix->save_master_switch[1]; |
1172 | mix->master_vol[0] = mix->save_master_vol[0]; | ||
1173 | mix->master_vol[1] = mix->save_master_vol[1]; | ||
1158 | tumbler_reset_audio(chip); | 1174 | tumbler_reset_audio(chip); |
1159 | if (mix->i2c.client && mix->i2c.init_client) { | 1175 | if (mix->i2c.client && mix->i2c.init_client) { |
1160 | if (mix->i2c.init_client(&mix->i2c) < 0) | 1176 | if (mix->i2c.init_client(&mix->i2c) < 0) |