diff --git a/[refs] b/[refs] index be625a188ea3..3675d2e8c405 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4522d58275f124105819723e24e912c8e5bf3cdd +refs/heads/master: 334c29a64507dda187565dd0db0403de3d70ec8b diff --git a/trunk/Documentation/DMA-API.txt b/trunk/Documentation/DMA-API.txt index 805db4b2cba6..05431621c861 100644 --- a/trunk/Documentation/DMA-API.txt +++ b/trunk/Documentation/DMA-API.txt @@ -77,7 +77,7 @@ To get this part of the dma_ API, you must #include Many drivers need lots of small dma-coherent memory regions for DMA descriptors or I/O buffers. Rather than allocating in units of a page or more using dma_alloc_coherent(), you can use DMA pools. These work -much like a struct kmem_cache, except that they use the dma-coherent allocator +much like a kmem_cache_t, except that they use the dma-coherent allocator not __get_free_pages(). Also, they understand common hardware constraints for alignment, like queue heads needing to be aligned on N byte boundaries. @@ -94,7 +94,7 @@ The pool create() routines initialize a pool of dma-coherent buffers for use with a given device. It must be called in a context which can sleep. -The "name" is for diagnostics (like a struct kmem_cache name); dev and size +The "name" is for diagnostics (like a kmem_cache_t name); dev and size are like what you'd pass to dma_alloc_coherent(). The device's hardware alignment requirement for this type of data is "align" (which is expressed in bytes, and must be a power of two). If your device has no boundary @@ -431,10 +431,10 @@ be identical to those passed in (and returned by dma_alloc_noncoherent()). int -dma_is_consistent(struct device *dev, dma_addr_t dma_handle) +dma_is_consistent(dma_addr_t dma_handle) -returns true if the device dev is performing consistent DMA on the memory -area pointed to by the dma_handle. +returns true if the memory pointed to by the dma_handle is actually +consistent. int dma_get_cache_alignment(void) @@ -459,7 +459,7 @@ anything like this. You must also be extra careful about accessing memory you intend to sync partially. void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) Do a partial sync of memory that was allocated by diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index ca094913c555..a166675c4303 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -418,35 +418,9 @@ X!Edrivers/pnp/system.c !Idrivers/parport/daisy.c - - Message-based devices - Fusion message devices -!Edrivers/message/fusion/mptbase.c -!Idrivers/message/fusion/mptbase.c -!Edrivers/message/fusion/mptscsih.c -!Idrivers/message/fusion/mptscsih.c -!Idrivers/message/fusion/mptctl.c -!Idrivers/message/fusion/mptspi.c -!Idrivers/message/fusion/mptfc.c -!Idrivers/message/fusion/mptlan.c - - I2O message devices -!Iinclude/linux/i2o.h -!Idrivers/message/i2o/core.h -!Edrivers/message/i2o/iop.c -!Idrivers/message/i2o/iop.c -!Idrivers/message/i2o/config-osm.c -!Edrivers/message/i2o/exec-osm.c -!Idrivers/message/i2o/exec-osm.c -!Idrivers/message/i2o/bus-osm.c -!Edrivers/message/i2o/device.c -!Idrivers/message/i2o/device.c -!Idrivers/message/i2o/driver.c -!Idrivers/message/i2o/pci.c -!Idrivers/message/i2o/i2o_block.c -!Idrivers/message/i2o/i2o_scsi.c -!Idrivers/message/i2o/i2o_proc.c - + + Video4Linux +!Edrivers/media/video/videodev.c diff --git a/trunk/Documentation/IPMI.txt b/trunk/Documentation/IPMI.txt index 24dc3fcf1594..0e3924ecd76b 100644 --- a/trunk/Documentation/IPMI.txt +++ b/trunk/Documentation/IPMI.txt @@ -365,7 +365,6 @@ You can change this at module load time (for a module) with: regshifts=,,... slave_addrs=,,... force_kipmid=,,... - unload_when_empty=[0|1] Each of these except si_trydefaults is a list, the first item for the first interface, second item for the second interface, etc. @@ -417,11 +416,6 @@ by the driver, but systems with broken interrupts might need an enable, or users that don't want the daemon (don't need the performance, don't want the CPU hit) can disable it. -If unload_when_empty is set to 1, the driver will be unloaded if it -doesn't find any interfaces or all the interfaces fail to work. The -default is one. Setting to 0 is useful with the hotmod, but is -obviously only useful for modules. - When compiled into the kernel, the parameters can be specified on the kernel command line as: @@ -447,25 +441,6 @@ have high-res timers enabled in the kernel and you don't have interrupts enabled, the driver will run VERY slowly. Don't blame me, these interfaces suck. -The driver supports a hot add and remove of interfaces. This way, -interfaces can be added or removed after the kernel is up and running. -This is done using /sys/modules/ipmi_si/hotmod, which is a write-only -parameter. You write a string to this interface. The string has the -format: - [:op2[:op3...]] -The "op"s are: - add|remove,kcs|bt|smic,mem|i/o,
[,[,[,...]]] -You can specify more than one interface on the line. The "opt"s are: - rsp= - rsi= - rsh= - irq= - ipmb= -and these have the same meanings as discussed above. Note that you -can also use this on the kernel command line for a more compact format -for specifying an interface. Note that when removing an interface, -only the first three parameters (si type, address type, and address) -are used for the comparison. Any options are ignored for removing. The SMBus Driver ---------------- @@ -527,10 +502,7 @@ used to control it: modprobe ipmi_watchdog timeout= pretimeout= action= preaction= preop= start_now=x - nowayout=x ifnum_to_use=n - -ifnum_to_use specifies which interface the watchdog timer should use. -The default is -1, which means to pick the first one registered. + nowayout=x The timeout is the number of seconds to the action, and the pretimeout is the amount of seconds before the reset that the pre-timeout panic will @@ -652,9 +624,5 @@ command line. The parameter is also available via the proc filesystem in /proc/sys/dev/ipmi/poweroff_powercycle. Note that if the system does not support power cycling, it will always do the power off. -The "ifnum_to_use" parameter specifies which interface the poweroff -code should use. The default is -1, which means to pick the first one -registered. - Note that if you have ACPI enabled, the system will prefer using ACPI to power off. diff --git a/trunk/Documentation/block/as-iosched.txt b/trunk/Documentation/block/as-iosched.txt index a598fe10a297..e2a66f8143c5 100644 --- a/trunk/Documentation/block/as-iosched.txt +++ b/trunk/Documentation/block/as-iosched.txt @@ -24,10 +24,8 @@ very similar behavior to the deadline IO scheduler. Selecting IO schedulers ----------------------- To choose IO schedulers at boot time, use the argument 'elevator=deadline'. -'noop', 'as' and 'cfq' (the default) are also available. IO schedulers are -assigned globally at boot time only presently. It's also possible to change -the IO scheduler for a determined device on the fly, as described in -Documentation/block/switching-sched.txt. +'noop' and 'as' (the default) are also available. IO schedulers are assigned +globally at boot time only presently. Anticipatory IO scheduler Policies diff --git a/trunk/Documentation/devices.txt b/trunk/Documentation/devices.txt index 8de132a02ba9..70690f1a14af 100644 --- a/trunk/Documentation/devices.txt +++ b/trunk/Documentation/devices.txt @@ -3,7 +3,7 @@ Maintained by Torben Mathiasen - Last revised: 29 November 2006 + Last revised: 15 May 2006 This list is the Linux Device List, the official registry of allocated device numbers and /dev directory nodes for the Linux operating @@ -94,7 +94,6 @@ Your cooperation is appreciated. 9 = /dev/urandom Faster, less secure random number gen. 10 = /dev/aio Asynchronous I/O notification interface 11 = /dev/kmsg Writes to this come out as printk's - 1 block RAM disk 0 = /dev/ram0 First RAM disk 1 = /dev/ram1 Second RAM disk @@ -123,7 +122,7 @@ Your cooperation is appreciated. devices are on major 128 and above and use the PTY master multiplex (/dev/ptmx) to acquire a PTY on demand. - + 2 block Floppy disks 0 = /dev/fd0 Controller 0, drive 0, autodetect 1 = /dev/fd1 Controller 0, drive 1, autodetect @@ -258,7 +257,7 @@ Your cooperation is appreciated. 129 = /dev/vcsa1 tty1 text/attribute contents ... 191 = /dev/vcsa63 tty63 text/attribute contents - + NOTE: These devices permit both read and write access. 7 block Loopback devices @@ -412,7 +411,7 @@ Your cooperation is appreciated. 207 = /dev/video/em8300_sp EM8300 DVD decoder subpicture 208 = /dev/compaq/cpqphpc Compaq PCI Hot Plug Controller 209 = /dev/compaq/cpqrid Compaq Remote Insight Driver - 210 = /dev/impi/bt IMPI coprocessor block transfer + 210 = /dev/impi/bt IMPI coprocessor block transfer 211 = /dev/impi/smic IMPI coprocessor stream interface 212 = /dev/watchdogs/0 First watchdog device 213 = /dev/watchdogs/1 Second watchdog device @@ -507,7 +506,6 @@ Your cooperation is appreciated. 33 = /dev/patmgr1 Sequencer patch manager 34 = /dev/midi02 Third MIDI port 50 = /dev/midi03 Fourth MIDI port - 14 block BIOS harddrive callback support {2.6} 0 = /dev/dos_hda First BIOS harddrive whole disk 64 = /dev/dos_hdb Second BIOS harddrive whole disk @@ -529,7 +527,6 @@ Your cooperation is appreciated. 16 char Non-SCSI scanners 0 = /dev/gs4500 Genius 4500 handheld scanner - 16 block GoldStar CD-ROM 0 = /dev/gscd GoldStar CD-ROM @@ -551,7 +548,6 @@ Your cooperation is appreciated. 0 = /dev/ttyC0 First Cyclades port ... 31 = /dev/ttyC31 32nd Cyclades port - 19 block "Double" compressed disk 0 = /dev/double0 First compressed disk ... @@ -567,7 +563,6 @@ Your cooperation is appreciated. 0 = /dev/cub0 Callout device for ttyC0 ... 31 = /dev/cub31 Callout device for ttyC31 - 20 block Hitachi CD-ROM (under development) 0 = /dev/hitcd Hitachi CD-ROM @@ -587,7 +582,7 @@ Your cooperation is appreciated. This device is used on the ARM-based Acorn RiscPC. Partitions are handled the same way as for IDE disks - (see major number 3). + (see major number 3). 22 char Digiboard serial card 0 = /dev/ttyD0 First Digiboard port @@ -596,7 +591,7 @@ Your cooperation is appreciated. 22 block Second IDE hard disk/CD-ROM interface 0 = /dev/hdc Master: whole disk (or CD-ROM) 64 = /dev/hdd Slave: whole disk (or CD-ROM) - + Partitions are handled the same way as for the first interface (see major number 3). @@ -644,7 +639,6 @@ Your cooperation is appreciated. 26 char Quanta WinVision frame grabber {2.6} 0 = /dev/wvisfgrab Quanta WinVision frame grabber - 26 block Second Matsushita (Panasonic/SoundBlaster) CD-ROM 0 = /dev/sbpcd4 Panasonic CD-ROM controller 1 unit 0 1 = /dev/sbpcd5 Panasonic CD-ROM controller 1 unit 1 @@ -676,7 +670,6 @@ Your cooperation is appreciated. 37 = /dev/nrawqft1 Unit 1, no rewind-on-close, no file marks 38 = /dev/nrawqft2 Unit 2, no rewind-on-close, no file marks 39 = /dev/nrawqft3 Unit 3, no rewind-on-close, no file marks - 27 block Third Matsushita (Panasonic/SoundBlaster) CD-ROM 0 = /dev/sbpcd8 Panasonic CD-ROM controller 2 unit 0 1 = /dev/sbpcd9 Panasonic CD-ROM controller 2 unit 1 @@ -688,7 +681,6 @@ Your cooperation is appreciated. 1 = /dev/staliomem1 Second Stallion card I/O memory 2 = /dev/staliomem2 Third Stallion card I/O memory 3 = /dev/staliomem3 Fourth Stallion card I/O memory - 28 char Atari SLM ACSI laser printer (68k/Atari) 0 = /dev/slm0 First SLM laser printer 1 = /dev/slm1 Second SLM laser printer @@ -698,7 +690,6 @@ Your cooperation is appreciated. 1 = /dev/sbpcd13 Panasonic CD-ROM controller 3 unit 1 2 = /dev/sbpcd14 Panasonic CD-ROM controller 3 unit 2 3 = /dev/sbpcd15 Panasonic CD-ROM controller 3 unit 3 - 28 block ACSI disk (68k/Atari) 0 = /dev/ada First ACSI disk whole disk 16 = /dev/adb Second ACSI disk whole disk @@ -759,7 +750,6 @@ Your cooperation is appreciated. 31 char MPU-401 MIDI 0 = /dev/mpu401data MPU-401 data port 1 = /dev/mpu401stat MPU-401 status port - 31 block ROM/flash memory card 0 = /dev/rom0 First ROM card (rw) ... @@ -811,7 +801,7 @@ Your cooperation is appreciated. 34 block Fourth IDE hard disk/CD-ROM interface 0 = /dev/hdg Master: whole disk (or CD-ROM) 64 = /dev/hdh Slave: whole disk (or CD-ROM) - + Partitions are handled the same way as for the first interface (see major number 3). @@ -828,7 +818,6 @@ Your cooperation is appreciated. 129 = /dev/smpte1 Second MIDI port, SMPTE timed 130 = /dev/smpte2 Third MIDI port, SMPTE timed 131 = /dev/smpte3 Fourth MIDI port, SMPTE timed - 35 block Slow memory ramdisk 0 = /dev/slram Slow memory ramdisk @@ -839,7 +828,6 @@ Your cooperation is appreciated. 16 = /dev/tap0 First Ethertap device ... 31 = /dev/tap15 16th Ethertap device - 36 block MCA ESDI hard disk 0 = /dev/eda First ESDI disk whole disk 64 = /dev/edb Second ESDI disk whole disk @@ -894,7 +882,6 @@ Your cooperation is appreciated. 40 char Matrox Meteor frame grabber {2.6} 0 = /dev/mmetfgrab Matrox Meteor frame grabber - 40 block Syquest EZ135 parallel port removable drive 0 = /dev/eza Parallel EZ135 drive, whole disk @@ -906,7 +893,6 @@ Your cooperation is appreciated. 41 char Yet Another Micro Monitor 0 = /dev/yamm Yet Another Micro Monitor - 41 block MicroSolutions BackPack parallel port CD-ROM 0 = /dev/bpcd BackPack CD-ROM @@ -915,7 +901,6 @@ Your cooperation is appreciated. the parallel port ATAPI CD-ROM driver at major number 46. 42 char Demo/sample use - 42 block Demo/sample use This number is intended for use in sample code, as @@ -933,7 +918,6 @@ Your cooperation is appreciated. 0 = /dev/ttyI0 First virtual modem ... 63 = /dev/ttyI63 64th virtual modem - 43 block Network block devices 0 = /dev/nb0 First network block device 1 = /dev/nb1 Second network block device @@ -950,13 +934,12 @@ Your cooperation is appreciated. 0 = /dev/cui0 Callout device for ttyI0 ... 63 = /dev/cui63 Callout device for ttyI63 - 44 block Flash Translation Layer (FTL) filesystems 0 = /dev/ftla FTL on first Memory Technology Device 16 = /dev/ftlb FTL on second Memory Technology Device 32 = /dev/ftlc FTL on third Memory Technology Device ... - 240 = /dev/ftlp FTL on 16th Memory Technology Device + 240 = /dev/ftlp FTL on 16th Memory Technology Device Partitions are handled in the same way as for IDE disks (see major number 3) except that the partition @@ -975,7 +958,6 @@ Your cooperation is appreciated. 191 = /dev/ippp63 64th SyncPPP device 255 = /dev/isdninfo ISDN monitor interface - 45 block Parallel port IDE disk devices 0 = /dev/pda First parallel port IDE disk 16 = /dev/pdb Second parallel port IDE disk @@ -1062,7 +1044,6 @@ Your cooperation is appreciated. 1 = /dev/dcbri1 Second DataComm card 2 = /dev/dcbri2 Third DataComm card 3 = /dev/dcbri3 Fourth DataComm card - 52 block Mylex DAC960 PCI RAID controller; fifth controller 0 = /dev/rd/c4d0 First disk, whole disk 8 = /dev/rd/c4d1 Second disk, whole disk @@ -1112,7 +1093,6 @@ Your cooperation is appreciated. 55 char DSP56001 digital signal processor 0 = /dev/dsp56k First DSP56001 - 55 block Mylex DAC960 PCI RAID controller; eighth controller 0 = /dev/rd/c7d0 First disk, whole disk 8 = /dev/rd/c7d1 Second disk, whole disk @@ -1150,7 +1130,6 @@ Your cooperation is appreciated. 0 = /dev/cup0 Callout device for ttyP0 1 = /dev/cup1 Callout device for ttyP1 ... - 58 block Reserved for logical volume manager 59 char sf firewall package @@ -1170,7 +1149,6 @@ Your cooperation is appreciated. NAMING CONFLICT -- PROPOSED REVISED NAME /dev/rpda0 etc 60-63 char LOCAL/EXPERIMENTAL USE - 60-63 block LOCAL/EXPERIMENTAL USE Allocated for local/experimental use. For devices not assigned official numbers, these ranges should be @@ -1456,6 +1434,7 @@ Your cooperation is appreciated. DAC960 (see major number 48) except that the limit on partitions is 15. + 78 char PAM Software's multimodem boards 0 = /dev/ttyM0 First PAM modem 1 = /dev/ttyM1 Second PAM modem @@ -1471,6 +1450,7 @@ Your cooperation is appreciated. DAC960 (see major number 48) except that the limit on partitions is 15. + 79 char PAM Software's multimodem boards - alternate devices 0 = /dev/cum0 Callout device for ttyM0 1 = /dev/cum1 Callout device for ttyM1 @@ -1486,6 +1466,7 @@ Your cooperation is appreciated. DAC960 (see major number 48) except that the limit on partitions is 15. + 80 char Photometrics AT200 CCD camera 0 = /dev/at200 Photometrics AT200 CCD camera @@ -1698,7 +1679,7 @@ Your cooperation is appreciated. 1 = /dev/dcxx1 Second capture card ... - 94 block IBM S/390 DASD block storage + 94 block IBM S/390 DASD block storage 0 = /dev/dasda First DASD device, major 1 = /dev/dasda1 First DASD device, block 1 2 = /dev/dasda2 First DASD device, block 2 @@ -1714,7 +1695,7 @@ Your cooperation is appreciated. 1 = /dev/ipnat NAT control device/log file 2 = /dev/ipstate State information log file 3 = /dev/ipauth Authentication control device/log file - ... + ... 96 char Parallel port ATAPI tape devices 0 = /dev/pt0 First parallel port ATAPI tape @@ -1724,7 +1705,7 @@ Your cooperation is appreciated. 129 = /dev/npt1 Second p.p. ATAPI tape, no rewind ... - 96 block Inverse NAND Flash Translation Layer + 96 block Inverse NAND Flash Translation Layer 0 = /dev/inftla First INFTL layer 16 = /dev/inftlb Second INFTL layer ... @@ -1956,6 +1937,7 @@ Your cooperation is appreciated. ... 113 block IBM iSeries virtual CD-ROM + 0 = /dev/iseries/vcda First virtual CD-ROM 1 = /dev/iseries/vcdb Second virtual CD-ROM ... @@ -2077,12 +2059,11 @@ Your cooperation is appreciated. ... 119 char VMware virtual network control - 0 = /dev/vmnet0 1st virtual network - 1 = /dev/vmnet1 2nd virtual network + 0 = /dev/vnet0 1st virtual network + 1 = /dev/vnet1 2nd virtual network ... 120-127 char LOCAL/EXPERIMENTAL USE - 120-127 block LOCAL/EXPERIMENTAL USE Allocated for local/experimental use. For devices not assigned official numbers, these ranges should be @@ -2094,6 +2075,7 @@ Your cooperation is appreciated. nodes; instead they should be accessed through the /dev/ptmx cloning interface. + 128 block SCSI disk devices (128-143) 0 = /dev/sddy 129th SCSI disk whole disk 16 = /dev/sddz 130th SCSI disk whole disk @@ -2105,6 +2087,7 @@ Your cooperation is appreciated. disks (see major number 3) except that the limit on partitions is 15. + 129 block SCSI disk devices (144-159) 0 = /dev/sdeo 145th SCSI disk whole disk 16 = /dev/sdep 146th SCSI disk whole disk @@ -2140,6 +2123,7 @@ Your cooperation is appreciated. disks (see major number 3) except that the limit on partitions is 15. + 132 block SCSI disk devices (192-207) 0 = /dev/sdgk 193rd SCSI disk whole disk 16 = /dev/sdgl 194th SCSI disk whole disk @@ -2151,6 +2135,7 @@ Your cooperation is appreciated. disks (see major number 3) except that the limit on partitions is 15. + 133 block SCSI disk devices (208-223) 0 = /dev/sdha 209th SCSI disk whole disk 16 = /dev/sdhb 210th SCSI disk whole disk @@ -2162,6 +2147,7 @@ Your cooperation is appreciated. disks (see major number 3) except that the limit on partitions is 15. + 134 block SCSI disk devices (224-239) 0 = /dev/sdhq 225th SCSI disk whole disk 16 = /dev/sdhr 226th SCSI disk whole disk @@ -2173,6 +2159,7 @@ Your cooperation is appreciated. disks (see major number 3) except that the limit on partitions is 15. + 135 block SCSI disk devices (240-255) 0 = /dev/sdig 241st SCSI disk whole disk 16 = /dev/sdih 242nd SCSI disk whole disk @@ -2184,6 +2171,7 @@ Your cooperation is appreciated. disks (see major number 3) except that the limit on partitions is 15. + 136-143 char Unix98 PTY slaves 0 = /dev/pts/0 First Unix98 pseudo-TTY 1 = /dev/pts/1 Second Unix98 pesudo-TTY @@ -2396,7 +2384,6 @@ Your cooperation is appreciated. ... 159 char RESERVED - 159 block RESERVED 160 char General Purpose Instrument Bus (GPIB) @@ -2440,7 +2427,7 @@ Your cooperation is appreciated. Partitions are handled in the same way as for IDE disks (see major number 3) except that the limit on - partitions is 31. + partitions is 31. 162 char Raw block device interface 0 = /dev/rawctl Raw I/O control device @@ -2496,6 +2483,7 @@ Your cooperation is appreciated. 171 char Reserved for IEEE 1394 (Firewire) + 172 char Moxa Intellio serial card 0 = /dev/ttyMX0 First Moxa port 1 = /dev/ttyMX1 Second Moxa port @@ -2555,6 +2543,9 @@ Your cooperation is appreciated. 64 = /dev/usb/rio500 Diamond Rio 500 65 = /dev/usb/usblcd USBLCD Interface (info@usblcd.de) 66 = /dev/usb/cpad0 Synaptics cPad (mouse/LCD) + 67 = /dev/usb/adutux0 1st Ontrak ADU device + ... + 76 = /dev/usb/adutux10 10th Ontrak ADU device 96 = /dev/usb/hiddev0 1st USB HID device ... 111 = /dev/usb/hiddev15 16th USB HID device @@ -2567,7 +2558,7 @@ Your cooperation is appreciated. 132 = /dev/usb/idmouse ID Mouse (fingerprint scanner) device 133 = /dev/usb/sisusbvga1 First SiSUSB VGA device ... - 140 = /dev/usb/sisusbvga8 Eighth SISUSB VGA device + 140 = /dev/usb/sisusbvga8 Eigth SISUSB VGA device 144 = /dev/usb/lcd USB LCD device 160 = /dev/usb/legousbtower0 1st USB Legotower device ... @@ -2580,7 +2571,7 @@ Your cooperation is appreciated. 0 = /dev/uba First USB block device 8 = /dev/ubb Second USB block device 16 = /dev/ubc Third USB block device - ... + ... 181 char Conrad Electronic parallel port radio clocks 0 = /dev/pcfclock0 First Conrad radio clock @@ -2666,7 +2657,7 @@ Your cooperation is appreciated. 32 = /dev/mvideo/status2 Third device ... ... - 240 = /dev/mvideo/status15 16th device + 240 = /dev/mvideo/status15 16th device ... 195 char Nvidia graphics devices @@ -2804,10 +2795,6 @@ Your cooperation is appreciated. ... 185 = /dev/ttyNX15 Hilscher netX serial port 15 186 = /dev/ttyJ0 JTAG1 DCC protocol based serial port emulation - 187 = /dev/ttyUL0 Xilinx uartlite - port 0 - ... - 190 = /dev/ttyUL3 Xilinx uartlite - port 3 - 191 = /dev/xvc0 Xen virtual console - port 0 205 char Low-density serial ports (alternate device) 0 = /dev/culu0 Callout device for ttyLU0 @@ -2845,6 +2832,7 @@ Your cooperation is appreciated. 82 = /dev/cuvr0 Callout device for ttyVR0 83 = /dev/cuvr1 Callout device for ttyVR1 + 206 char OnStream SC-x0 tape devices 0 = /dev/osst0 First OnStream SCSI tape, mode 0 1 = /dev/osst1 Second OnStream SCSI tape, mode 0 @@ -2934,6 +2922,7 @@ Your cooperation is appreciated. ... 212 char LinuxTV.org DVB driver subsystem + 0 = /dev/dvb/adapter0/video0 first video decoder of first card 1 = /dev/dvb/adapter0/audio0 first audio decoder of first card 2 = /dev/dvb/adapter0/sec0 (obsolete/unused) @@ -3019,9 +3008,9 @@ Your cooperation is appreciated. 2 = /dev/3270/tub2 Second 3270 terminal ... -229 char IBM iSeries/pSeries virtual console - 0 = /dev/hvc0 First console port - 1 = /dev/hvc1 Second console port +229 char IBM iSeries virtual console + 0 = /dev/iseries/vtty0 First console port + 1 = /dev/iseries/vtty1 Second console port ... 230 char IBM iSeries virtual tape @@ -3094,14 +3083,12 @@ Your cooperation is appreciated. 234-239 UNASSIGNED 240-254 char LOCAL/EXPERIMENTAL USE - 240-254 block LOCAL/EXPERIMENTAL USE Allocated for local/experimental use. For devices not assigned official numbers, these ranges should be used in order to avoid conflicting with future assignments. 255 char RESERVED - 255 block RESERVED This major is reserved to assist the expansion to a @@ -3128,20 +3115,7 @@ Your cooperation is appreciated. 257 char Phoenix Technologies Cryptographic Services Driver 0 = /dev/ptlsec Crypto Services Driver -257 block SSFDC Flash Translation Layer filesystem - 0 = /dev/ssfdca First SSFDC layer - 8 = /dev/ssfdcb Second SSFDC layer - 16 = /dev/ssfdcc Third SSFDC layer - 24 = /dev/ssfdcd 4th SSFDC layer - 32 = /dev/ssfdce 5th SSFDC layer - 40 = /dev/ssfdcf 6th SSFDC layer - 48 = /dev/ssfdcg 7th SSFDC layer - 56 = /dev/ssfdch 8th SSFDC layer - -258 block ROM/Flash read-only translation layer - 0 = /dev/blockrom0 First ROM card's translation layer interface - 1 = /dev/blockrom1 Second ROM card's translation layer interface - ... + **** ADDITIONAL /dev DIRECTORY ENTRIES diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index 790ef6fbe495..eb1a6cad21e6 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -124,7 +124,7 @@ sync_fs: no no read write_super_lockfs: ? unlockfs: ? statfs: no no no -remount_fs: yes yes maybe (see below) +remount_fs: no yes maybe (see below) clear_inode: no umount_begin: yes no no show_options: no (vfsmount->sem) diff --git a/trunk/Documentation/filesystems/fuse.txt b/trunk/Documentation/filesystems/fuse.txt index 345392c4caeb..3d7447738958 100644 --- a/trunk/Documentation/filesystems/fuse.txt +++ b/trunk/Documentation/filesystems/fuse.txt @@ -51,22 +51,6 @@ homepage: http://fuse.sourceforge.net/ -Filesystem type -~~~~~~~~~~~~~~~ - -The filesystem type given to mount(2) can be one of the following: - -'fuse' - - This is the usual way to mount a FUSE filesystem. The first - argument of the mount system call may contain an arbitrary string, - which is not interpreted by the kernel. - -'fuseblk' - - The filesystem is block device based. The first argument of the - mount system call is interpreted as the name of the device. - Mount options ~~~~~~~~~~~~~ @@ -110,11 +94,6 @@ Mount options The default is infinite. Note that the size of read requests is limited anyway to 32 pages (which is 128kbyte on i386). -'blksize=N' - - Set the block size for the filesystem. The default is 512. This - option is only valid for 'fuseblk' type mounts. - Control filesystem ~~~~~~~~~~~~~~~~~~ diff --git a/trunk/Documentation/filesystems/sysv-fs.txt b/trunk/Documentation/filesystems/sysv-fs.txt index 253b50d1328e..d81722418010 100644 --- a/trunk/Documentation/filesystems/sysv-fs.txt +++ b/trunk/Documentation/filesystems/sysv-fs.txt @@ -1,8 +1,11 @@ +This is the implementation of the SystemV/Coherent filesystem for Linux. It implements all of - Xenix FS, - SystemV/386 FS, - Coherent FS. +This is version beta 4. + To install: * Answer the 'System V and Coherent filesystem support' question with 'y' when configuring the kernel. @@ -25,173 +28,11 @@ Bugs in the present implementation: for this FS on hard disk yet. -These filesystems are rather similar. Here is a comparison with Minix FS: - -* Linux fdisk reports on partitions - - Minix FS 0x81 Linux/Minix - - Xenix FS ?? - - SystemV FS ?? - - Coherent FS 0x08 AIX bootable - -* Size of a block or zone (data allocation unit on disk) - - Minix FS 1024 - - Xenix FS 1024 (also 512 ??) - - SystemV FS 1024 (also 512 and 2048) - - Coherent FS 512 - -* General layout: all have one boot block, one super block and - separate areas for inodes and for directories/data. - On SystemV Release 2 FS (e.g. Microport) the first track is reserved and - all the block numbers (including the super block) are offset by one track. - -* Byte ordering of "short" (16 bit entities) on disk: - - Minix FS little endian 0 1 - - Xenix FS little endian 0 1 - - SystemV FS little endian 0 1 - - Coherent FS little endian 0 1 - Of course, this affects only the file system, not the data of files on it! - -* Byte ordering of "long" (32 bit entities) on disk: - - Minix FS little endian 0 1 2 3 - - Xenix FS little endian 0 1 2 3 - - SystemV FS little endian 0 1 2 3 - - Coherent FS PDP-11 2 3 0 1 - Of course, this affects only the file system, not the data of files on it! - -* Inode on disk: "short", 0 means non-existent, the root dir ino is: - - Minix FS 1 - - Xenix FS, SystemV FS, Coherent FS 2 - -* Maximum number of hard links to a file: - - Minix FS 250 - - Xenix FS ?? - - SystemV FS ?? - - Coherent FS >=10000 - -* Free inode management: - - Minix FS a bitmap - - Xenix FS, SystemV FS, Coherent FS - There is a cache of a certain number of free inodes in the super-block. - When it is exhausted, new free inodes are found using a linear search. - -* Free block management: - - Minix FS a bitmap - - Xenix FS, SystemV FS, Coherent FS - Free blocks are organized in a "free list". Maybe a misleading term, - since it is not true that every free block contains a pointer to - the next free block. Rather, the free blocks are organized in chunks - of limited size, and every now and then a free block contains pointers - to the free blocks pertaining to the next chunk; the first of these - contains pointers and so on. The list terminates with a "block number" - 0 on Xenix FS and SystemV FS, with a block zeroed out on Coherent FS. - -* Super-block location: - - Minix FS block 1 = bytes 1024..2047 - - Xenix FS block 1 = bytes 1024..2047 - - SystemV FS bytes 512..1023 - - Coherent FS block 1 = bytes 512..1023 - -* Super-block layout: - - Minix FS - unsigned short s_ninodes; - unsigned short s_nzones; - unsigned short s_imap_blocks; - unsigned short s_zmap_blocks; - unsigned short s_firstdatazone; - unsigned short s_log_zone_size; - unsigned long s_max_size; - unsigned short s_magic; - - Xenix FS, SystemV FS, Coherent FS - unsigned short s_firstdatazone; - unsigned long s_nzones; - unsigned short s_fzone_count; - unsigned long s_fzones[NICFREE]; - unsigned short s_finode_count; - unsigned short s_finodes[NICINOD]; - char s_flock; - char s_ilock; - char s_modified; - char s_rdonly; - unsigned long s_time; - short s_dinfo[4]; -- SystemV FS only - unsigned long s_free_zones; - unsigned short s_free_inodes; - short s_dinfo[4]; -- Xenix FS only - unsigned short s_interleave_m,s_interleave_n; -- Coherent FS only - char s_fname[6]; - char s_fpack[6]; - then they differ considerably: - Xenix FS - char s_clean; - char s_fill[371]; - long s_magic; - long s_type; - SystemV FS - long s_fill[12 or 14]; - long s_state; - long s_magic; - long s_type; - Coherent FS - unsigned long s_unique; - Note that Coherent FS has no magic. - -* Inode layout: - - Minix FS - unsigned short i_mode; - unsigned short i_uid; - unsigned long i_size; - unsigned long i_time; - unsigned char i_gid; - unsigned char i_nlinks; - unsigned short i_zone[7+1+1]; - - Xenix FS, SystemV FS, Coherent FS - unsigned short i_mode; - unsigned short i_nlink; - unsigned short i_uid; - unsigned short i_gid; - unsigned long i_size; - unsigned char i_zone[3*(10+1+1+1)]; - unsigned long i_atime; - unsigned long i_mtime; - unsigned long i_ctime; - -* Regular file data blocks are organized as - - Minix FS - 7 direct blocks - 1 indirect block (pointers to blocks) - 1 double-indirect block (pointer to pointers to blocks) - - Xenix FS, SystemV FS, Coherent FS - 10 direct blocks - 1 indirect block (pointers to blocks) - 1 double-indirect block (pointer to pointers to blocks) - 1 triple-indirect block (pointer to pointers to pointers to blocks) - -* Inode size, inodes per block - - Minix FS 32 32 - - Xenix FS 64 16 - - SystemV FS 64 16 - - Coherent FS 64 8 - -* Directory entry on disk - - Minix FS - unsigned short inode; - char name[14/30]; - - Xenix FS, SystemV FS, Coherent FS - unsigned short inode; - char name[14]; - -* Dir entry size, dir entries per block - - Minix FS 16/32 64/32 - - Xenix FS 16 64 - - SystemV FS 16 64 - - Coherent FS 16 32 - -* How to implement symbolic links such that the host fsck doesn't scream: - - Minix FS normal - - Xenix FS kludge: as regular files with chmod 1000 - - SystemV FS ?? - - Coherent FS kludge: as regular files with chmod 1000 +Please report any bugs and suggestions to + Bruno Haible + Pascal Haible + Krzysztof G. Baranowski +Bruno Haible + -Notation: We often speak of a "block" but mean a zone (the allocation unit) -and not the disk driver's notion of "block". diff --git a/trunk/Documentation/i386/boot.txt b/trunk/Documentation/i386/boot.txt index 9575de300a61..c51314b1a463 100644 --- a/trunk/Documentation/i386/boot.txt +++ b/trunk/Documentation/i386/boot.txt @@ -2,7 +2,7 @@ ---------------------------- H. Peter Anvin - Last update 2006-11-17 + Last update 2005-09-02 On the i386 platform, the Linux kernel uses a rather complicated boot convention. This has evolved partially due to historical aspects, as @@ -35,8 +35,6 @@ Protocol 2.03: (Kernel 2.4.18-pre1) Explicitly makes the highest possible initrd address available to the bootloader. Protocol 2.04: (Kernel 2.6.14) Extend the syssize field to four bytes. -Protocol 2.05: (Kernel 2.6.20) Make protected mode kernel relocatable. - Introduce relocatable_kernel and kernel_alignment fields. **** MEMORY LAYOUT @@ -131,8 +129,6 @@ Offset Proto Name Meaning 0226/2 N/A pad1 Unused 0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line 022C/4 2.03+ initrd_addr_max Highest legal initrd address -0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel -0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not (1) For backwards compatibility, if the setup_sects field contains 0, the real value is 4. diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index b79bcdf16319..2e1898e4e8fd 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -599,6 +599,8 @@ and is between 256 and 4096 characters. It is defined in the file hugepages= [HW,IA-32,IA-64] Maximal number of HugeTLB pages. + noirqbalance [IA-32,SMP,KNL] Disable kernel irq balancing + i8042.direct [HW] Put keyboard port into non-translated mode i8042.dumbkbd [HW] Pretend that controller can only read data from keyboard and cannot control its state @@ -648,10 +650,6 @@ and is between 256 and 4096 characters. It is defined in the file idle= [HW] Format: idle=poll or idle=halt - ignore_loglevel [KNL] - Ignore loglevel setting - this will print /all/ - kernel messages to the console. Useful for debugging. - ihash_entries= [KNL] Set number of hash buckets for inode cache. @@ -716,12 +714,7 @@ and is between 256 and 4096 characters. It is defined in the file Format: ,,, isolcpus= [KNL,SMP] Isolate CPUs from the general scheduler. - Format: - ,..., - or - - (must be a positive range in ascending order) - or a mixture - ,...,- + Format: ,..., This option can be used to specify one or more CPUs to isolate from the general SMP balancing and scheduling algorithms. The only way to move a process onto or off @@ -1019,10 +1012,6 @@ and is between 256 and 4096 characters. It is defined in the file emulation library even if a 387 maths coprocessor is present. - noaliencache [MM, NUMA] Disables the allcoation of alien caches in - the slab allocator. Saves per-node memory, but will - impact performance on real NUMA hardware. - noalign [KNL,ARM] noapic [SMP,APIC] Tells the kernel to not make use of any @@ -1063,14 +1052,9 @@ and is between 256 and 4096 characters. It is defined in the file in certain environments such as networked servers or real-time systems. - noirqbalance [IA-32,SMP,KNL] Disable kernel irq balancing - noirqdebug [IA-32] Disables the code which attempts to detect and disable unhandled interrupt sources. - no_timer_check [IA-32,X86_64,APIC] Disables the code which tests for - broken timer IRQ sources. - noisapnp [ISAPNP] Disables ISA PnP code. noinitrd [RAM] Tells the kernel not to load any configured @@ -1301,7 +1285,6 @@ and is between 256 and 4096 characters. It is defined in the file Param: "schedule" - profile schedule points. Param: - step/bucket size as a power of 2 for statistical time based profiling. - Param: "sleep" - profile D-state sleeping (millisecs) processor.max_cstate= [HW,ACPI] Limit processor to maximum C-state @@ -1383,12 +1366,6 @@ and is between 256 and 4096 characters. It is defined in the file resume= [SWSUSP] Specify the partition device for software suspend - resume_offset= [SWSUSP] - Specify the offset from the beginning of the partition - given by "resume=" at which the swap header is located, - in units (needed only for swap files). - See Documentation/power/swsusp-and-swap-files.txt - rhash_entries= [KNL,NET] Set number of hash buckets for route cache @@ -1755,9 +1732,6 @@ and is between 256 and 4096 characters. It is defined in the file norandmaps Don't use address space randomization Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space - unwind_debug=N N > 0 will enable dwarf2 unwinder debugging - This is useful to get more information why - you got a "dwarf2 unwinder stuck" ______________________________________________________________________ diff --git a/trunk/Documentation/power/s2ram.txt b/trunk/Documentation/power/s2ram.txt deleted file mode 100644 index b05f512130ea..000000000000 --- a/trunk/Documentation/power/s2ram.txt +++ /dev/null @@ -1,56 +0,0 @@ - How to get s2ram working - ~~~~~~~~~~~~~~~~~~~~~~~~ - 2006 Linus Torvalds - 2006 Pavel Machek - -1) Check suspend.sf.net, program s2ram there has long whitelist of - "known ok" machines, along with tricks to use on each one. - -2) If that does not help, try reading tricks.txt and - video.txt. Perhaps problem is as simple as broken module, and - simple module unload can fix it. - -3) You can use Linus' TRACE_RESUME infrastructure, described below. - - Using TRACE_RESUME - ~~~~~~~~~~~~~~~~~~ - -I've been working at making the machines I have able to STR, and almost -always it's a driver that is buggy. Thank God for the suspend/resume -debugging - the thing that Chuck tried to disable. That's often the _only_ -way to debug these things, and it's actually pretty powerful (but -time-consuming - having to insert TRACE_RESUME() markers into the device -driver that doesn't resume and recompile and reboot). - -Anyway, the way to debug this for people who are interested (have a -machine that doesn't boot) is: - - - enable PM_DEBUG, and PM_TRACE - - - use a script like this: - - #!/bin/sh - sync - echo 1 > /sys/power/pm_trace - echo mem > /sys/power/state - - to suspend - - - if it doesn't come back up (which is usually the problem), reboot by - holding the power button down, and look at the dmesg output for things - like - - Magic number: 4:156:725 - hash matches drivers/base/power/resume.c:28 - hash matches device 0000:01:00.0 - - which means that the last trace event was just before trying to resume - device 0000:01:00.0. Then figure out what driver is controlling that - device (lspci and /sys/devices/pci* is your friend), and see if you can - fix it, disable it, or trace into its resume function. - -For example, the above happens to be the VGA device on my EVO, which I -used to run with "radeonfb" (it's an ATI Radeon mobility). It turns out -that "radeonfb" simply cannot resume that device - it tries to set the -PLL's, and it just _hangs_. Using the regular VGA console and letting X -resume it instead works fine. diff --git a/trunk/Documentation/power/swsusp-and-swap-files.txt b/trunk/Documentation/power/swsusp-and-swap-files.txt deleted file mode 100644 index 06f911a5f885..000000000000 --- a/trunk/Documentation/power/swsusp-and-swap-files.txt +++ /dev/null @@ -1,60 +0,0 @@ -Using swap files with software suspend (swsusp) - (C) 2006 Rafael J. Wysocki - -The Linux kernel handles swap files almost in the same way as it handles swap -partitions and there are only two differences between these two types of swap -areas: -(1) swap files need not be contiguous, -(2) the header of a swap file is not in the first block of the partition that -holds it. From the swsusp's point of view (1) is not a problem, because it is -already taken care of by the swap-handling code, but (2) has to be taken into -consideration. - -In principle the location of a swap file's header may be determined with the -help of appropriate filesystem driver. Unfortunately, however, it requires the -filesystem holding the swap file to be mounted, and if this filesystem is -journaled, it cannot be mounted during resume from disk. For this reason to -identify a swap file swsusp uses the name of the partition that holds the file -and the offset from the beginning of the partition at which the swap file's -header is located. For convenience, this offset is expressed in -units. - -In order to use a swap file with swsusp, you need to: - -1) Create the swap file and make it active, eg. - -# dd if=/dev/zero of= bs=1024 count= -# mkswap -# swapon - -2) Use an application that will bmap the swap file with the help of the -FIBMAP ioctl and determine the location of the file's swap header, as the -offset, in units, from the beginning of the partition which -holds the swap file. - -3) Add the following parameters to the kernel command line: - -resume= resume_offset= - -where is the partition on which the swap file is located -and is the offset of the swap header determined by the -application in 2) (of course, this step may be carried out automatically -by the same application that determies the swap file's header offset using the -FIBMAP ioctl) - -OR - -Use a userland suspend application that will set the partition and offset -with the help of the SNAPSHOT_SET_SWAP_AREA ioctl described in -Documentation/power/userland-swsusp.txt (this is the only method to suspend -to a swap file allowing the resume to be initiated from an initrd or initramfs -image). - -Now, swsusp will use the swap file in the same way in which it would use a swap -partition. In particular, the swap file has to be active (ie. be present in -/proc/swaps) so that it can be used for suspending. - -Note that if the swap file used for suspending is deleted and recreated, -the location of its header need not be the same as before. Thus every time -this happens the value of the "resume_offset=" kernel command line parameter -has to be updated. diff --git a/trunk/Documentation/power/swsusp.txt b/trunk/Documentation/power/swsusp.txt index 0761ff6c57ed..e635e6f1e316 100644 --- a/trunk/Documentation/power/swsusp.txt +++ b/trunk/Documentation/power/swsusp.txt @@ -297,12 +297,20 @@ system is shut down or suspended. Additionally use the encrypted suspend image to prevent sensitive data from being stolen after resume. -Q: Can I suspend to a swap file? +Q: Why can't we suspend to a swap file? -A: Generally, yes, you can. However, it requires you to use the "resume=" and -"resume_offset=" kernel command line parameters, so the resume from a swap file -cannot be initiated from an initrd or initramfs image. See -swsusp-and-swap-files.txt for details. +A: Because accessing swap file needs the filesystem mounted, and +filesystem might do something wrong (like replaying the journal) +during mount. + +There are few ways to get that fixed: + +1) Probably could be solved by modifying every filesystem to support +some kind of "really read-only!" option. Patches welcome. + +2) suspend2 gets around that by storing absolute positions in on-disk +image (and blocksize), with resume parameter pointing directly to +suspend header. Q: Is there a maximum system RAM size that is supported by swsusp? diff --git a/trunk/Documentation/power/userland-swsusp.txt b/trunk/Documentation/power/userland-swsusp.txt index 000556c932e9..64755e9285db 100644 --- a/trunk/Documentation/power/userland-swsusp.txt +++ b/trunk/Documentation/power/userland-swsusp.txt @@ -9,8 +9,9 @@ done it already. Now, to use the userland interface for software suspend you need special utilities that will read/write the system memory snapshot from/to the kernel. Such utilities are available, for example, from -. You may want to have a look at them if you -are going to develop your own suspend/resume utilities. +. You may want to have +a look at them if you are going to develop your own suspend/resume +utilities. The interface consists of a character device providing the open(), release(), read(), and write() operations as well as several ioctl() @@ -20,9 +21,9 @@ be read from /sys/class/misc/snapshot/dev. The device can be open either for reading or for writing. If open for reading, it is considered to be in the suspend mode. Otherwise it is -assumed to be in the resume mode. The device cannot be open for simultaneous -reading and writing. It is also impossible to have the device open more than -once at a time. +assumed to be in the resume mode. The device cannot be open for reading +and writing. It is also impossible to have the device open more than once +at a time. The ioctl() commands recognized by the device are: @@ -68,46 +69,9 @@ SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated with SNAPSHOT_SET_SWAP_FILE - set the resume partition (the last ioctl() argument should specify the device's major and minor numbers in the old two-byte format, as returned by the stat() function in the .st_rdev - member of the stat structure) - -SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in - units) from the beginning of the partition at which the swap header is - located (the last ioctl() argument should point to a struct - resume_swap_area, as defined in kernel/power/power.h, containing the - resume device specification, as for the SNAPSHOT_SET_SWAP_FILE ioctl(), - and the offset); for swap partitions the offset is always 0, but it is - different to zero for swap files (please see - Documentation/swsusp-and-swap-files.txt for details). - The SNAPSHOT_SET_SWAP_AREA ioctl() is considered as a replacement for - SNAPSHOT_SET_SWAP_FILE which is regarded as obsolete. It is - recommended to always use this call, because the code to set the resume - partition may be removed from future kernels - -SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to - immediately enter the suspend-to-RAM state, so this call must always - be preceded by the SNAPSHOT_FREEZE call and it is also necessary - to use the SNAPSHOT_UNFREEZE call after the system wakes up. This call - is needed to implement the suspend-to-both mechanism in which the - suspend image is first created, as though the system had been suspended - to disk, and then the system is suspended to RAM (this makes it possible - to resume the system from RAM if there's enough battery power or restore - its state on the basis of the saved suspend image otherwise) - -SNAPSHOT_PMOPS - enable the usage of the pmops->prepare, pmops->enter and - pmops->finish methods (the in-kernel swsusp knows these as the "platform - method") which are needed on many machines to (among others) speed up - the resume by letting the BIOS skip some steps or to let the system - recognise the correct state of the hardware after the resume (in - particular on many machines this ensures that unplugged AC - adapters get correctly detected and that kacpid does not run wild after - the resume). The last ioctl() argument can take one of the three - values, defined in kernel/power/power.h: - PMOPS_PREPARE - make the kernel carry out the - pm_ops->prepare(PM_SUSPEND_DISK) operation - PMOPS_ENTER - make the kernel power off the system by calling - pm_ops->enter(PM_SUSPEND_DISK) - PMOPS_FINISH - make the kernel carry out the - pm_ops->finish(PM_SUSPEND_DISK) operation + member of the stat structure); it is recommended to always use this + call, because the code to set the resume partition could be removed from + future kernels The device's read() operation can be used to transfer the snapshot image from the kernel. It has the following limitations: @@ -127,12 +91,10 @@ unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are still frozen when the device is being closed). Currently it is assumed that the userland utilities reading/writing the -snapshot image from/to the kernel will use a swap parition, called the resume -partition, or a swap file as storage space (if a swap file is used, the resume -partition is the partition that holds this file). However, this is not really -required, as they can use, for example, a special (blank) suspend partition or -a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and -mounted afterwards. +snapshot image from/to the kernel will use a swap partition, called the resume +partition, as storage space. However, this is not really required, as they +can use, for example, a special (blank) suspend partition or a file on a partition +that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and mounted afterwards. These utilities SHOULD NOT make any assumptions regarding the ordering of data within the snapshot image, except for the image header that MAY be diff --git a/trunk/Documentation/stable_api_nonsense.txt b/trunk/Documentation/stable_api_nonsense.txt index a2afca3b2bab..f39c9d714db3 100644 --- a/trunk/Documentation/stable_api_nonsense.txt +++ b/trunk/Documentation/stable_api_nonsense.txt @@ -62,6 +62,9 @@ consider the following facts about the Linux kernel: - different structures can contain different fields - Some functions may not be implemented at all, (i.e. some locks compile away to nothing for non-SMP builds.) + - Parameter passing of variables from function to function can be + done in different ways (the CONFIG_REGPARM option controls + this.) - Memory within the kernel can be aligned in different ways, depending on the build options. - Linux runs on a wide range of different processor architectures. diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index 5922e84d9133..0bc7f1e3c9e6 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -27,7 +27,6 @@ show up in /proc/sys/kernel: - hotplug - java-appletviewer [ binfmt_java, obsolete ] - java-interpreter [ binfmt_java, obsolete ] -- kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] - modprobe ==> Documentation/kmod.txt - msgmax @@ -171,13 +170,6 @@ This flag controls the L2 cache of G3 processor boards. If ============================================================== -kstack_depth_to_print: (X86 only) - -Controls the number of words to print when dumping the raw -kernel stack. - -============================================================== - osrelease, ostype & version: # cat osrelease diff --git a/trunk/Documentation/x86_64/boot-options.txt b/trunk/Documentation/x86_64/boot-options.txt index dbdcaf68e3ea..f3c57f43ba64 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -52,6 +52,10 @@ APICs apicmaintimer. Useful when your PIT timer is totally broken. + disable_8254_timer / enable_8254_timer + Enable interrupt 0 timer routing over the 8254 in addition to over + the IO-APIC. The kernel tries to set a sensible default. + Early Console syntax: earlyprintk=vga @@ -179,7 +183,7 @@ PCI IOMMU iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]][,merge] - [,forcesac][,fullflush][,nomerge][,noaperture][,calgary] + [,forcesac][,fullflush][,nomerge][,noaperture] size set size of iommu (in bytes) noagp don't initialize the AGP driver and use full aperture. off don't use the IOMMU @@ -200,7 +204,6 @@ IOMMU buffering. nodac Forbid DMA >4GB panic Always panic when IOMMU overflows - calgary Use the Calgary IOMMU if it is available swiotlb=pages[,force] diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index cf24400213f8..5dff26814a06 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1091,19 +1091,13 @@ M: miku@iki.fi S: Maintained EXT2 FILE SYSTEM -L: linux-ext4@vger.kernel.org +L: ext2-devel@lists.sourceforge.net S: Maintained EXT3 FILE SYSTEM P: Stephen Tweedie, Andrew Morton M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com -L: linux-ext4@vger.kernel.org -S: Maintained - -EXT4 FILE SYSTEM -P: Stephen Tweedie, Andrew Morton -M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com -L: linux-ext4@vger.kernel.org +L: ext2-devel@lists.sourceforge.net S: Maintained F71805F HARDWARE MONITORING DRIVER @@ -1220,8 +1214,7 @@ HARDWARE MONITORING P: Jean Delvare M: khali@linux-fr.org L: lm-sensors@lm-sensors.org -W: http://www.lm-sensors.org/ -T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-hwmon/ +W: http://www.lm-sensors.nu/ S: Maintained HARDWARE RANDOM NUMBER GENERATOR CORE @@ -1347,7 +1340,8 @@ I2C SUBSYSTEM P: Jean Delvare M: khali@linux-fr.org L: i2c@lm-sensors.org -T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/ +W: http://www.lm-sensors.nu/ +T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ S: Maintained I2O @@ -1679,7 +1673,7 @@ S: Supported JOURNALLING LAYER FOR BLOCK DEVICES (JBD) P: Stephen Tweedie, Andrew Morton M: sct@redhat.com, akpm@osdl.org -L: linux-ext4@vger.kernel.org +L: ext2-devel@lists.sourceforge.net S: Maintained K8TEMP HARDWARE MONITORING DRIVER @@ -2919,6 +2913,7 @@ S: Maintained SUN3/3X P: Sam Creasey M: sammy@sammy.net +L: sun3-list@redhat.com W: http://sammy.net/sun3/ S: Maintained @@ -3459,12 +3454,6 @@ W: http://oss.sgi.com/projects/xfs T: git git://oss.sgi.com:8090/xfs/xfs-2.6 S: Supported -XILINX UARTLITE SERIAL DRIVER -P: Peter Korsgaard -M: jacmet@sunsite.dk -L: linux-serial@vger.kernel.org -S: Maintained - X86 3-LEVEL PAGING (PAE) SUPPORT P: Ingo Molnar M: mingo@redhat.com diff --git a/trunk/REPORTING-BUGS b/trunk/REPORTING-BUGS index ac02e42a2627..f9da827a0c18 100644 --- a/trunk/REPORTING-BUGS +++ b/trunk/REPORTING-BUGS @@ -40,9 +40,7 @@ summary from [1.]>" for easy identification by the developers. [1.] One line summary of the problem: [2.] Full description of the problem/report: [3.] Keywords (i.e., modules, networking, kernel): -[4.] Kernel information -[4.1.] Kernel version (from /proc/version): -[4.2.] Kernel .config file: +[4.] Kernel version (from /proc/version): [5.] Most recent kernel version which did not have the bug: [6.] Output of Oops.. message (if applicable) with symbolic information resolved (see Documentation/oops-tracing.txt) diff --git a/trunk/arch/alpha/kernel/pci.c b/trunk/arch/alpha/kernel/pci.c index 3c10b9a1ddf5..ffb7d5423cc0 100644 --- a/trunk/arch/alpha/kernel/pci.c +++ b/trunk/arch/alpha/kernel/pci.c @@ -516,11 +516,10 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn) if (bus == 0 && dfn == 0) { hose = pci_isa_hose; } else { - dev = pci_get_bus_and_slot(bus, dfn); + dev = pci_find_slot(bus, dfn); if (!dev) return -ENODEV; hose = dev->sysdata; - pci_dev_put(dev); } } diff --git a/trunk/arch/alpha/kernel/sys_miata.c b/trunk/arch/alpha/kernel/sys_miata.c index 910b43cd63e8..b8b817feb1ee 100644 --- a/trunk/arch/alpha/kernel/sys_miata.c +++ b/trunk/arch/alpha/kernel/sys_miata.c @@ -183,15 +183,11 @@ miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin) if((slot == 7) && (PCI_FUNC(dev->devfn) == 3)) { u8 irq=0; - struct pci_dev *pdev = pci_get_slot(dev->bus, dev->devfn & ~7); - if(pdev == NULL || pci_read_config_byte(pdev, 0x40,&irq) != PCIBIOS_SUCCESSFUL) { - pci_dev_put(pdev); + + if(pci_read_config_byte(pci_find_slot(dev->bus->number, dev->devfn & ~(7)), 0x40,&irq)!=PCIBIOS_SUCCESSFUL) return -1; - } - else { - pci_dev_put(pdev); + else return irq; - } } return COMMON_TABLE_LOOKUP; diff --git a/trunk/arch/alpha/kernel/sys_nautilus.c b/trunk/arch/alpha/kernel/sys_nautilus.c index e7594a7cf585..93744bab73fb 100644 --- a/trunk/arch/alpha/kernel/sys_nautilus.c +++ b/trunk/arch/alpha/kernel/sys_nautilus.c @@ -200,7 +200,7 @@ nautilus_init_pci(void) bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); hose->bus = bus; - irongate = pci_get_bus_and_slot(0, 0); + irongate = pci_find_slot(0, 0); bus->self = irongate; bus->resource[1] = &irongate_mem; diff --git a/trunk/arch/alpha/mm/fault.c b/trunk/arch/alpha/mm/fault.c index 8aa9db834c11..8871529a34e2 100644 --- a/trunk/arch/alpha/mm/fault.c +++ b/trunk/arch/alpha/mm/fault.c @@ -108,7 +108,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, /* If we're in an interrupt context, or have no user context, we must not take the fault. */ - if (!mm || in_atomic()) + if (!mm || in_interrupt()) goto no_context; #ifdef CONFIG_ALPHA_LARGE_VMALLOC diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index f38a60a03b8c..48cf7fffddf2 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-omap1/devices.c b/trunk/arch/arm/mach-omap1/devices.c index 6dcd10ab4496..a611c3b63954 100644 --- a/trunk/arch/arm/mach-omap1/devices.c +++ b/trunk/arch/arm/mach-omap1/devices.c @@ -55,7 +55,7 @@ static inline void omap_init_irda(void) {} /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE) +#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC) #define OMAP_RTC_BASE 0xfffb4800 diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c index 01abb0ace234..3d211dc2f2f9 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -40,7 +40,7 @@ /* io map for dma */ static void __iomem *dma_base; -static struct kmem_cache *dma_kmem; +static kmem_cache_t *dma_kmem; struct s3c24xx_dma_selection dma_sel; @@ -1271,7 +1271,7 @@ struct sysdev_class dma_sysclass = { /* kmem cache implementation */ -static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f) +static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) { memset(p, 0, sizeof(struct s3c2410_dma_buf)); } diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index 9fd6d2eafb40..5e658a874498 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -230,7 +230,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_interrupt() || !mm) goto no_context; /* diff --git a/trunk/arch/arm26/kernel/ecard.c b/trunk/arch/arm26/kernel/ecard.c index 43dd41be71fb..047d0a408b9d 100644 --- a/trunk/arch/arm26/kernel/ecard.c +++ b/trunk/arch/arm26/kernel/ecard.c @@ -620,10 +620,12 @@ ecard_probe(int slot, card_type_t type) struct ex_ecid cid; int i, rc = -ENOMEM; - ec = kzalloc(sizeof(ecard_t), GFP_KERNEL); + ec = kmalloc(sizeof(ecard_t), GFP_KERNEL); if (!ec) goto nomem; + memset(ec, 0, sizeof(ecard_t)); + ec->slot_no = slot; ec->type = type; ec->irq = NO_IRQ; diff --git a/trunk/arch/arm26/mm/fault.c b/trunk/arch/arm26/mm/fault.c index 93c0cee0fb5e..a1f6d8a9cc32 100644 --- a/trunk/arch/arm26/mm/fault.c +++ b/trunk/arch/arm26/mm/fault.c @@ -215,7 +215,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_interrupt() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/trunk/arch/arm26/mm/memc.c b/trunk/arch/arm26/mm/memc.c index f2901581d4da..34def6397c3c 100644 --- a/trunk/arch/arm26/mm/memc.c +++ b/trunk/arch/arm26/mm/memc.c @@ -24,7 +24,7 @@ #define MEMC_TABLE_SIZE (256*sizeof(unsigned long)) -struct kmem_cache *pte_cache, *pgd_cache; +kmem_cache_t *pte_cache, *pgd_cache; int page_nr; /* @@ -162,12 +162,12 @@ void __init create_memmap_holes(struct meminfo *mi) { } -static void pte_cache_ctor(void *pte, struct kmem_cache *cache, unsigned long flags) +static void pte_cache_ctor(void *pte, kmem_cache_t *cache, unsigned long flags) { memzero(pte, sizeof(pte_t) * PTRS_PER_PTE); } -static void pgd_cache_ctor(void *pgd, struct kmem_cache *cache, unsigned long flags) +static void pgd_cache_ctor(void *pgd, kmem_cache_t *cache, unsigned long flags) { memzero(pgd + MEMC_TABLE_SIZE, USER_PTRS_PER_PGD * sizeof(pgd_t)); } diff --git a/trunk/arch/avr32/kernel/kprobes.c b/trunk/arch/avr32/kernel/kprobes.c index d0abbcaf1c1e..ca41fc1edbe1 100644 --- a/trunk/arch/avr32/kernel/kprobes.c +++ b/trunk/arch/avr32/kernel/kprobes.c @@ -154,7 +154,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) return 1; no_kprobe: - preempt_enable_no_resched(); return ret; } diff --git a/trunk/arch/avr32/kernel/signal.c b/trunk/arch/avr32/kernel/signal.c index 0ec14854a200..33096651c24f 100644 --- a/trunk/arch/avr32/kernel/signal.c +++ b/trunk/arch/avr32/kernel/signal.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/avr32/mm/dma-coherent.c b/trunk/arch/avr32/mm/dma-coherent.c index b68d669f823d..44ab8a7bdae2 100644 --- a/trunk/arch/avr32/mm/dma-coherent.c +++ b/trunk/arch/avr32/mm/dma-coherent.c @@ -11,7 +11,7 @@ #include #include -void dma_cache_sync(struct device *dev, void *vaddr, size_t size, int direction) +void dma_cache_sync(void *vaddr, size_t size, int direction) { /* * No need to sync an uncached area diff --git a/trunk/arch/cris/mm/fault.c b/trunk/arch/cris/mm/fault.c index c73e91f1299a..934c51078cce 100644 --- a/trunk/arch/cris/mm/fault.c +++ b/trunk/arch/cris/mm/fault.c @@ -232,7 +232,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_interrupt() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/trunk/arch/frv/kernel/futex.c b/trunk/arch/frv/kernel/futex.c index 14f64b054c7e..eae874a970c6 100644 --- a/trunk/arch/frv/kernel/futex.c +++ b/trunk/arch/frv/kernel/futex.c @@ -10,9 +10,9 @@ */ #include -#include #include #include +#include /* * the various futex operations; MMU fault checking is ignored under no-MMU @@ -200,7 +200,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -223,7 +223,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) break; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/arch/frv/kernel/setup.c b/trunk/arch/frv/kernel/setup.c index 1a5eb6c301c9..a8c61dac1cee 100644 --- a/trunk/arch/frv/kernel/setup.c +++ b/trunk/arch/frv/kernel/setup.c @@ -947,7 +947,7 @@ static void __init setup_linux_memory(void) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) { reserve_bootmem(INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET; + initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; initrd_end = initrd_start + INITRD_SIZE; } else { diff --git a/trunk/arch/frv/kernel/signal.c b/trunk/arch/frv/kernel/signal.c index 85baeae9666a..b8a5882b8625 100644 --- a/trunk/arch/frv/kernel/signal.c +++ b/trunk/arch/frv/kernel/signal.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/frv/mm/fault.c b/trunk/arch/frv/mm/fault.c index 3f12296c3688..8b3eb50c5105 100644 --- a/trunk/arch/frv/mm/fault.c +++ b/trunk/arch/frv/mm/fault.c @@ -78,7 +78,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_interrupt() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/trunk/arch/frv/mm/pgalloc.c b/trunk/arch/frv/mm/pgalloc.c index 19b13be114a2..f76dd03ddd99 100644 --- a/trunk/arch/frv/mm/pgalloc.c +++ b/trunk/arch/frv/mm/pgalloc.c @@ -18,7 +18,7 @@ #include pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); -struct kmem_cache *pgd_cache; +kmem_cache_t *pgd_cache; pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { @@ -100,7 +100,7 @@ static inline void pgd_list_del(pgd_t *pgd) set_page_private(next, (unsigned long) pprev); } -void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) +void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) { unsigned long flags; @@ -120,7 +120,7 @@ void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) } /* never called when PTRS_PER_PMD > 1 */ -void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) +void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused) { unsigned long flags; /* can be called from interrupt context */ diff --git a/trunk/arch/h8300/kernel/setup.c b/trunk/arch/h8300/kernel/setup.c index 6adf8f41d2a1..1077b71d5226 100644 --- a/trunk/arch/h8300/kernel/setup.c +++ b/trunk/arch/h8300/kernel/setup.c @@ -116,7 +116,7 @@ void __init setup_arch(char **cmdline_p) #endif #else if ((memory_end < CONFIG_BLKDEV_RESERVE_ADDRESS) && - (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS)) + (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS) /* overlap userarea */ memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS; #endif diff --git a/trunk/arch/h8300/kernel/signal.c b/trunk/arch/h8300/kernel/signal.c index 02955604d760..7787f70a05bb 100644 --- a/trunk/arch/h8300/kernel/signal.c +++ b/trunk/arch/h8300/kernel/signal.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/h8300/kernel/vmlinux.lds.S b/trunk/arch/h8300/kernel/vmlinux.lds.S index f05288be8878..756325dd480e 100644 --- a/trunk/arch/h8300/kernel/vmlinux.lds.S +++ b/trunk/arch/h8300/kernel/vmlinux.lds.S @@ -70,7 +70,6 @@ SECTIONS #endif .text : { - _text = .; #if defined(CONFIG_ROMKERNEL) *(.int_redirect) #endif diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index ea70359b02d0..8ff1c6fb5aa1 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -182,17 +182,6 @@ config X86_ES7000 endchoice -config PARAVIRT - bool "Paravirtualization support (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - Paravirtualization is a way of running multiple instances of - Linux on the same machine, under a hypervisor. This option - changes the kernel so it can modify itself when it is run - under a hypervisor, improving performance significantly. - However, when run without a hypervisor the kernel is - theoretically slower. If in doubt, say N. - config ACPI_SRAT bool default y @@ -454,8 +443,7 @@ source "drivers/firmware/Kconfig" choice prompt "High Memory Support" - default HIGHMEM4G if !X86_NUMAQ - default HIGHMEM64G if X86_NUMAQ + default NOHIGHMEM config NOHIGHMEM bool "off" @@ -722,6 +710,20 @@ config BOOT_IOREMAP depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI)) default y +config REGPARM + bool "Use register arguments" + default y + help + Compile the kernel with -mregparm=3. This instructs gcc to use + a more efficient function call ABI which passes the first three + arguments of a function call via registers, which results in denser + and faster code. + + If this option is disabled, then the default ABI of passing + arguments via the stack is used. + + If unsure, say Y. + config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" depends on PROC_FS @@ -771,39 +773,23 @@ config CRASH_DUMP PHYSICAL_START. For more details see Documentation/kdump/kdump.txt -config RELOCATABLE - bool "Build a relocatable kernel(EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This build a kernel image that retains relocation information - so it can be loaded someplace besides the default 1MB. - The relocations tend to the kernel binary about 10% larger, - but are discarded at runtime. - - One use is for the kexec on panic case where the recovery kernel - must live at a different physical address than the primary - kernel. +config PHYSICAL_START + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) -config PHYSICAL_ALIGN - hex "Alignment value to which kernel should be aligned" + default "0x1000000" if CRASH_DUMP default "0x100000" - range 0x2000 0x400000 help - This value puts the alignment restrictions on physical address - where kernel is loaded and run from. Kernel is compiled for an - address which meets above alignment restriction. - - If bootloader loads the kernel at a non-aligned address and - CONFIG_RELOCATABLE is set, kernel will move itself to nearest - address aligned to above value and run from there. - - If bootloader loads the kernel at a non-aligned address and - CONFIG_RELOCATABLE is not set, kernel will ignore the run time - load address and decompress itself to the address it has been - compiled for and run from there. The address for which kernel is - compiled already meets above alignment restrictions. Hence the - end result is that kernel runs from a physical address meeting - above alignment restrictions. + This gives the physical address where the kernel is loaded. Normally + for regular kernels this value is 0x100000 (1MB). But in the case + of kexec on panic the fail safe kernel needs to run at a different + address than the panic-ed kernel. This option is used to set the load + address for kernels used to capture crash dump on being kexec'ed + after panic. The default value for crash dump kernels is + 0x1000000 (16MB). This can also be set based on the "X" value as + specified in the "crashkernel=YM@XM" command line boot parameter + passed to the panic-ed kernel. Typically this parameter is set as + crashkernel=64M@16M. Please take a look at + Documentation/kdump/kdump.txt for more details about crash dumps. Don't change this unless you know what you are doing. diff --git a/trunk/arch/i386/Kconfig.cpu b/trunk/arch/i386/Kconfig.cpu index 821fd269ca58..fc4f2abccf06 100644 --- a/trunk/arch/i386/Kconfig.cpu +++ b/trunk/arch/i386/Kconfig.cpu @@ -103,15 +103,8 @@ config MPENTIUMM Select this for Intel Pentium M (not Pentium-4 M) notebook chips. -config MCORE2 - bool "Core 2/newer Xeon" - help - Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) - CPUs. You can distingush newer from older Xeons by the CPU family - in /proc/cpuinfo. Newer ones have 6. - config MPENTIUM4 - bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon" + bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon" help Select this for Intel Pentium 4 chips. This includes the Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M @@ -236,7 +229,7 @@ config X86_L1_CACHE_SHIFT default "7" if MPENTIUM4 || X86_GENERIC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX - default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 + default "6" if MK7 || MK8 || MPENTIUMM config RWSEM_GENERIC_SPINLOCK bool @@ -294,17 +287,17 @@ config X86_ALIGNMENT_16 config X86_GOOD_APIC bool - depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 + depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON default y config X86_INTEL_USERCOPY bool - depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 + depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON default y config X86_USE_PPRO_CHECKSUM bool - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX default y config X86_USE_3DNOW @@ -319,5 +312,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ default y diff --git a/trunk/arch/i386/Kconfig.debug b/trunk/arch/i386/Kconfig.debug index f68cc6f215f8..b31c0802e1cc 100644 --- a/trunk/arch/i386/Kconfig.debug +++ b/trunk/arch/i386/Kconfig.debug @@ -85,14 +85,4 @@ config DOUBLEFAULT option saves about 4k and might cause you much additional grey hair. -config DEBUG_PARAVIRT - bool "Enable some paravirtualization debugging" - default y - depends on PARAVIRT && DEBUG_KERNEL - help - Currently deliberately clobbers regs which are allowed to be - clobbered in inlined paravirt hooks, even in native mode. - If turning this off solves a problem, then DISABLE_INTERRUPTS() or - ENABLE_INTERRUPTS() is lying about what registers can be clobbered. - endmenu diff --git a/trunk/arch/i386/Makefile b/trunk/arch/i386/Makefile index f7ac1aea1d8a..0677908dfa06 100644 --- a/trunk/arch/i386/Makefile +++ b/trunk/arch/i386/Makefile @@ -26,12 +26,10 @@ endif LDFLAGS := -m elf_i386 OBJCOPYFLAGS := -O binary -R .note -R .comment -S -ifdef CONFIG_RELOCATABLE -LDFLAGS_vmlinux := --emit-relocs -endif +LDFLAGS_vmlinux := CHECKFLAGS += -D__i386__ -CFLAGS += -pipe -msoft-float -mregparm=3 +CFLAGS += -pipe -msoft-float # prevent gcc from keeping the stack 16 byte aligned CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) @@ -39,6 +37,8 @@ CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) # CPU-specific tuning. Anything which can be shared with UML should go here. include $(srctree)/arch/i386/Makefile.cpu +cflags-$(CONFIG_REGPARM) += -mregparm=3 + # temporary until string.h is fixed cflags-y += -ffreestanding diff --git a/trunk/arch/i386/Makefile.cpu b/trunk/arch/i386/Makefile.cpu index a32c031c90d7..a11befba26d5 100644 --- a/trunk/arch/i386/Makefile.cpu +++ b/trunk/arch/i386/Makefile.cpu @@ -32,7 +32,6 @@ cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) -cflags-$(CONFIG_MCORE2) += -march=i686 $(call cc-option,-mtune=core2,$(call cc-option,-mtune=generic,-mtune=i686)) # AMD Elan support cflags-$(CONFIG_X86_ELAN) += -march=i486 diff --git a/trunk/arch/i386/boot/compressed/Makefile b/trunk/arch/i386/boot/compressed/Makefile index a661217f33ec..258ea95224f6 100644 --- a/trunk/arch/i386/boot/compressed/Makefile +++ b/trunk/arch/i386/boot/compressed/Makefile @@ -4,42 +4,22 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \ - vmlinux.bin.all vmlinux.relocs +targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o EXTRA_AFLAGS := -traditional -LDFLAGS_vmlinux := -T -CFLAGS_misc.o += -fPIC -hostprogs-y := relocs +LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 -$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE +$(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE $(call if_changed,ld) @: $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) -quiet_cmd_relocs = RELOCS $@ - cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $< -$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE - $(call if_changed,relocs) - -vmlinux.bin.all-y := $(obj)/vmlinux.bin -vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs -quiet_cmd_relocbin = BUILD $@ - cmd_relocbin = cat $(filter-out FORCE,$^) > $@ -$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE - $(call if_changed,relocbin) - -ifdef CONFIG_RELOCATABLE -$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE - $(call if_changed,gzip) -else $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -endif LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T -$(obj)/piggy.o: $(src)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE $(call if_changed,ld) diff --git a/trunk/arch/i386/boot/compressed/head.S b/trunk/arch/i386/boot/compressed/head.S index f395a4bb38bb..b5893e4ecd37 100644 --- a/trunk/arch/i386/boot/compressed/head.S +++ b/trunk/arch/i386/boot/compressed/head.S @@ -26,11 +26,9 @@ #include #include #include -#include -.section ".text.head" .globl startup_32 - + startup_32: cld cli @@ -39,142 +37,93 @@ startup_32: movl %eax,%es movl %eax,%fs movl %eax,%gs - movl %eax,%ss - -/* Calculate the delta between where we were compiled to run - * at and where we were actually loaded at. This can only be done - * with a short local call on x86. Nothing else will tell us what - * address we are running at. The reserved chunk of the real-mode - * data at 0x34-0x3f are used as the stack for this calculation. - * Only 4 bytes are needed. - */ - leal 0x40(%esi), %esp - call 1f -1: popl %ebp - subl $1b, %ebp - -/* %ebp contains the address we are loaded at by the boot loader and %ebx - * contains the address where we should move the kernel image temporarily - * for safe in-place decompression. - */ - -#ifdef CONFIG_RELOCATABLE - movl %ebp, %ebx - addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx - andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx -#else - movl $LOAD_PHYSICAL_ADDR, %ebx -#endif - - /* Replace the compressed data size with the uncompressed size */ - subl input_len(%ebp), %ebx - movl output_len(%ebp), %eax - addl %eax, %ebx - /* Add 8 bytes for every 32K input block */ - shrl $12, %eax - addl %eax, %ebx - /* Add 32K + 18 bytes of extra slack */ - addl $(32768 + 18), %ebx - /* Align on a 4K boundary */ - addl $4095, %ebx - andl $~4095, %ebx - -/* Copy the compressed kernel to the end of our buffer - * where decompression in place becomes safe. - */ - pushl %esi - leal _end(%ebp), %esi - leal _end(%ebx), %edi - movl $(_end - startup_32), %ecx - std - rep - movsb - cld - popl %esi -/* Compute the kernel start address. - */ -#ifdef CONFIG_RELOCATABLE - addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp - andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp -#else - movl $LOAD_PHYSICAL_ADDR, %ebp -#endif + lss stack_start,%esp + xorl %eax,%eax +1: incl %eax # check that A20 really IS enabled + movl %eax,0x000000 # loop forever if it isn't + cmpl %eax,0x100000 + je 1b /* - * Jump to the relocated address. + * Initialize eflags. Some BIOS's leave bits like NT set. This would + * confuse the debugger if this code is traced. + * XXX - best to initialize before switching to protected mode. */ - leal relocated(%ebx), %eax - jmp *%eax -.section ".text" -relocated: - + pushl $0 + popfl /* * Clear BSS */ xorl %eax,%eax - leal _edata(%ebx),%edi - leal _end(%ebx), %ecx + movl $_edata,%edi + movl $_end,%ecx subl %edi,%ecx cld rep stosb - -/* - * Setup the stack for the decompressor - */ - leal stack_end(%ebx), %esp - /* * Do the decompression, and jump to the new kernel.. */ - movl output_len(%ebx), %eax - pushl %eax - pushl %ebp # output address - movl input_len(%ebx), %eax - pushl %eax # input_len - leal input_data(%ebx), %eax - pushl %eax # input_data - leal _end(%ebx), %eax - pushl %eax # end of the image as third argument + subl $16,%esp # place for structure on the stack + movl %esp,%eax pushl %esi # real mode pointer as second arg + pushl %eax # address of structure as first arg call decompress_kernel - addl $20, %esp - popl %ecx - -#if CONFIG_RELOCATABLE -/* Find the address of the relocations. - */ - movl %ebp, %edi - addl %ecx, %edi + orl %eax,%eax + jnz 3f + popl %esi # discard address + popl %esi # real mode pointer + xorl %ebx,%ebx + ljmp $(__BOOT_CS), $__PHYSICAL_START -/* Calculate the delta between where vmlinux was compiled to run - * and where it was actually loaded. - */ - movl %ebp, %ebx - subl $LOAD_PHYSICAL_ADDR, %ebx - jz 2f /* Nothing to be done if loaded at compiled addr. */ /* - * Process relocations. + * We come here, if we were loaded high. + * We need to move the move-in-place routine down to 0x1000 + * and then start it with the buffer addresses in registers, + * which we got from the stack. */ - -1: subl $4, %edi - movl 0(%edi), %ecx - testl %ecx, %ecx - jz 2f - addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) - jmp 1b -2: -#endif +3: + movl $move_routine_start,%esi + movl $0x1000,%edi + movl $move_routine_end,%ecx + subl %esi,%ecx + addl $3,%ecx + shrl $2,%ecx + cld + rep + movsl + + popl %esi # discard the address + popl %ebx # real mode pointer + popl %esi # low_buffer_start + popl %ecx # lcount + popl %edx # high_buffer_start + popl %eax # hcount + movl $__PHYSICAL_START,%edi + cli # make sure we don't get interrupted + ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine /* - * Jump to the decompressed kernel. + * Routine (template) for moving the decompressed kernel in place, + * if we were high loaded. This _must_ PIC-code ! */ +move_routine_start: + movl %ecx,%ebp + shrl $2,%ecx + rep + movsl + movl %ebp,%ecx + andl $3,%ecx + rep + movsb + movl %edx,%esi + movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0 + addl $3,%ecx + shrl $2,%ecx + rep + movsl + movl %ebx,%esi # Restore setup pointer xorl %ebx,%ebx - jmp *%ebp - -.bss -.balign 4 -stack: - .fill 4096, 1, 0 -stack_end: + ljmp $(__BOOT_CS), $__PHYSICAL_START +move_routine_end: diff --git a/trunk/arch/i386/boot/compressed/misc.c b/trunk/arch/i386/boot/compressed/misc.c index 1ce7017fd627..b2ccd543410d 100644 --- a/trunk/arch/i386/boot/compressed/misc.c +++ b/trunk/arch/i386/boot/compressed/misc.c @@ -9,94 +9,11 @@ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ -#undef CONFIG_PARAVIRT #include #include #include #include #include -#include - -/* WARNING!! - * This code is compiled with -fPIC and it is relocated dynamically - * at run time, but no relocation processing is performed. - * This means that it is not safe to place pointers in static structures. - */ - -/* - * Getting to provable safe in place decompression is hard. - * Worst case behaviours need to be analized. - * Background information: - * - * The file layout is: - * magic[2] - * method[1] - * flags[1] - * timestamp[4] - * extraflags[1] - * os[1] - * compressed data blocks[N] - * crc[4] orig_len[4] - * - * resulting in 18 bytes of non compressed data overhead. - * - * Files divided into blocks - * 1 bit (last block flag) - * 2 bits (block type) - * - * 1 block occurs every 32K -1 bytes or when there 50% compression has been achieved. - * The smallest block type encoding is always used. - * - * stored: - * 32 bits length in bytes. - * - * fixed: - * magic fixed tree. - * symbols. - * - * dynamic: - * dynamic tree encoding. - * symbols. - * - * - * The buffer for decompression in place is the length of the - * uncompressed data, plus a small amount extra to keep the algorithm safe. - * The compressed data is placed at the end of the buffer. The output - * pointer is placed at the start of the buffer and the input pointer - * is placed where the compressed data starts. Problems will occur - * when the output pointer overruns the input pointer. - * - * The output pointer can only overrun the input pointer if the input - * pointer is moving faster than the output pointer. A condition only - * triggered by data whose compressed form is larger than the uncompressed - * form. - * - * The worst case at the block level is a growth of the compressed data - * of 5 bytes per 32767 bytes. - * - * The worst case internal to a compressed block is very hard to figure. - * The worst case can at least be boundined by having one bit that represents - * 32764 bytes and then all of the rest of the bytes representing the very - * very last byte. - * - * All of which is enough to compute an amount of extra data that is required - * to be safe. To avoid problems at the block level allocating 5 extra bytes - * per 32767 bytes of data is sufficient. To avoind problems internal to a block - * adding an extra 32767 bytes (the worst case uncompressed block size) is - * sufficient, to ensure that in the worst case the decompressed data for - * block will stop the byte before the compressed data for a block begins. - * To avoid problems with the compressed data's meta information an extra 18 - * bytes are needed. Leading to the formula: - * - * extra_bytes = (uncompressed_size >> 12) + 32768 + 18 + decompressor_size. - * - * Adding 8 bytes per 32K is a bit excessive but much easier to calculate. - * Adding 32768 instead of 32767 just makes for round numbers. - * Adding the decompressor_size is necessary as it musht live after all - * of the data as well. Last I measured the decompressor is about 14K. - * 10K of actuall data and 4K of bss. - * - */ /* * gzip declarations @@ -113,20 +30,15 @@ typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; -#define WSIZE 0x80000000 /* Window size must be at least 32k, - * and a power of two - * We don't actually have a window just - * a huge output buffer so I report - * a 2G windows size, as that should - * always be larger than our output buffer. - */ +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ -static uch *inbuf; /* input buffer */ -static uch *window; /* Sliding window buffer, (and final output buffer) */ +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ @@ -177,6 +89,8 @@ extern unsigned char input_data[]; extern int input_len; static long bytes_out = 0; +static uch *output_data; +static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); @@ -186,17 +100,24 @@ static void *memcpy(void *dest, const void *src, unsigned n); static void putstr(const char *); -static unsigned long free_mem_ptr; -static unsigned long free_mem_end_ptr; +extern int end; +static long free_mem_ptr = (long)&end; +static long free_mem_end_ptr; +#define INPLACE_MOVE_ROUTINE 0x1000 +#define LOW_BUFFER_START 0x2000 +#define LOW_BUFFER_MAX 0x90000 #define HEAP_SIZE 0x3000 +static unsigned int low_buffer_end, low_buffer_size; +static int high_loaded =0; +static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/; static char *vidmem = (char *)0xb8000; static int vidport; static int lines, cols; #ifdef CONFIG_X86_NUMAQ -void *xquad_portio; +static void * xquad_portio = NULL; #endif #include "../../../../lib/inflate.c" @@ -230,7 +151,7 @@ static void gzip_mark(void **ptr) static void gzip_release(void **ptr) { - free_mem_ptr = (unsigned long) *ptr; + free_mem_ptr = (long) *ptr; } static void scroll(void) @@ -258,7 +179,7 @@ static void putstr(const char *s) y--; } } else { - vidmem [ ( x + cols * y ) * 2 ] = c; + vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { @@ -303,31 +224,58 @@ static void* memcpy(void* dest, const void* src, unsigned n) */ static int fill_inbuf(void) { - error("ran out of input data"); - return 0; + if (insize != 0) { + error("ran out of input data"); + } + + inbuf = input_data; + insize = input_len; + inptr = 1; + return inbuf[0]; } /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ +static void flush_window_low(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, *out, ch; + + in = window; + out = &output_data[output_ptr]; + for (n = 0; n < outcnt; n++) { + ch = *out++ = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; +} + +static void flush_window_high(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + in = window; + for (n = 0; n < outcnt; n++) { + ch = *output_data++ = *in++; + if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; +} + static void flush_window(void) { - /* With my window equal to my output buffer - * I only need to compute the crc here. - */ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, ch; - - in = window; - for (n = 0; n < outcnt; n++) { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; + if (high_loaded) flush_window_high(); + else flush_window_low(); } static void error(char *x) @@ -339,8 +287,66 @@ static void error(char *x) while(1); /* Halt */ } -asmlinkage void decompress_kernel(void *rmode, unsigned long end, - uch *input_data, unsigned long input_len, uch *output) +#define STACK_SIZE (4096) + +long user_stack [STACK_SIZE]; + +struct { + long * a; + short b; + } stack_start = { & user_stack [STACK_SIZE] , __BOOT_DS }; + +static void setup_normal_output_buffer(void) +{ +#ifdef STANDARD_MEMORY_BIOS_CALL + if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); +#else + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); +#endif + output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ + free_mem_end_ptr = (long)real_mode; +} + +struct moveparams { + uch *low_buffer_start; int lcount; + uch *high_buffer_start; int hcount; +}; + +static void setup_output_buffer_if_we_run_high(struct moveparams *mv) +{ + high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); +#ifdef STANDARD_MEMORY_BIOS_CALL + if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); +#else + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); +#endif + mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; + low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX + ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff; + low_buffer_size = low_buffer_end - LOW_BUFFER_START; + high_loaded = 1; + free_mem_end_ptr = (long)high_buffer_start; + if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { + high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); + mv->hcount = 0; /* say: we need not to move high_buffer */ + } + else mv->hcount = -1; + mv->high_buffer_start = high_buffer_start; +} + +static void close_output_buffer_if_we_run_high(struct moveparams *mv) +{ + if (bytes_out > low_buffer_size) { + mv->lcount = low_buffer_size; + if (mv->hcount) + mv->hcount = bytes_out - low_buffer_size; + } else { + mv->lcount = bytes_out; + mv->hcount = 0; + } +} + +asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) { real_mode = rmode; @@ -355,25 +361,13 @@ asmlinkage void decompress_kernel(void *rmode, unsigned long end, lines = RM_SCREEN_INFO.orig_video_lines; cols = RM_SCREEN_INFO.orig_video_cols; - window = output; /* Output buffer (Normally at 1M) */ - free_mem_ptr = end; /* Heap */ - free_mem_end_ptr = end + HEAP_SIZE; - inbuf = input_data; /* Input buffer */ - insize = input_len; - inptr = 0; - - if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1)) - error("Destination address not CONFIG_PHYSICAL_ALIGN aligned"); - if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff)) - error("Destination address too large"); -#ifndef CONFIG_RELOCATABLE - if ((u32)output != LOAD_PHYSICAL_ADDR) - error("Wrong destination address"); -#endif + if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); + else setup_output_buffer_if_we_run_high(mv); makecrc(); putstr("Uncompressing Linux... "); gunzip(); putstr("Ok, booting the kernel.\n"); - return; + if (high_loaded) close_output_buffer_if_we_run_high(mv); + return high_loaded; } diff --git a/trunk/arch/i386/boot/compressed/relocs.c b/trunk/arch/i386/boot/compressed/relocs.c deleted file mode 100644 index 468da89153c4..000000000000 --- a/trunk/arch/i386/boot/compressed/relocs.c +++ /dev/null @@ -1,625 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define USE_BSD -#include - -#define MAX_SHDRS 100 -static Elf32_Ehdr ehdr; -static Elf32_Shdr shdr[MAX_SHDRS]; -static Elf32_Sym *symtab[MAX_SHDRS]; -static Elf32_Rel *reltab[MAX_SHDRS]; -static char *strtab[MAX_SHDRS]; -static unsigned long reloc_count, reloc_idx; -static unsigned long *relocs; - -/* - * Following symbols have been audited. There values are constant and do - * not change if bzImage is loaded at a different physical address than - * the address for which it has been compiled. Don't warn user about - * absolute relocations present w.r.t these symbols. - */ -static const char* safe_abs_relocs[] = { - "__kernel_vsyscall", - "__kernel_rt_sigreturn", - "__kernel_sigreturn", - "SYSENTER_RETURN", -}; - -static int is_safe_abs_reloc(const char* sym_name) -{ - int i, array_size; - - array_size = sizeof(safe_abs_relocs)/sizeof(char*); - - for(i = 0; i < array_size; i++) { - if (!strcmp(sym_name, safe_abs_relocs[i])) - /* Match found */ - return 1; - } - return 0; -} - -static void die(char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); -} - -static const char *sym_type(unsigned type) -{ - static const char *type_name[] = { -#define SYM_TYPE(X) [X] = #X - SYM_TYPE(STT_NOTYPE), - SYM_TYPE(STT_OBJECT), - SYM_TYPE(STT_FUNC), - SYM_TYPE(STT_SECTION), - SYM_TYPE(STT_FILE), - SYM_TYPE(STT_COMMON), - SYM_TYPE(STT_TLS), -#undef SYM_TYPE - }; - const char *name = "unknown sym type name"; - if (type < sizeof(type_name)/sizeof(type_name[0])) { - name = type_name[type]; - } - return name; -} - -static const char *sym_bind(unsigned bind) -{ - static const char *bind_name[] = { -#define SYM_BIND(X) [X] = #X - SYM_BIND(STB_LOCAL), - SYM_BIND(STB_GLOBAL), - SYM_BIND(STB_WEAK), -#undef SYM_BIND - }; - const char *name = "unknown sym bind name"; - if (bind < sizeof(bind_name)/sizeof(bind_name[0])) { - name = bind_name[bind]; - } - return name; -} - -static const char *sym_visibility(unsigned visibility) -{ - static const char *visibility_name[] = { -#define SYM_VISIBILITY(X) [X] = #X - SYM_VISIBILITY(STV_DEFAULT), - SYM_VISIBILITY(STV_INTERNAL), - SYM_VISIBILITY(STV_HIDDEN), - SYM_VISIBILITY(STV_PROTECTED), -#undef SYM_VISIBILITY - }; - const char *name = "unknown sym visibility name"; - if (visibility < sizeof(visibility_name)/sizeof(visibility_name[0])) { - name = visibility_name[visibility]; - } - return name; -} - -static const char *rel_type(unsigned type) -{ - static const char *type_name[] = { -#define REL_TYPE(X) [X] = #X - REL_TYPE(R_386_NONE), - REL_TYPE(R_386_32), - REL_TYPE(R_386_PC32), - REL_TYPE(R_386_GOT32), - REL_TYPE(R_386_PLT32), - REL_TYPE(R_386_COPY), - REL_TYPE(R_386_GLOB_DAT), - REL_TYPE(R_386_JMP_SLOT), - REL_TYPE(R_386_RELATIVE), - REL_TYPE(R_386_GOTOFF), - REL_TYPE(R_386_GOTPC), -#undef REL_TYPE - }; - const char *name = "unknown type rel type name"; - if (type < sizeof(type_name)/sizeof(type_name[0])) { - name = type_name[type]; - } - return name; -} - -static const char *sec_name(unsigned shndx) -{ - const char *sec_strtab; - const char *name; - sec_strtab = strtab[ehdr.e_shstrndx]; - name = ""; - if (shndx < ehdr.e_shnum) { - name = sec_strtab + shdr[shndx].sh_name; - } - else if (shndx == SHN_ABS) { - name = "ABSOLUTE"; - } - else if (shndx == SHN_COMMON) { - name = "COMMON"; - } - return name; -} - -static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym) -{ - const char *name; - name = ""; - if (sym->st_name) { - name = sym_strtab + sym->st_name; - } - else { - name = sec_name(shdr[sym->st_shndx].sh_name); - } - return name; -} - - - -#if BYTE_ORDER == LITTLE_ENDIAN -#define le16_to_cpu(val) (val) -#define le32_to_cpu(val) (val) -#endif -#if BYTE_ORDER == BIG_ENDIAN -#define le16_to_cpu(val) bswap_16(val) -#define le32_to_cpu(val) bswap_32(val) -#endif - -static uint16_t elf16_to_cpu(uint16_t val) -{ - return le16_to_cpu(val); -} - -static uint32_t elf32_to_cpu(uint32_t val) -{ - return le32_to_cpu(val); -} - -static void read_ehdr(FILE *fp) -{ - if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) { - die("Cannot read ELF header: %s\n", - strerror(errno)); - } - if (memcmp(ehdr.e_ident, ELFMAG, 4) != 0) { - die("No ELF magic\n"); - } - if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) { - die("Not a 32 bit executable\n"); - } - if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) { - die("Not a LSB ELF executable\n"); - } - if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) { - die("Unknown ELF version\n"); - } - /* Convert the fields to native endian */ - ehdr.e_type = elf16_to_cpu(ehdr.e_type); - ehdr.e_machine = elf16_to_cpu(ehdr.e_machine); - ehdr.e_version = elf32_to_cpu(ehdr.e_version); - ehdr.e_entry = elf32_to_cpu(ehdr.e_entry); - ehdr.e_phoff = elf32_to_cpu(ehdr.e_phoff); - ehdr.e_shoff = elf32_to_cpu(ehdr.e_shoff); - ehdr.e_flags = elf32_to_cpu(ehdr.e_flags); - ehdr.e_ehsize = elf16_to_cpu(ehdr.e_ehsize); - ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize); - ehdr.e_phnum = elf16_to_cpu(ehdr.e_phnum); - ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize); - ehdr.e_shnum = elf16_to_cpu(ehdr.e_shnum); - ehdr.e_shstrndx = elf16_to_cpu(ehdr.e_shstrndx); - - if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) { - die("Unsupported ELF header type\n"); - } - if (ehdr.e_machine != EM_386) { - die("Not for x86\n"); - } - if (ehdr.e_version != EV_CURRENT) { - die("Unknown ELF version\n"); - } - if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) { - die("Bad Elf header size\n"); - } - if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) { - die("Bad program header entry\n"); - } - if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) { - die("Bad section header entry\n"); - } - if (ehdr.e_shstrndx >= ehdr.e_shnum) { - die("String table index out of bounds\n"); - } -} - -static void read_shdrs(FILE *fp) -{ - int i; - if (ehdr.e_shnum > MAX_SHDRS) { - die("%d section headers supported: %d\n", - ehdr.e_shnum, MAX_SHDRS); - } - if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) { - die("Seek to %d failed: %s\n", - ehdr.e_shoff, strerror(errno)); - } - if (fread(&shdr, sizeof(shdr[0]), ehdr.e_shnum, fp) != ehdr.e_shnum) { - die("Cannot read ELF section headers: %s\n", - strerror(errno)); - } - for(i = 0; i < ehdr.e_shnum; i++) { - shdr[i].sh_name = elf32_to_cpu(shdr[i].sh_name); - shdr[i].sh_type = elf32_to_cpu(shdr[i].sh_type); - shdr[i].sh_flags = elf32_to_cpu(shdr[i].sh_flags); - shdr[i].sh_addr = elf32_to_cpu(shdr[i].sh_addr); - shdr[i].sh_offset = elf32_to_cpu(shdr[i].sh_offset); - shdr[i].sh_size = elf32_to_cpu(shdr[i].sh_size); - shdr[i].sh_link = elf32_to_cpu(shdr[i].sh_link); - shdr[i].sh_info = elf32_to_cpu(shdr[i].sh_info); - shdr[i].sh_addralign = elf32_to_cpu(shdr[i].sh_addralign); - shdr[i].sh_entsize = elf32_to_cpu(shdr[i].sh_entsize); - } - -} - -static void read_strtabs(FILE *fp) -{ - int i; - for(i = 0; i < ehdr.e_shnum; i++) { - if (shdr[i].sh_type != SHT_STRTAB) { - continue; - } - strtab[i] = malloc(shdr[i].sh_size); - if (!strtab[i]) { - die("malloc of %d bytes for strtab failed\n", - shdr[i].sh_size); - } - if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { - die("Seek to %d failed: %s\n", - shdr[i].sh_offset, strerror(errno)); - } - if (fread(strtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { - die("Cannot read symbol table: %s\n", - strerror(errno)); - } - } -} - -static void read_symtabs(FILE *fp) -{ - int i,j; - for(i = 0; i < ehdr.e_shnum; i++) { - if (shdr[i].sh_type != SHT_SYMTAB) { - continue; - } - symtab[i] = malloc(shdr[i].sh_size); - if (!symtab[i]) { - die("malloc of %d bytes for symtab failed\n", - shdr[i].sh_size); - } - if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { - die("Seek to %d failed: %s\n", - shdr[i].sh_offset, strerror(errno)); - } - if (fread(symtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { - die("Cannot read symbol table: %s\n", - strerror(errno)); - } - for(j = 0; j < shdr[i].sh_size/sizeof(symtab[i][0]); j++) { - symtab[i][j].st_name = elf32_to_cpu(symtab[i][j].st_name); - symtab[i][j].st_value = elf32_to_cpu(symtab[i][j].st_value); - symtab[i][j].st_size = elf32_to_cpu(symtab[i][j].st_size); - symtab[i][j].st_shndx = elf16_to_cpu(symtab[i][j].st_shndx); - } - } -} - - -static void read_relocs(FILE *fp) -{ - int i,j; - for(i = 0; i < ehdr.e_shnum; i++) { - if (shdr[i].sh_type != SHT_REL) { - continue; - } - reltab[i] = malloc(shdr[i].sh_size); - if (!reltab[i]) { - die("malloc of %d bytes for relocs failed\n", - shdr[i].sh_size); - } - if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { - die("Seek to %d failed: %s\n", - shdr[i].sh_offset, strerror(errno)); - } - if (fread(reltab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { - die("Cannot read symbol table: %s\n", - strerror(errno)); - } - for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { - reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset); - reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info); - } - } -} - - -static void print_absolute_symbols(void) -{ - int i; - printf("Absolute symbols\n"); - printf(" Num: Value Size Type Bind Visibility Name\n"); - for(i = 0; i < ehdr.e_shnum; i++) { - char *sym_strtab; - Elf32_Sym *sh_symtab; - int j; - if (shdr[i].sh_type != SHT_SYMTAB) { - continue; - } - sh_symtab = symtab[i]; - sym_strtab = strtab[shdr[i].sh_link]; - for(j = 0; j < shdr[i].sh_size/sizeof(symtab[0][0]); j++) { - Elf32_Sym *sym; - const char *name; - sym = &symtab[i][j]; - name = sym_name(sym_strtab, sym); - if (sym->st_shndx != SHN_ABS) { - continue; - } - printf("%5d %08x %5d %10s %10s %12s %s\n", - j, sym->st_value, sym->st_size, - sym_type(ELF32_ST_TYPE(sym->st_info)), - sym_bind(ELF32_ST_BIND(sym->st_info)), - sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)), - name); - } - } - printf("\n"); -} - -static void print_absolute_relocs(void) -{ - int i, printed = 0; - - for(i = 0; i < ehdr.e_shnum; i++) { - char *sym_strtab; - Elf32_Sym *sh_symtab; - unsigned sec_applies, sec_symtab; - int j; - if (shdr[i].sh_type != SHT_REL) { - continue; - } - sec_symtab = shdr[i].sh_link; - sec_applies = shdr[i].sh_info; - if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { - continue; - } - sh_symtab = symtab[sec_symtab]; - sym_strtab = strtab[shdr[sec_symtab].sh_link]; - for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { - Elf32_Rel *rel; - Elf32_Sym *sym; - const char *name; - rel = &reltab[i][j]; - sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; - name = sym_name(sym_strtab, sym); - if (sym->st_shndx != SHN_ABS) { - continue; - } - - /* Absolute symbols are not relocated if bzImage is - * loaded at a non-compiled address. Display a warning - * to user at compile time about the absolute - * relocations present. - * - * User need to audit the code to make sure - * some symbols which should have been section - * relative have not become absolute because of some - * linker optimization or wrong programming usage. - * - * Before warning check if this absolute symbol - * relocation is harmless. - */ - if (is_safe_abs_reloc(name)) - continue; - - if (!printed) { - printf("WARNING: Absolute relocations" - " present\n"); - printf("Offset Info Type Sym.Value " - "Sym.Name\n"); - printed = 1; - } - - printf("%08x %08x %10s %08x %s\n", - rel->r_offset, - rel->r_info, - rel_type(ELF32_R_TYPE(rel->r_info)), - sym->st_value, - name); - } - } - - if (printed) - printf("\n"); -} - -static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) -{ - int i; - /* Walk through the relocations */ - for(i = 0; i < ehdr.e_shnum; i++) { - char *sym_strtab; - Elf32_Sym *sh_symtab; - unsigned sec_applies, sec_symtab; - int j; - if (shdr[i].sh_type != SHT_REL) { - continue; - } - sec_symtab = shdr[i].sh_link; - sec_applies = shdr[i].sh_info; - if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { - continue; - } - sh_symtab = symtab[sec_symtab]; - sym_strtab = strtab[shdr[sec_symtab].sh_link]; - for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { - Elf32_Rel *rel; - Elf32_Sym *sym; - unsigned r_type; - rel = &reltab[i][j]; - sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; - r_type = ELF32_R_TYPE(rel->r_info); - /* Don't visit relocations to absolute symbols */ - if (sym->st_shndx == SHN_ABS) { - continue; - } - if (r_type == R_386_PC32) { - /* PC relative relocations don't need to be adjusted */ - } - else if (r_type == R_386_32) { - /* Visit relocations that need to be adjusted */ - visit(rel, sym); - } - else { - die("Unsupported relocation type: %d\n", r_type); - } - } - } -} - -static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) -{ - reloc_count += 1; -} - -static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) -{ - /* Remember the address that needs to be adjusted. */ - relocs[reloc_idx++] = rel->r_offset; -} - -static int cmp_relocs(const void *va, const void *vb) -{ - const unsigned long *a, *b; - a = va; b = vb; - return (*a == *b)? 0 : (*a > *b)? 1 : -1; -} - -static void emit_relocs(int as_text) -{ - int i; - /* Count how many relocations I have and allocate space for them. */ - reloc_count = 0; - walk_relocs(count_reloc); - relocs = malloc(reloc_count * sizeof(relocs[0])); - if (!relocs) { - die("malloc of %d entries for relocs failed\n", - reloc_count); - } - /* Collect up the relocations */ - reloc_idx = 0; - walk_relocs(collect_reloc); - - /* Order the relocations for more efficient processing */ - qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); - - /* Print the relocations */ - if (as_text) { - /* Print the relocations in a form suitable that - * gas will like. - */ - printf(".section \".data.reloc\",\"a\"\n"); - printf(".balign 4\n"); - for(i = 0; i < reloc_count; i++) { - printf("\t .long 0x%08lx\n", relocs[i]); - } - printf("\n"); - } - else { - unsigned char buf[4]; - buf[0] = buf[1] = buf[2] = buf[3] = 0; - /* Print a stop */ - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); - /* Now print each relocation */ - for(i = 0; i < reloc_count; i++) { - buf[0] = (relocs[i] >> 0) & 0xff; - buf[1] = (relocs[i] >> 8) & 0xff; - buf[2] = (relocs[i] >> 16) & 0xff; - buf[3] = (relocs[i] >> 24) & 0xff; - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); - } - } -} - -static void usage(void) -{ - die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); -} - -int main(int argc, char **argv) -{ - int show_absolute_syms, show_absolute_relocs; - int as_text; - const char *fname; - FILE *fp; - int i; - - show_absolute_syms = 0; - show_absolute_relocs = 0; - as_text = 0; - fname = NULL; - for(i = 1; i < argc; i++) { - char *arg = argv[i]; - if (*arg == '-') { - if (strcmp(argv[1], "--abs-syms") == 0) { - show_absolute_syms = 1; - continue; - } - - if (strcmp(argv[1], "--abs-relocs") == 0) { - show_absolute_relocs = 1; - continue; - } - else if (strcmp(argv[1], "--text") == 0) { - as_text = 1; - continue; - } - } - else if (!fname) { - fname = arg; - continue; - } - usage(); - } - if (!fname) { - usage(); - } - fp = fopen(fname, "r"); - if (!fp) { - die("Cannot open %s: %s\n", - fname, strerror(errno)); - } - read_ehdr(fp); - read_shdrs(fp); - read_strtabs(fp); - read_symtabs(fp); - read_relocs(fp); - if (show_absolute_syms) { - print_absolute_symbols(); - return 0; - } - if (show_absolute_relocs) { - print_absolute_relocs(); - return 0; - } - emit_relocs(as_text); - return 0; -} diff --git a/trunk/arch/i386/boot/compressed/vmlinux.lds b/trunk/arch/i386/boot/compressed/vmlinux.lds deleted file mode 100644 index cc4854f6c6c1..000000000000 --- a/trunk/arch/i386/boot/compressed/vmlinux.lds +++ /dev/null @@ -1,43 +0,0 @@ -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(startup_32) -SECTIONS -{ - /* Be careful parts of head.S assume startup_32 is at - * address 0. - */ - . = 0 ; - .text.head : { - _head = . ; - *(.text.head) - _ehead = . ; - } - .data.compressed : { - *(.data.compressed) - } - .text : { - _text = .; /* Text */ - *(.text) - *(.text.*) - _etext = . ; - } - .rodata : { - _rodata = . ; - *(.rodata) /* read-only data */ - *(.rodata.*) - _erodata = . ; - } - .data : { - _data = . ; - *(.data) - *(.data.*) - _edata = . ; - } - .bss : { - _bss = . ; - *(.bss) - *(.bss.*) - *(COMMON) - _end = . ; - } -} diff --git a/trunk/arch/i386/boot/compressed/vmlinux.scr b/trunk/arch/i386/boot/compressed/vmlinux.scr index 707a88f7f29e..1ed9d791f863 100644 --- a/trunk/arch/i386/boot/compressed/vmlinux.scr +++ b/trunk/arch/i386/boot/compressed/vmlinux.scr @@ -1,10 +1,9 @@ SECTIONS { - .data.compressed : { + .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) - output_len = . - 4; input_data_end = .; } } diff --git a/trunk/arch/i386/boot/setup.S b/trunk/arch/i386/boot/setup.S index 06edf1c66242..3aec4538a113 100644 --- a/trunk/arch/i386/boot/setup.S +++ b/trunk/arch/i386/boot/setup.S @@ -81,7 +81,7 @@ start: # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature - .word 0x0205 # header version number (>= 0x0105) + .word 0x0204 # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) realmode_swtch: .word 0, 0 # default_switch, SETUPSEG start_sys_seg: .word SYSSEG @@ -160,17 +160,6 @@ ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff # The highest safe address for # the contents of an initrd -kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment - #required for protected mode - #kernel -#ifdef CONFIG_RELOCATABLE -relocatable_kernel: .byte 1 -#else -relocatable_kernel: .byte 0 -#endif -pad2: .byte 0 -pad3: .word 0 - trampoline: call start_of_setup .align 16 # The offset at this point is 0x240 @@ -599,6 +588,11 @@ rmodeswtch_normal: call default_switch rmodeswtch_end: +# we get the code32 start address and modify the below 'jmpi' +# (loader may have changed it) + movl %cs:code32_start, %eax + movl %eax, %cs:code32 + # Now we move the system to its rightful place ... but we check if we have a # big-kernel. In that case we *must* not move it ... testb $LOADED_HIGH, %cs:loadflags @@ -794,12 +788,11 @@ a20_err_msg: a20_done: #endif /* CONFIG_X86_VOYAGER */ -# set up gdt and idt and 32bit start address +# set up gdt and idt lidt idt_48 # load idt with 0,0 xorl %eax, %eax # Compute gdt_base movw %ds, %ax # (Convert %ds:gdt to a linear ptr) shll $4, %eax - addl %eax, code32 addl $gdt, %eax movl %eax, (gdt_48+2) lgdt gdt_48 # load gdt with whatever is @@ -858,26 +851,9 @@ flush_instr: # Manual, Mixing 16-bit and 32-bit code, page 16-6) .byte 0x66, 0xea # prefix + jmpi-opcode -code32: .long startup_32 # will be set to %cs+startup_32 +code32: .long 0x1000 # will be set to 0x100000 + # for big kernels .word __BOOT_CS -.code32 -startup_32: - movl $(__BOOT_DS), %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %fs - movl %eax, %gs - movl %eax, %ss - - xorl %eax, %eax -1: incl %eax # check that A20 really IS enabled - movl %eax, 0x00000000 # loop forever if it isn't - cmpl %eax, 0x00100000 - je 1b - - # Jump to the 32bit entry point - jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi) -.code16 # Here's a bunch of information about your current kernel.. kernel_version: .ascii UTS_RELEASE diff --git a/trunk/arch/i386/defconfig b/trunk/arch/i386/defconfig index 65891f11aced..97aacd6bd7d8 100644 --- a/trunk/arch/i386/defconfig +++ b/trunk/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-git7 -# Wed Dec 6 23:50:49 2006 +# Linux kernel version: 2.6.19-rc2-git4 +# Sat Oct 21 03:38:56 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -40,14 +40,13 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set -CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -111,7 +110,6 @@ CONFIG_SMP=y # CONFIG_X86_VISWS is not set CONFIG_X86_GENERICARCH=y # CONFIG_X86_ES7000 is not set -# CONFIG_PARAVIRT is not set CONFIG_X86_CYCLONE_TIMER=y # CONFIG_M386 is not set # CONFIG_M486 is not set @@ -122,7 +120,6 @@ CONFIG_X86_CYCLONE_TIMER=y # CONFIG_MPENTIUMII is not set CONFIG_MPENTIUMIII=y # CONFIG_MPENTIUMM is not set -# CONFIG_MCORE2 is not set # CONFIG_MPENTIUM4 is not set # CONFIG_MK6 is not set # CONFIG_MK7 is not set @@ -200,6 +197,7 @@ CONFIG_RESOURCES_64BIT=y CONFIG_MTRR=y # CONFIG_EFI is not set # CONFIG_IRQBALANCE is not set +CONFIG_REGPARM=y CONFIG_SECCOMP=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y @@ -207,8 +205,7 @@ CONFIG_HZ_250=y CONFIG_HZ=250 # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set -# CONFIG_RELOCATABLE is not set -CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 # CONFIG_HOTPLUG_CPU is not set CONFIG_COMPAT_VDSO=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y @@ -370,7 +367,6 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -681,7 +677,6 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set @@ -855,7 +850,6 @@ CONFIG_BNX2=y # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -990,6 +984,10 @@ CONFIG_RTC=y # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# CONFIG_AGP=y # CONFIG_AGP_ALI is not set # CONFIG_AGP_ATI is not set @@ -1110,7 +1108,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set -# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1188,7 +1185,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set CONFIG_USB_MON=y diff --git a/trunk/arch/i386/kernel/Makefile b/trunk/arch/i386/kernel/Makefile index 1e8988e558c5..1a884b6e6e5c 100644 --- a/trunk/arch/i386/kernel/Makefile +++ b/trunk/arch/i386/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ - pci-dma.o i386_ksyms.o i387.o bootflag.o e820.o\ + pci-dma.o i386_ksyms.o i387.o bootflag.o \ quirks.o i8237.o topology.o alternative.o i8253.o tsc.o obj-$(CONFIG_STACKTRACE) += stacktrace.o @@ -40,9 +40,6 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o -# Make sure this is linked after any other paravirt_ops structs: see head.S -obj-$(CONFIG_PARAVIRT) += paravirt.o - EXTRA_AFLAGS := -traditional obj-$(CONFIG_SCx200) += scx200.o diff --git a/trunk/arch/i386/kernel/acpi/cstate.c b/trunk/arch/i386/kernel/acpi/cstate.c index 12e937c1ce4b..4664b55f623e 100644 --- a/trunk/arch/i386/kernel/acpi/cstate.c +++ b/trunk/arch/i386/kernel/acpi/cstate.c @@ -156,8 +156,10 @@ static int __init ffh_cstate_init(void) static void __exit ffh_cstate_exit(void) { - free_percpu(cpu_cstate_entry); - cpu_cstate_entry = NULL; + if (cpu_cstate_entry) { + free_percpu(cpu_cstate_entry); + cpu_cstate_entry = NULL; + } } arch_initcall(ffh_cstate_init); diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index 4b60af7f91dd..c9841692bb7c 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -10,7 +10,6 @@ #include #include #include -#include #ifdef CONFIG_ACPI @@ -50,24 +49,6 @@ static int __init check_bridge(int vendor, int device) return 0; } -static void check_intel(void) -{ - u16 vendor, device; - - vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID); - - if (vendor != PCI_VENDOR_ID_INTEL) - return; - - device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); -#ifdef CONFIG_SMP - if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || - device == PCI_DEVICE_ID_INTEL_E7520_MCH || - device == PCI_DEVICE_ID_INTEL_E7525_MCH) - quirk_intel_irqbalance(); -#endif -} - void __init check_acpi_pci(void) { int num, slot, func; @@ -79,8 +60,6 @@ void __init check_acpi_pci(void) if (!early_pci_allowed()) return; - check_intel(); - /* Poor man's PCI discovery */ for (num = 0; num < 32; num++) { for (slot = 0; slot < 32; slot++) { diff --git a/trunk/arch/i386/kernel/alternative.c b/trunk/arch/i386/kernel/alternative.c index 9eca21b49f6b..535f9794fba1 100644 --- a/trunk/arch/i386/kernel/alternative.c +++ b/trunk/arch/i386/kernel/alternative.c @@ -124,20 +124,6 @@ static unsigned char** find_nop_table(void) #endif /* CONFIG_X86_64 */ -static void nop_out(void *insns, unsigned int len) -{ - unsigned char **noptable = find_nop_table(); - - while (len > 0) { - unsigned int noplen = len; - if (noplen > ASM_NOP_MAX) - noplen = ASM_NOP_MAX; - memcpy(insns, noptable[noplen], noplen); - insns += noplen; - len -= noplen; - } -} - extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; extern u8 *__smp_locks[], *__smp_locks_end[]; @@ -152,9 +138,10 @@ extern u8 __smp_alt_begin[], __smp_alt_end[]; void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { + unsigned char **noptable = find_nop_table(); struct alt_instr *a; u8 *instr; - int diff; + int diff, i, k; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { @@ -172,7 +159,13 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) #endif memcpy(instr, a->replacement, a->replacementlen); diff = a->instrlen - a->replacementlen; - nop_out(instr + a->replacementlen, diff); + /* Pad the rest with nops */ + for (i = a->replacementlen; diff > 0; diff -= k, i += k) { + k = diff; + if (k > ASM_NOP_MAX) + k = ASM_NOP_MAX; + memcpy(a->instr + i, noptable[k], k); + } } } @@ -216,6 +209,7 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) { + unsigned char **noptable = find_nop_table(); u8 **ptr; for (ptr = start; ptr < end; ptr++) { @@ -223,7 +217,7 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end continue; if (*ptr > text_end) continue; - nop_out(*ptr, 1); + **ptr = noptable[1][0]; }; } @@ -349,40 +343,6 @@ void alternatives_smp_switch(int smp) #endif -#ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) -{ - struct paravirt_patch *p; - - for (p = start; p < end; p++) { - unsigned int used; - - used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, - p->len); -#ifdef CONFIG_DEBUG_PARAVIRT - { - int i; - /* Deliberately clobber regs using "not %reg" to find bugs. */ - for (i = 0; i < 3; i++) { - if (p->len - used >= 2 && (p->clobbers & (1 << i))) { - memcpy(p->instr + used, "\xf7\xd0", 2); - p->instr[used+1] |= i; - used += 2; - } - } - } -#endif - /* Pad the rest with nops */ - nop_out(p->instr + used, p->len - used); - } - - /* Sync to be conservative, in case we patched following instructions */ - sync_core(); -} -extern struct paravirt_patch __start_parainstructions[], - __stop_parainstructions[]; -#endif /* CONFIG_PARAVIRT */ - void __init alternative_instructions(void) { unsigned long flags; @@ -430,6 +390,5 @@ void __init alternative_instructions(void) alternatives_smp_switch(0); } #endif - apply_paravirt(__start_parainstructions, __stop_parainstructions); local_irq_restore(flags); } diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 776d9be26af9..2fd4b7d927c2 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -647,30 +647,23 @@ static struct { static int lapic_suspend(struct sys_device *dev, pm_message_t state) { unsigned long flags; - int maxlvt; if (!apic_pm_state.active) return 0; - maxlvt = get_maxlvt(); - apic_pm_state.apic_id = apic_read(APIC_ID); apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); apic_pm_state.apic_ldr = apic_read(APIC_LDR); apic_pm_state.apic_dfr = apic_read(APIC_DFR); apic_pm_state.apic_spiv = apic_read(APIC_SPIV); apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); - if (maxlvt >= 4) - apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); + apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); -#ifdef CONFIG_X86_MCE_P4THERMAL - if (maxlvt >= 5) - apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); -#endif + apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); local_irq_save(flags); disable_local_APIC(); @@ -682,13 +675,10 @@ static int lapic_resume(struct sys_device *dev) { unsigned int l, h; unsigned long flags; - int maxlvt; if (!apic_pm_state.active) return 0; - maxlvt = get_maxlvt(); - local_irq_save(flags); /* @@ -710,12 +700,8 @@ static int lapic_resume(struct sys_device *dev) apic_write(APIC_SPIV, apic_pm_state.apic_spiv); apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); -#ifdef CONFIG_X86_MCE_P4THERMAL - if (maxlvt >= 5) - apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); -#endif - if (maxlvt >= 4) - apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); + apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); + apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); apic_write(APIC_TMICT, apic_pm_state.apic_tmict); diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c index a97847da9ed5..a60358fe9a49 100644 --- a/trunk/arch/i386/kernel/apm.c +++ b/trunk/arch/i386/kernel/apm.c @@ -231,7 +231,6 @@ #include #include #include -#include #include "io_ports.h" @@ -2236,7 +2235,7 @@ static int __init apm_init(void) dmi_check_system(apm_dmi_table); - if (apm_info.bios.version == 0 || paravirt_enabled()) { + if (apm_info.bios.version == 0) { printk(KERN_INFO "apm: BIOS not found.\n"); return -ENODEV; } diff --git a/trunk/arch/i386/kernel/asm-offsets.c b/trunk/arch/i386/kernel/asm-offsets.c index 1b2f3cd33270..c80271f8f084 100644 --- a/trunk/arch/i386/kernel/asm-offsets.c +++ b/trunk/arch/i386/kernel/asm-offsets.c @@ -15,7 +15,6 @@ #include #include #include -#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -52,35 +51,13 @@ void foo(void) OFFSET(TI_exec_domain, thread_info, exec_domain); OFFSET(TI_flags, thread_info, flags); OFFSET(TI_status, thread_info, status); + OFFSET(TI_cpu, thread_info, cpu); OFFSET(TI_preempt_count, thread_info, preempt_count); OFFSET(TI_addr_limit, thread_info, addr_limit); OFFSET(TI_restart_block, thread_info, restart_block); OFFSET(TI_sysenter_return, thread_info, sysenter_return); BLANK(); - OFFSET(GDS_size, Xgt_desc_struct, size); - OFFSET(GDS_address, Xgt_desc_struct, address); - OFFSET(GDS_pad, Xgt_desc_struct, pad); - BLANK(); - - OFFSET(PT_EBX, pt_regs, ebx); - OFFSET(PT_ECX, pt_regs, ecx); - OFFSET(PT_EDX, pt_regs, edx); - OFFSET(PT_ESI, pt_regs, esi); - OFFSET(PT_EDI, pt_regs, edi); - OFFSET(PT_EBP, pt_regs, ebp); - OFFSET(PT_EAX, pt_regs, eax); - OFFSET(PT_DS, pt_regs, xds); - OFFSET(PT_ES, pt_regs, xes); - OFFSET(PT_GS, pt_regs, xgs); - OFFSET(PT_ORIG_EAX, pt_regs, orig_eax); - OFFSET(PT_EIP, pt_regs, eip); - OFFSET(PT_CS, pt_regs, xcs); - OFFSET(PT_EFLAGS, pt_regs, eflags); - OFFSET(PT_OLDESP, pt_regs, esp); - OFFSET(PT_OLDSS, pt_regs, xss); - BLANK(); - OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); OFFSET(RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext); BLANK(); @@ -97,18 +74,4 @@ void foo(void) DEFINE(VDSO_PRELINK, VDSO_PRELINK); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); - - BLANK(); - OFFSET(PDA_cpu, i386_pda, cpu_number); - OFFSET(PDA_pcurrent, i386_pda, pcurrent); - -#ifdef CONFIG_PARAVIRT - BLANK(); - OFFSET(PARAVIRT_enabled, paravirt_ops, paravirt_enabled); - OFFSET(PARAVIRT_irq_disable, paravirt_ops, irq_disable); - OFFSET(PARAVIRT_irq_enable, paravirt_ops, irq_enable); - OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit); - OFFSET(PARAVIRT_iret, paravirt_ops, iret); - OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0); -#endif } diff --git a/trunk/arch/i386/kernel/cpu/amd.c b/trunk/arch/i386/kernel/cpu/amd.c index 41cfea57232b..e4758095d87a 100644 --- a/trunk/arch/i386/kernel/cpu/amd.c +++ b/trunk/arch/i386/kernel/cpu/amd.c @@ -104,7 +104,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) f_vide(); rdtscl(d2); d = d2-d; - + + /* Knock these two lines out if it debugs out ok */ + printk(KERN_INFO "AMD K6 stepping B detected - "); + /* -- cut here -- */ if (d > 20*K6_BUG_LOOP) printk("system stability may be impaired when more than 32 MB are used.\n"); else diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 1b34c56f8123..d9f3e3c31f05 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -18,15 +18,14 @@ #include #include #endif -#include #include "cpu.h" DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); -struct i386_pda *_cpu_pda[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(_cpu_pda); +DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); +EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); static int cachesize_override __cpuinitdata = -1; static int disable_x86_fxsr __cpuinitdata; @@ -236,14 +235,29 @@ static int __cpuinit have_cpuid_p(void) return flag_is_changeable_p(X86_EFLAGS_ID); } -void __init cpu_detect(struct cpuinfo_x86 *c) +/* Do minimum CPU detection early. + Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. + The others are not touched to avoid unwanted side effects. + + WARNING: this function is only called on the BP. Don't add code here + that is supposed to run on all CPUs. */ +static void __init early_cpu_detect(void) { + struct cpuinfo_x86 *c = &boot_cpu_data; + + c->x86_cache_alignment = 32; + + if (!have_cpuid_p()) + return; + /* Get vendor name */ cpuid(0x00000000, &c->cpuid_level, (int *)&c->x86_vendor_id[0], (int *)&c->x86_vendor_id[8], (int *)&c->x86_vendor_id[4]); + get_cpu_vendor(c, 1); + c->x86 = 4; if (c->cpuid_level >= 0x00000001) { u32 junk, tfms, cap0, misc; @@ -260,26 +274,6 @@ void __init cpu_detect(struct cpuinfo_x86 *c) } } -/* Do minimum CPU detection early. - Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. - The others are not touched to avoid unwanted side effects. - - WARNING: this function is only called on the BP. Don't add code here - that is supposed to run on all CPUs. */ -static void __init early_cpu_detect(void) -{ - struct cpuinfo_x86 *c = &boot_cpu_data; - - c->x86_cache_alignment = 32; - - if (!have_cpuid_p()) - return; - - cpu_detect(c); - - get_cpu_vendor(c, 1); -} - static void __cpuinit generic_identify(struct cpuinfo_x86 * c) { u32 tfms, xlvl; @@ -314,8 +308,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c) #else c->apicid = (ebx >> 24) & 0xFF; #endif - if (c->x86_capability[0] & (1<<19)) - c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8; } else { /* Have CPUID level 0 only - unheard of */ c->x86 = 4; @@ -380,7 +372,6 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) c->x86_vendor_id[0] = '\0'; /* Unset */ c->x86_model_id[0] = '\0'; /* Unset */ c->x86_max_cores = 1; - c->x86_clflush_size = 32; memset(&c->x86_capability, 0, sizeof c->x86_capability); if (!have_cpuid_p()) { @@ -600,24 +591,42 @@ void __init early_cpu_init(void) disable_pse = 1; #endif } - -/* Make sure %gs is initialized properly in idle threads */ -struct pt_regs * __devinit idle_regs(struct pt_regs *regs) -{ - memset(regs, 0, sizeof(struct pt_regs)); - regs->xgs = __KERNEL_PDA; - return regs; -} - -static __cpuinit int alloc_gdt(int cpu) +/* + * cpu_init() initializes state that is per-CPU. Some data is already + * initialized (naturally) in the bootstrap process, such as the GDT + * and IDT. We reload them nevertheless, this function acts as a + * 'CPU state barrier', nothing should get across. + */ +void __cpuinit cpu_init(void) { - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + int cpu = smp_processor_id(); + struct tss_struct * t = &per_cpu(init_tss, cpu); + struct thread_struct *thread = ¤t->thread; struct desc_struct *gdt; - struct i386_pda *pda; + __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu); + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - gdt = (struct desc_struct *)cpu_gdt_descr->address; - pda = cpu_pda(cpu); + if (cpu_test_and_set(cpu, cpu_initialized)) { + printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); + for (;;) local_irq_enable(); + } + printk(KERN_INFO "Initializing CPU#%d\n", cpu); + + if (cpu_has_vme || cpu_has_tsc || cpu_has_de) + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); + if (tsc_disable && cpu_has_tsc) { + printk(KERN_NOTICE "Disabling TSC...\n"); + /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ + clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); + set_in_cr4(X86_CR4_TSD); + } + /* The CPU hotplug case */ + if (cpu_gdt_descr->address) { + gdt = (struct desc_struct *)cpu_gdt_descr->address; + memset(gdt, 0, PAGE_SIZE); + goto old_gdt; + } /* * This is a horrible hack to allocate the GDT. The problem * is that cpu_init() is called really early for the boot CPU @@ -625,130 +634,43 @@ static __cpuinit int alloc_gdt(int cpu) * CPUs, when bootmem will have gone away */ if (NODE_DATA(0)->bdata->node_bootmem_map) { - BUG_ON(gdt != NULL || pda != NULL); - - gdt = alloc_bootmem_pages(PAGE_SIZE); - pda = alloc_bootmem(sizeof(*pda)); - /* alloc_bootmem(_pages) panics on failure, so no check */ - + gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); + /* alloc_bootmem_pages panics on failure, so no check */ memset(gdt, 0, PAGE_SIZE); - memset(pda, 0, sizeof(*pda)); } else { - /* GDT and PDA might already have been allocated if - this is a CPU hotplug re-insertion. */ - if (gdt == NULL) - gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); - - if (pda == NULL) - pda = kmalloc_node(sizeof(*pda), GFP_KERNEL, cpu_to_node(cpu)); - - if (unlikely(!gdt || !pda)) { - free_pages((unsigned long)gdt, 0); - kfree(pda); - return 0; + gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); + if (unlikely(!gdt)) { + printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); + for (;;) + local_irq_enable(); } } - - cpu_gdt_descr->address = (unsigned long)gdt; - cpu_pda(cpu) = pda; - - return 1; -} - -/* Initial PDA used by boot CPU */ -struct i386_pda boot_pda = { - ._pda = &boot_pda, - .cpu_number = 0, - .pcurrent = &init_task, -}; - -static inline void set_kernel_gs(void) -{ - /* Set %gs for this CPU's PDA. Memory clobber is to create a - barrier with respect to any PDA operations, so the compiler - doesn't move any before here. */ - asm volatile ("mov %0, %%gs" : : "r" (__KERNEL_PDA) : "memory"); -} - -/* Initialize the CPU's GDT and PDA. The boot CPU does this for - itself, but secondaries find this done for them. */ -__cpuinit int init_gdt(int cpu, struct task_struct *idle) -{ - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - struct desc_struct *gdt; - struct i386_pda *pda; - - /* For non-boot CPUs, the GDT and PDA should already have been - allocated. */ - if (!alloc_gdt(cpu)) { - printk(KERN_CRIT "CPU%d failed to allocate GDT or PDA\n", cpu); - return 0; - } - - gdt = (struct desc_struct *)cpu_gdt_descr->address; - pda = cpu_pda(cpu); - - BUG_ON(gdt == NULL || pda == NULL); - +old_gdt: /* * Initialize the per-CPU GDT with the boot GDT, * and set up the GDT descriptor: */ memcpy(gdt, cpu_gdt_table, GDT_SIZE); - cpu_gdt_descr->size = GDT_SIZE - 1; - - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, - (u32 *)&gdt[GDT_ENTRY_PDA].b, - (unsigned long)pda, sizeof(*pda) - 1, - 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */ - memset(pda, 0, sizeof(*pda)); - pda->_pda = pda; - pda->cpu_number = cpu; - pda->pcurrent = idle; - - return 1; -} + /* Set up GDT entry for 16bit stack */ + *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |= + ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) | + ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) | + (CPU_16BIT_STACK_SIZE - 1); -/* Common CPU init for both boot and secondary CPUs */ -static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) -{ - struct tss_struct * t = &per_cpu(init_tss, cpu); - struct thread_struct *thread = &curr->thread; - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + cpu_gdt_descr->size = GDT_SIZE - 1; + cpu_gdt_descr->address = (unsigned long)gdt; - /* Reinit these anyway, even if they've already been done (on - the boot CPU, this will transition from the boot gdt+pda to - the real ones). */ load_gdt(cpu_gdt_descr); - set_kernel_gs(); - - if (cpu_test_and_set(cpu, cpu_initialized)) { - printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); - for (;;) local_irq_enable(); - } - - printk(KERN_INFO "Initializing CPU#%d\n", cpu); - - if (cpu_has_vme || cpu_has_tsc || cpu_has_de) - clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); - if (tsc_disable && cpu_has_tsc) { - printk(KERN_NOTICE "Disabling TSC...\n"); - /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ - clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); - set_in_cr4(X86_CR4_TSD); - } - load_idt(&idt_descr); /* * Set up and load the per-CPU TSS and LDT */ atomic_inc(&init_mm.mm_count); - curr->active_mm = &init_mm; - if (curr->mm) - BUG(); - enter_lazy_tlb(&init_mm, curr); + current->active_mm = &init_mm; + BUG_ON(current->mm); + enter_lazy_tlb(&init_mm, current); load_esp0(t, thread); set_tss_desc(cpu,t); @@ -760,8 +682,8 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); #endif - /* Clear %fs. */ - asm volatile ("mov %0, %%fs" : : "r" (0)); + /* Clear %fs and %gs. */ + asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r" (0)); /* Clear all 6 debug registers: */ set_debugreg(0, 0); @@ -779,37 +701,6 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) mxcsr_feature_mask_init(); } -/* Entrypoint to initialize secondary CPU */ -void __cpuinit secondary_cpu_init(void) -{ - int cpu = smp_processor_id(); - struct task_struct *curr = current; - - _cpu_init(cpu, curr); -} - -/* - * cpu_init() initializes state that is per-CPU. Some data is already - * initialized (naturally) in the bootstrap process, such as the GDT - * and IDT. We reload them nevertheless, this function acts as a - * 'CPU state barrier', nothing should get across. - */ -void __cpuinit cpu_init(void) -{ - int cpu = smp_processor_id(); - struct task_struct *curr = current; - - /* Set up the real GDT and PDA, so we can transition from the - boot versions. */ - if (!init_gdt(cpu, curr)) { - /* failed to allocate something; not much we can do... */ - for (;;) - local_irq_enable(); - } - - _cpu_init(cpu, curr); -} - #ifdef CONFIG_HOTPLUG_CPU void __cpuinit cpu_uninit(void) { diff --git a/trunk/arch/i386/kernel/cpu/intel.c b/trunk/arch/i386/kernel/cpu/intel.c index 56fe26584957..94a95aa5227e 100644 --- a/trunk/arch/i386/kernel/cpu/intel.c +++ b/trunk/arch/i386/kernel/cpu/intel.c @@ -107,7 +107,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) * Note that the workaround only should be initialized once... */ c->f00f_bug = 0; - if (!paravirt_enabled() && c->x86 == 5) { + if ( c->x86 == 5 ) { static int f00f_workaround_enabled = 0; c->f00f_bug = 1; @@ -195,17 +195,9 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); - - if (cpu_has_ds) { - unsigned int l1; - rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); - if (!(l1 & (1<<11))) - set_bit(X86_FEATURE_BTS, c->x86_capability); - if (!(l1 & (1<<12))) - set_bit(X86_FEATURE_PEBS, c->x86_capability); - } } + static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* Intel PIII Tualatin. This comes in two flavours. diff --git a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c index 80b4c5d421b1..5c43be47587f 100644 --- a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -480,10 +480,12 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) if (num_cache_leaves == 0) return -ENOENT; - cpuid4_info[cpu] = kzalloc( + cpuid4_info[cpu] = kmalloc( sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); if (unlikely(cpuid4_info[cpu] == NULL)) return -ENOMEM; + memset(cpuid4_info[cpu], 0, + sizeof(struct _cpuid4_info) * num_cache_leaves); oldmask = current->cpus_allowed; retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); @@ -656,14 +658,17 @@ static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) return -ENOENT; /* Allocate all required memory */ - cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); + cache_kobject[cpu] = kmalloc(sizeof(struct kobject), GFP_KERNEL); if (unlikely(cache_kobject[cpu] == NULL)) goto err_out; + memset(cache_kobject[cpu], 0, sizeof(struct kobject)); - index_kobject[cpu] = kzalloc( + index_kobject[cpu] = kmalloc( sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); if (unlikely(index_kobject[cpu] == NULL)) goto err_out; + memset(index_kobject[cpu], 0, + sizeof(struct _index_kobject) * num_cache_leaves); return 0; diff --git a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c b/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c index 065005c3f168..bad8b4420709 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c @@ -116,6 +116,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) return sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); } +#ifdef CONFIG_HOTPLUG_CPU static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) { return sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); @@ -152,6 +153,7 @@ static struct notifier_block thermal_throttle_cpu_notifier = { .notifier_call = thermal_throttle_cpu_callback, }; +#endif /* CONFIG_HOTPLUG_CPU */ static __init int thermal_throttle_init_device(void) { diff --git a/trunk/arch/i386/kernel/cpu/mtrr/Makefile b/trunk/arch/i386/kernel/cpu/mtrr/Makefile index 191fc0533649..a25b701ab84e 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/Makefile +++ b/trunk/arch/i386/kernel/cpu/mtrr/Makefile @@ -1,3 +1,5 @@ obj-y := main.o if.o generic.o state.o -obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o +obj-y += amd.o +obj-y += cyrix.o +obj-y += centaur.o diff --git a/trunk/arch/i386/kernel/cpu/mtrr/amd.c b/trunk/arch/i386/kernel/cpu/mtrr/amd.c index 0949cdbf848a..1a1e04b6fd00 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/amd.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/amd.c @@ -7,7 +7,7 @@ static void amd_get_mtrr(unsigned int reg, unsigned long *base, - unsigned long *size, mtrr_type * type) + unsigned int *size, mtrr_type * type) { unsigned long low, high; diff --git a/trunk/arch/i386/kernel/cpu/mtrr/centaur.c b/trunk/arch/i386/kernel/cpu/mtrr/centaur.c index cb9aa3a7a7ab..33f00ac314ef 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/centaur.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/centaur.c @@ -17,7 +17,7 @@ static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */ */ static int -centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) +centaur_get_free_region(unsigned long base, unsigned long size) /* [SUMMARY] Get a free MTRR. The starting (base) address of the region. The size (in bytes) of the region. @@ -26,11 +26,10 @@ centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) { int i, max; mtrr_type ltype; - unsigned long lbase, lsize; + unsigned long lbase; + unsigned int lsize; max = num_var_ranges; - if (replace_reg >= 0 && replace_reg < max) - return replace_reg; for (i = 0; i < max; ++i) { if (centaur_mcr_reserved & (1 << i)) continue; @@ -50,7 +49,7 @@ mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) static void centaur_get_mcr(unsigned int reg, unsigned long *base, - unsigned long *size, mtrr_type * type) + unsigned int *size, mtrr_type * type) { *base = centaur_mcr[reg].high >> PAGE_SHIFT; *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; diff --git a/trunk/arch/i386/kernel/cpu/mtrr/cyrix.c b/trunk/arch/i386/kernel/cpu/mtrr/cyrix.c index 0737a596db43..9027a987006b 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/cyrix.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/cyrix.c @@ -9,7 +9,7 @@ int arr3_protected; static void cyrix_get_arr(unsigned int reg, unsigned long *base, - unsigned long *size, mtrr_type * type) + unsigned int *size, mtrr_type * type) { unsigned long flags; unsigned char arr, ccr3, rcr, shift; @@ -77,7 +77,7 @@ cyrix_get_arr(unsigned int reg, unsigned long *base, } static int -cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) +cyrix_get_free_region(unsigned long base, unsigned long size) /* [SUMMARY] Get a free ARR. The starting (base) address of the region. The size (in bytes) of the region. @@ -86,24 +86,9 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) { int i; mtrr_type ltype; - unsigned long lbase, lsize; + unsigned long lbase; + unsigned int lsize; - switch (replace_reg) { - case 7: - if (size < 0x40) - break; - case 6: - case 5: - case 4: - return replace_reg; - case 3: - if (arr3_protected) - break; - case 2: - case 1: - case 0: - return replace_reg; - } /* If we are to set up a region >32M then look at ARR7 immediately */ if (size > 0x2000) { cyrix_get_arr(7, &lbase, &lsize, <ype); @@ -229,7 +214,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base, typedef struct { unsigned long base; - unsigned long size; + unsigned int size; mtrr_type type; } arr_state_t; diff --git a/trunk/arch/i386/kernel/cpu/mtrr/generic.c b/trunk/arch/i386/kernel/cpu/mtrr/generic.c index f77fc53db654..0b61eed8bbd8 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/generic.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/generic.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -16,19 +15,12 @@ struct mtrr_state { struct mtrr_var_range *var_ranges; mtrr_type fixed_ranges[NUM_FIXED_RANGES]; unsigned char enabled; - unsigned char have_fixed; mtrr_type def_type; }; static unsigned long smp_changes_mask; static struct mtrr_state mtrr_state = {}; -#undef MODULE_PARAM_PREFIX -#define MODULE_PARAM_PREFIX "mtrr." - -static __initdata int mtrr_show; -module_param_named(show, mtrr_show, bool, 0); - /* Get the MSR pair relating to a var range */ static void __init get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) @@ -51,14 +43,6 @@ get_fixed_ranges(mtrr_type * frs) rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]); } -static void __init print_fixed(unsigned base, unsigned step, const mtrr_type*types) -{ - unsigned i; - - for (i = 0; i < 8; ++i, ++types, base += step) - printk(KERN_INFO "MTRR %05X-%05X %s\n", base, base + step - 1, mtrr_attrib_to_str(*types)); -} - /* Grab all of the MTRR state for this CPU into *state */ void __init get_mtrr_state(void) { @@ -74,49 +58,13 @@ void __init get_mtrr_state(void) } vrs = mtrr_state.var_ranges; - rdmsr(MTRRcap_MSR, lo, dummy); - mtrr_state.have_fixed = (lo >> 8) & 1; - for (i = 0; i < num_var_ranges; i++) get_mtrr_var_range(i, &vrs[i]); - if (mtrr_state.have_fixed) - get_fixed_ranges(mtrr_state.fixed_ranges); + get_fixed_ranges(mtrr_state.fixed_ranges); rdmsr(MTRRdefType_MSR, lo, dummy); mtrr_state.def_type = (lo & 0xff); mtrr_state.enabled = (lo & 0xc00) >> 10; - - if (mtrr_show) { - int high_width; - - printk(KERN_INFO "MTRR default type: %s\n", mtrr_attrib_to_str(mtrr_state.def_type)); - if (mtrr_state.have_fixed) { - printk(KERN_INFO "MTRR fixed ranges %sabled:\n", - mtrr_state.enabled & 1 ? "en" : "dis"); - print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); - for (i = 0; i < 2; ++i) - print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8); - for (i = 0; i < 8; ++i) - print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8); - } - printk(KERN_INFO "MTRR variable ranges %sabled:\n", - mtrr_state.enabled & 2 ? "en" : "dis"); - high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4; - for (i = 0; i < num_var_ranges; ++i) { - if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) - printk(KERN_INFO "MTRR %u base %0*X%05X000 mask %0*X%05X000 %s\n", - i, - high_width, - mtrr_state.var_ranges[i].base_hi, - mtrr_state.var_ranges[i].base_lo >> 12, - high_width, - mtrr_state.var_ranges[i].mask_hi, - mtrr_state.var_ranges[i].mask_lo >> 12, - mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); - else - printk(KERN_INFO "MTRR %u disabled\n", i); - } - } } /* Some BIOS's are fucked and don't set all MTRRs the same! */ @@ -147,7 +95,7 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) smp_processor_id(), msr, a, b); } -int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) +int generic_get_free_region(unsigned long base, unsigned long size) /* [SUMMARY] Get a free MTRR. The starting (base) address of the region. The size (in bytes) of the region. @@ -156,11 +104,10 @@ int generic_get_free_region(unsigned long base, unsigned long size, int replace_ { int i, max; mtrr_type ltype; - unsigned long lbase, lsize; + unsigned long lbase; + unsigned lsize; max = num_var_ranges; - if (replace_reg >= 0 && replace_reg < max) - return replace_reg; for (i = 0; i < max; ++i) { mtrr_if->get(i, &lbase, &lsize, <ype); if (lsize == 0) @@ -170,7 +117,7 @@ int generic_get_free_region(unsigned long base, unsigned long size, int replace_ } static void generic_get_mtrr(unsigned int reg, unsigned long *base, - unsigned long *size, mtrr_type *type) + unsigned int *size, mtrr_type * type) { unsigned int mask_lo, mask_hi, base_lo, base_hi; @@ -255,9 +202,7 @@ static int set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) return changed; } -static u32 deftype_lo, deftype_hi; - -static unsigned long set_mtrr_state(void) +static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi) /* [SUMMARY] Set the MTRR state for this CPU. The MTRR state information to read. Some relevant CPU context. @@ -272,14 +217,14 @@ static unsigned long set_mtrr_state(void) if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i])) change_mask |= MTRR_CHANGE_MASK_VARIABLE; - if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges)) + if (set_fixed_ranges(mtrr_state.fixed_ranges)) change_mask |= MTRR_CHANGE_MASK_FIXED; /* Set_mtrr_restore restores the old value of MTRRdefType, so to set it we fiddle with the saved value */ if ((deftype_lo & 0xff) != mtrr_state.def_type || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { - deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | (mtrr_state.enabled << 10); + deftype_lo |= (mtrr_state.def_type | mtrr_state.enabled << 10); change_mask |= MTRR_CHANGE_MASK_DEFTYPE; } @@ -288,6 +233,7 @@ static unsigned long set_mtrr_state(void) static unsigned long cr4 = 0; +static u32 deftype_lo, deftype_hi; static DEFINE_SPINLOCK(set_atomicity_lock); /* @@ -325,7 +271,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); /* Disable MTRRs, and set the default type to uncached */ - mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & ~0xcff, deftype_hi); + mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi); } static void post_set(void) __releases(set_atomicity_lock) @@ -354,7 +300,7 @@ static void generic_set_all(void) prepare_set(); /* Actually set the state */ - mask = set_mtrr_state(); + mask = set_mtrr_state(deftype_lo,deftype_hi); post_set(); local_irq_restore(flags); @@ -420,7 +366,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); return -EINVAL; } - if (!(base + size < 0x70000 || base > 0x7003F) && + if (!(base + size < 0x70000000 || base > 0x7003FFFF) && (type == MTRR_TYPE_WRCOMB || type == MTRR_TYPE_WRBACK)) { printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); diff --git a/trunk/arch/i386/kernel/cpu/mtrr/if.c b/trunk/arch/i386/kernel/cpu/mtrr/if.c index 5ae1705eafa6..5ac051bb9d55 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/if.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/if.c @@ -17,7 +17,7 @@ extern unsigned int *usage_table; #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) -static const char *const mtrr_strings[MTRR_NUM_TYPES] = +static char *mtrr_strings[MTRR_NUM_TYPES] = { "uncachable", /* 0 */ "write-combining", /* 1 */ @@ -28,7 +28,7 @@ static const char *const mtrr_strings[MTRR_NUM_TYPES] = "write-back", /* 6 */ }; -const char *mtrr_attrib_to_str(int x) +char *mtrr_attrib_to_str(int x) { return (x <= 6) ? mtrr_strings[x] : "?"; } @@ -44,9 +44,10 @@ mtrr_file_add(unsigned long base, unsigned long size, max = num_var_ranges; if (fcount == NULL) { - fcount = kzalloc(max * sizeof *fcount, GFP_KERNEL); + fcount = kmalloc(max * sizeof *fcount, GFP_KERNEL); if (!fcount) return -ENOMEM; + memset(fcount, 0, max * sizeof *fcount); FILE_FCOUNT(file) = fcount; } if (!page) { @@ -154,7 +155,6 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) { int err = 0; mtrr_type type; - unsigned long size; struct mtrr_sentry sentry; struct mtrr_gentry gentry; void __user *arg = (void __user *) __arg; @@ -235,15 +235,15 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) case MTRRIOC_GET_ENTRY: if (gentry.regnum >= num_var_ranges) return -EINVAL; - mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); + mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); /* Hide entries that go above 4GB */ - if (gentry.base + size - 1 >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT)) - || size >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT))) + if (gentry.base + gentry.size > 0x100000 + || gentry.size == 0x100000) gentry.base = gentry.size = gentry.type = 0; else { gentry.base <<= PAGE_SHIFT; - gentry.size = size << PAGE_SHIFT; + gentry.size <<= PAGE_SHIFT; gentry.type = type; } @@ -273,14 +273,8 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) case MTRRIOC_GET_PAGE_ENTRY: if (gentry.regnum >= num_var_ranges) return -EINVAL; - mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); - /* Hide entries that would overflow */ - if (size != (__typeof__(gentry.size))size) - gentry.base = gentry.size = gentry.type = 0; - else { - gentry.size = size; - gentry.type = type; - } + mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); + gentry.type = type; break; } @@ -359,7 +353,8 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) char factor; int i, max, len; mtrr_type type; - unsigned long base, size; + unsigned long base; + unsigned int size; len = 0; max = num_var_ranges; @@ -378,7 +373,7 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) } /* RED-PEN: base can be > 32bit */ len += seq_printf(seq, - "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n", + "reg%02i: base=0x%05lx000 (%4liMB), size=%4i%cB: %s, count=%d\n", i, base, base >> (20 - PAGE_SHIFT), size, factor, mtrr_attrib_to_str(type), usage_table[i]); } diff --git a/trunk/arch/i386/kernel/cpu/mtrr/main.c b/trunk/arch/i386/kernel/cpu/mtrr/main.c index 16bb7ea87145..fff90bda4733 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/main.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/main.c @@ -59,11 +59,7 @@ struct mtrr_ops * mtrr_if = NULL; static void set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type); -#ifndef CONFIG_X86_64 extern int arr3_protected; -#else -#define arr3_protected 0 -#endif void set_mtrr_ops(struct mtrr_ops * ops) { @@ -172,13 +168,6 @@ static void ipi_handler(void *info) #endif -static inline int types_compatible(mtrr_type type1, mtrr_type type2) { - return type1 == MTRR_TYPE_UNCACHABLE || - type2 == MTRR_TYPE_UNCACHABLE || - (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) || - (type1 == MTRR_TYPE_WRBACK && type2 == MTRR_TYPE_WRTHROUGH); -} - /** * set_mtrr - update mtrrs on all processors * @reg: mtrr in question @@ -274,8 +263,8 @@ static void set_mtrr(unsigned int reg, unsigned long base, /** * mtrr_add_page - Add a memory type region - * @base: Physical base address of region in pages (in units of 4 kB!) - * @size: Physical size of region in pages (4 kB) + * @base: Physical base address of region in pages (4 KB) + * @size: Physical size of region in pages (4 KB) * @type: Type of MTRR desired * @increment: If this is true do usage counting on the region * @@ -311,9 +300,11 @@ static void set_mtrr(unsigned int reg, unsigned long base, int mtrr_add_page(unsigned long base, unsigned long size, unsigned int type, char increment) { - int i, replace, error; + int i; mtrr_type ltype; - unsigned long lbase, lsize; + unsigned long lbase; + unsigned int lsize; + int error; if (!mtrr_if) return -ENXIO; @@ -333,18 +324,12 @@ int mtrr_add_page(unsigned long base, unsigned long size, return -ENOSYS; } - if (!size) { - printk(KERN_WARNING "mtrr: zero sized request\n"); - return -EINVAL; - } - if (base & size_or_mask || size & size_or_mask) { printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n"); return -EINVAL; } error = -EINVAL; - replace = -1; /* No CPU hotplug when we change MTRR entries */ lock_cpu_hotplug(); @@ -352,28 +337,21 @@ int mtrr_add_page(unsigned long base, unsigned long size, mutex_lock(&mtrr_mutex); for (i = 0; i < num_var_ranges; ++i) { mtrr_if->get(i, &lbase, &lsize, <ype); - if (!lsize || base > lbase + lsize - 1 || base + size - 1 < lbase) + if (base >= lbase + lsize) + continue; + if ((base < lbase) && (base + size <= lbase)) continue; /* At this point we know there is some kind of overlap/enclosure */ - if (base < lbase || base + size - 1 > lbase + lsize - 1) { - if (base <= lbase && base + size - 1 >= lbase + lsize - 1) { - /* New region encloses an existing region */ - if (type == ltype) { - replace = replace == -1 ? i : -2; - continue; - } - else if (types_compatible(type, ltype)) - continue; - } + if ((base < lbase) || (base + size > lbase + lsize)) { printk(KERN_WARNING "mtrr: 0x%lx000,0x%lx000 overlaps existing" - " 0x%lx000,0x%lx000\n", base, size, lbase, + " 0x%lx000,0x%x000\n", base, size, lbase, lsize); goto out; } /* New region is enclosed by an existing region */ if (ltype != type) { - if (types_compatible(type, ltype)) + if (type == MTRR_TYPE_UNCACHABLE) continue; printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", base, size, mtrr_attrib_to_str(ltype), @@ -386,18 +364,10 @@ int mtrr_add_page(unsigned long base, unsigned long size, goto out; } /* Search for an empty MTRR */ - i = mtrr_if->get_free_region(base, size, replace); + i = mtrr_if->get_free_region(base, size); if (i >= 0) { set_mtrr(i, base, size, type); - if (likely(replace < 0)) - usage_table[i] = 1; - else { - usage_table[i] = usage_table[replace] + !!increment; - if (unlikely(replace != i)) { - set_mtrr(replace, 0, 0, 0); - usage_table[replace] = 0; - } - } + usage_table[i] = 1; } else printk(KERN_INFO "mtrr: no more MTRRs available\n"); error = i; @@ -485,7 +455,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) { int i, max; mtrr_type ltype; - unsigned long lbase, lsize; + unsigned long lbase; + unsigned int lsize; int error = -EINVAL; if (!mtrr_if) @@ -573,11 +544,9 @@ extern void centaur_init_mtrr(void); static void __init init_ifs(void) { -#ifndef CONFIG_X86_64 amd_init_mtrr(); cyrix_init_mtrr(); centaur_init_mtrr(); -#endif } /* The suspend/resume methods are only for CPU without MTRR. CPU using generic @@ -586,7 +555,7 @@ static void __init init_ifs(void) struct mtrr_value { mtrr_type ltype; unsigned long lbase; - unsigned long lsize; + unsigned int lsize; }; static struct mtrr_value * mtrr_state; @@ -596,8 +565,10 @@ static int mtrr_save(struct sys_device * sysdev, pm_message_t state) int i; int size = num_var_ranges * sizeof(struct mtrr_value); - mtrr_state = kzalloc(size,GFP_ATOMIC); - if (!mtrr_state) + mtrr_state = kmalloc(size,GFP_ATOMIC); + if (mtrr_state) + memset(mtrr_state,0,size); + else return -ENOMEM; for (i = 0; i < num_var_ranges; i++) { diff --git a/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h b/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h index d61ea9db6cfe..99c9f2682041 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h +++ b/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h @@ -43,16 +43,15 @@ struct mtrr_ops { void (*set_all)(void); void (*get)(unsigned int reg, unsigned long *base, - unsigned long *size, mtrr_type * type); - int (*get_free_region)(unsigned long base, unsigned long size, - int replace_reg); + unsigned int *size, mtrr_type * type); + int (*get_free_region) (unsigned long base, unsigned long size); + int (*validate_add_page)(unsigned long base, unsigned long size, unsigned int type); int (*have_wrcomb)(void); }; -extern int generic_get_free_region(unsigned long base, unsigned long size, - int replace_reg); +extern int generic_get_free_region(unsigned long base, unsigned long size); extern int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type); @@ -63,17 +62,17 @@ extern int positive_have_wrcomb(void); /* library functions for processor-specific routines */ struct set_mtrr_context { unsigned long flags; + unsigned long deftype_lo; + unsigned long deftype_hi; unsigned long cr4val; - u32 deftype_lo; - u32 deftype_hi; - u32 ccr3; + unsigned long ccr3; }; struct mtrr_var_range { - u32 base_lo; - u32 base_hi; - u32 mask_lo; - u32 mask_hi; + unsigned long base_lo; + unsigned long base_hi; + unsigned long mask_lo; + unsigned long mask_hi; }; void set_mtrr_done(struct set_mtrr_context *ctxt); @@ -93,6 +92,6 @@ extern struct mtrr_ops * mtrr_if; extern unsigned int num_var_ranges; void mtrr_state_warn(void); -const char *mtrr_attrib_to_str(int x); +char *mtrr_attrib_to_str(int x); void mtrr_wrmsr(unsigned, unsigned, unsigned); diff --git a/trunk/arch/i386/kernel/cpu/proc.c b/trunk/arch/i386/kernel/cpu/proc.c index 6624d8583c42..76aac088a323 100644 --- a/trunk/arch/i386/kernel/cpu/proc.c +++ b/trunk/arch/i386/kernel/cpu/proc.c @@ -152,10 +152,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, " [%d]", i); } - seq_printf(m, "\nbogomips\t: %lu.%02lu\n", + seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n", c->loops_per_jiffy/(500000/HZ), (c->loops_per_jiffy/(5000/HZ)) % 100); - seq_printf(m, "clflush size\t: %u\n\n", c->x86_clflush_size); return 0; } diff --git a/trunk/arch/i386/kernel/cpuid.c b/trunk/arch/i386/kernel/cpuid.c index db6dd20c3589..ab0c327e79dc 100644 --- a/trunk/arch/i386/kernel/cpuid.c +++ b/trunk/arch/i386/kernel/cpuid.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -166,6 +167,7 @@ static int cpuid_device_create(int i) return err; } +#ifdef CONFIG_HOTPLUG_CPU static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -185,6 +187,7 @@ static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier = { .notifier_call = cpuid_class_cpu_callback, }; +#endif /* !CONFIG_HOTPLUG_CPU */ static int __init cpuid_init(void) { diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index a5e0e990ea95..144b43288965 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -31,6 +31,68 @@ /* This keeps a track of which one is crashing cpu. */ static int crashing_cpu; +static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, + size_t data_len) +{ + struct elf_note note; + + note.n_namesz = strlen(name) + 1; + note.n_descsz = data_len; + note.n_type = type; + memcpy(buf, ¬e, sizeof(note)); + buf += (sizeof(note) +3)/4; + memcpy(buf, name, note.n_namesz); + buf += (note.n_namesz + 3)/4; + memcpy(buf, data, note.n_descsz); + buf += (note.n_descsz + 3)/4; + + return buf; +} + +static void final_note(u32 *buf) +{ + struct elf_note note; + + note.n_namesz = 0; + note.n_descsz = 0; + note.n_type = 0; + memcpy(buf, ¬e, sizeof(note)); +} + +static void crash_save_this_cpu(struct pt_regs *regs, int cpu) +{ + struct elf_prstatus prstatus; + u32 *buf; + + if ((cpu < 0) || (cpu >= NR_CPUS)) + return; + + /* Using ELF notes here is opportunistic. + * I need a well defined structure format + * for the data I pass, and I need tags + * on the data to indicate what information I have + * squirrelled away. ELF notes happen to provide + * all of that, so there is no need to invent something new. + */ + buf = (u32*)per_cpu_ptr(crash_notes, cpu); + if (!buf) + return; + memset(&prstatus, 0, sizeof(prstatus)); + prstatus.pr_pid = current->pid; + elf_core_copy_regs(&prstatus.pr_reg, regs); + buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, + sizeof(prstatus)); + final_note(buf); +} + +static void crash_save_self(struct pt_regs *regs) +{ + int cpu; + + cpu = safe_smp_processor_id(); + crash_save_this_cpu(regs, cpu); +} + #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) static atomic_t waiting_for_crash_ipi; @@ -59,7 +121,7 @@ static int crash_nmi_callback(struct notifier_block *self, crash_fixup_ss_esp(&fixed_regs, regs); regs = &fixed_regs; } - crash_save_cpu(regs, cpu); + crash_save_this_cpu(regs, cpu); disable_local_APIC(); atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ @@ -133,5 +195,5 @@ void machine_crash_shutdown(struct pt_regs *regs) #if defined(CONFIG_X86_IO_APIC) disable_IO_APIC(); #endif - crash_save_cpu(regs, safe_smp_processor_id()); + crash_save_self(regs); } diff --git a/trunk/arch/i386/kernel/e820.c b/trunk/arch/i386/kernel/e820.c deleted file mode 100644 index 2f7d0a92fd7c..000000000000 --- a/trunk/arch/i386/kernel/e820.c +++ /dev/null @@ -1,894 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef CONFIG_EFI -int efi_enabled = 0; -EXPORT_SYMBOL(efi_enabled); -#endif - -struct e820map e820; -struct change_member { - struct e820entry *pbios; /* pointer to original bios entry */ - unsigned long long addr; /* address for this change point */ -}; -static struct change_member change_point_list[2*E820MAX] __initdata; -static struct change_member *change_point[2*E820MAX] __initdata; -static struct e820entry *overlap_list[E820MAX] __initdata; -static struct e820entry new_bios[E820MAX] __initdata; -/* For PCI or other memory-mapped resources */ -unsigned long pci_mem_start = 0x10000000; -#ifdef CONFIG_PCI -EXPORT_SYMBOL(pci_mem_start); -#endif -extern int user_defined_memmap; -struct resource data_resource = { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -struct resource code_resource = { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource system_rom_resource = { - .name = "System ROM", - .start = 0xf0000, - .end = 0xfffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource extension_rom_resource = { - .name = "Extension ROM", - .start = 0xe0000, - .end = 0xeffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource adapter_rom_resources[] = { { - .name = "Adapter ROM", - .start = 0xc8000, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -} }; - -static struct resource video_rom_resource = { - .name = "Video ROM", - .start = 0xc0000, - .end = 0xc7fff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource video_ram_resource = { - .name = "Video RAM area", - .start = 0xa0000, - .end = 0xbffff, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource standard_io_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x001f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic1", - .start = 0x0020, - .end = 0x0021, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer0", - .start = 0x0040, - .end = 0x0043, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer1", - .start = 0x0050, - .end = 0x0053, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0060, - .end = 0x006f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma page reg", - .start = 0x0080, - .end = 0x008f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic2", - .start = 0x00a0, - .end = 0x00a1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "fpu", - .start = 0x00f0, - .end = 0x00ff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -} }; - -static int romsignature(const unsigned char *x) -{ - unsigned short sig; - int ret = 0; - if (probe_kernel_address((const unsigned short *)x, sig) == 0) - ret = (sig == 0xaa55); - return ret; -} - -static int __init romchecksum(unsigned char *rom, unsigned long length) -{ - unsigned char *p, sum = 0; - - for (p = rom; p < rom + length; p++) - sum += *p; - return sum == 0; -} - -static void __init probe_roms(void) -{ - unsigned long start, length, upper; - unsigned char *rom; - int i; - - /* video rom */ - upper = adapter_rom_resources[0].start; - for (start = video_rom_resource.start; start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - video_rom_resource.start = start; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* if checksum okay, trust length byte */ - if (length && romchecksum(rom, length)) - video_rom_resource.end = start + length - 1; - - request_resource(&iomem_resource, &video_rom_resource); - break; - } - - start = (video_rom_resource.end + 1 + 2047) & ~2047UL; - if (start < upper) - start = upper; - - /* system rom */ - request_resource(&iomem_resource, &system_rom_resource); - upper = system_rom_resource.start; - - /* check for extension rom (ignore length byte!) */ - rom = isa_bus_to_virt(extension_rom_resource.start); - if (romsignature(rom)) { - length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (romchecksum(rom, length)) { - request_resource(&iomem_resource, &extension_rom_resource); - upper = extension_rom_resource.start; - } - } - - /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !romchecksum(rom, length)) - continue; - - adapter_rom_resources[i].start = start; - adapter_rom_resources[i].end = start + length - 1; - request_resource(&iomem_resource, &adapter_rom_resources[i]); - - start = adapter_rom_resources[i++].end & ~2047UL; - } -} - -/* - * Request address space for all standard RAM and ROM resources - * and also for regions reported as reserved by the e820. - */ -static void __init -legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) -{ - int i; - - probe_roms(); - for (i = 0; i < e820.nr_map; i++) { - struct resource *res; -#ifndef CONFIG_RESOURCES_64BIT - if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) - continue; -#endif - res = kzalloc(sizeof(struct resource), GFP_ATOMIC); - switch (e820.map[i].type) { - case E820_RAM: res->name = "System RAM"; break; - case E820_ACPI: res->name = "ACPI Tables"; break; - case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; - default: res->name = "reserved"; - } - res->start = e820.map[i].addr; - res->end = res->start + e820.map[i].size - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - if (request_resource(&iomem_resource, res)) { - kfree(res); - continue; - } - if (e820.map[i].type == E820_RAM) { - /* - * We don't know which RAM region contains kernel data, - * so we try it repeatedly and let the resource manager - * test it. - */ - request_resource(res, code_resource); - request_resource(res, data_resource); -#ifdef CONFIG_KEXEC - request_resource(res, &crashk_res); -#endif - } - } -} - -/* - * Request address space for all standard resources - * - * This is called just before pcibios_init(), which is also a - * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). - */ -static int __init request_standard_resources(void) -{ - int i; - - printk("Setting up standard PCI resources\n"); - if (efi_enabled) - efi_initialize_iomem_resources(&code_resource, &data_resource); - else - legacy_init_iomem_resources(&code_resource, &data_resource); - - /* EFI systems may still have VGA */ - request_resource(&iomem_resource, &video_ram_resource); - - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) - request_resource(&ioport_resource, &standard_io_resources[i]); - return 0; -} - -subsys_initcall(request_standard_resources); - -void __init add_memory_region(unsigned long long start, - unsigned long long size, int type) -{ - int x; - - if (!efi_enabled) { - x = e820.nr_map; - - if (x == E820MAX) { - printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); - return; - } - - e820.map[x].addr = start; - e820.map[x].size = size; - e820.map[x].type = type; - e820.nr_map++; - } -} /* add_memory_region */ - -/* - * Sanitize the BIOS e820 map. - * - * Some e820 responses include overlapping entries. The following - * replaces the original e820 map with a new one, removing overlaps. - * - */ -int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) -{ - struct change_member *change_tmp; - unsigned long current_type, last_type; - unsigned long long last_addr; - int chgidx, still_changing; - int overlap_entries; - int new_bios_entry; - int old_nr, new_nr, chg_nr; - int i; - - /* - Visually we're performing the following (1,2,3,4 = memory types)... - - Sample memory map (w/overlaps): - ____22__________________ - ______________________4_ - ____1111________________ - _44_____________________ - 11111111________________ - ____________________33__ - ___________44___________ - __________33333_________ - ______________22________ - ___________________2222_ - _________111111111______ - _____________________11_ - _________________4______ - - Sanitized equivalent (no overlap): - 1_______________________ - _44_____________________ - ___1____________________ - ____22__________________ - ______11________________ - _________1______________ - __________3_____________ - ___________44___________ - _____________33_________ - _______________2________ - ________________1_______ - _________________4______ - ___________________2____ - ____________________33__ - ______________________4_ - */ - printk("sanitize start\n"); - /* if there's only one memory region, don't bother */ - if (*pnr_map < 2) { - printk("sanitize bail 0\n"); - return -1; - } - - old_nr = *pnr_map; - - /* bail out if we find any unreasonable addresses in bios map */ - for (i=0; iaddr = biosmap[i].addr; - change_point[chgidx++]->pbios = &biosmap[i]; - change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; - change_point[chgidx++]->pbios = &biosmap[i]; - } - } - chg_nr = chgidx; /* true number of change-points */ - - /* sort change-point list by memory addresses (low -> high) */ - still_changing = 1; - while (still_changing) { - still_changing = 0; - for (i=1; i < chg_nr; i++) { - /* if > , swap */ - /* or, if current= & last=, swap */ - if ((change_point[i]->addr < change_point[i-1]->addr) || - ((change_point[i]->addr == change_point[i-1]->addr) && - (change_point[i]->addr == change_point[i]->pbios->addr) && - (change_point[i-1]->addr != change_point[i-1]->pbios->addr)) - ) - { - change_tmp = change_point[i]; - change_point[i] = change_point[i-1]; - change_point[i-1] = change_tmp; - still_changing=1; - } - } - } - - /* create a new bios memory map, removing overlaps */ - overlap_entries=0; /* number of entries in the overlap table */ - new_bios_entry=0; /* index for creating new bios map entries */ - last_type = 0; /* start with undefined memory type */ - last_addr = 0; /* start with 0 as last starting address */ - /* loop through change-points, determining affect on the new bios map */ - for (chgidx=0; chgidx < chg_nr; chgidx++) - { - /* keep track of all overlapping bios entries */ - if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) - { - /* add map entry to overlap list (> 1 entry implies an overlap) */ - overlap_list[overlap_entries++]=change_point[chgidx]->pbios; - } - else - { - /* remove entry from list (order independent, so swap with last) */ - for (i=0; ipbios) - overlap_list[i] = overlap_list[overlap_entries-1]; - } - overlap_entries--; - } - /* if there are overlapping entries, decide which "type" to use */ - /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ - current_type = 0; - for (i=0; itype > current_type) - current_type = overlap_list[i]->type; - /* continue building up new bios map based on this information */ - if (current_type != last_type) { - if (last_type != 0) { - new_bios[new_bios_entry].size = - change_point[chgidx]->addr - last_addr; - /* move forward only if the new size was non-zero */ - if (new_bios[new_bios_entry].size != 0) - if (++new_bios_entry >= E820MAX) - break; /* no more space left for new bios entries */ - } - if (current_type != 0) { - new_bios[new_bios_entry].addr = change_point[chgidx]->addr; - new_bios[new_bios_entry].type = current_type; - last_addr=change_point[chgidx]->addr; - } - last_type = current_type; - } - } - new_nr = new_bios_entry; /* retain count for new bios entries */ - - /* copy new bios mapping into original location */ - memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); - *pnr_map = new_nr; - - printk("sanitize end\n"); - return 0; -} - -/* - * Copy the BIOS e820 map into a safe place. - * - * Sanity-check it while we're at it.. - * - * If we're lucky and live on a modern system, the setup code - * will have given us a memory map that we can use to properly - * set up memory. If we aren't, we'll fake a memory map. - * - * We check to see that the memory map contains at least 2 elements - * before we'll use it, because the detection code in setup.S may - * not be perfect and most every PC known to man has two memory - * regions: one from 0 to 640k, and one from 1mb up. (The IBM - * thinkpad 560x, for example, does not cooperate with the memory - * detection code.) - */ -int __init copy_e820_map(struct e820entry * biosmap, int nr_map) -{ - /* Only one memory region (or negative)? Ignore it */ - if (nr_map < 2) - return -1; - - do { - unsigned long long start = biosmap->addr; - unsigned long long size = biosmap->size; - unsigned long long end = start + size; - unsigned long type = biosmap->type; - printk("copy_e820_map() start: %016Lx size: %016Lx end: %016Lx type: %ld\n", start, size, end, type); - - /* Overflow in 64 bits? Ignore the memory map. */ - if (start > end) - return -1; - - /* - * Some BIOSes claim RAM in the 640k - 1M region. - * Not right. Fix it up. - */ - if (type == E820_RAM) { - printk("copy_e820_map() type is E820_RAM\n"); - if (start < 0x100000ULL && end > 0xA0000ULL) { - printk("copy_e820_map() lies in range...\n"); - if (start < 0xA0000ULL) { - printk("copy_e820_map() start < 0xA0000ULL\n"); - add_memory_region(start, 0xA0000ULL-start, type); - } - if (end <= 0x100000ULL) { - printk("copy_e820_map() end <= 0x100000ULL\n"); - continue; - } - start = 0x100000ULL; - size = end - start; - } - } - add_memory_region(start, size, type); - } while (biosmap++,--nr_map); - return 0; -} - -/* - * Callback for efi_memory_walk. - */ -static int __init -efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) -{ - unsigned long *max_pfn = arg, pfn; - - if (start < end) { - pfn = PFN_UP(end -1); - if (pfn > *max_pfn) - *max_pfn = pfn; - } - return 0; -} - -static int __init -efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) -{ - memory_present(0, PFN_UP(start), PFN_DOWN(end)); - return 0; -} - -/* - * Find the highest page frame number we have available - */ -void __init find_max_pfn(void) -{ - int i; - - max_pfn = 0; - if (efi_enabled) { - efi_memmap_walk(efi_find_max_pfn, &max_pfn); - efi_memmap_walk(efi_memory_present_wrapper, NULL); - return; - } - - for (i = 0; i < e820.nr_map; i++) { - unsigned long start, end; - /* RAM? */ - if (e820.map[i].type != E820_RAM) - continue; - start = PFN_UP(e820.map[i].addr); - end = PFN_DOWN(e820.map[i].addr + e820.map[i].size); - if (start >= end) - continue; - if (end > max_pfn) - max_pfn = end; - memory_present(0, start, end); - } -} - -/* - * Free all available memory for boot time allocation. Used - * as a callback function by efi_memory_walk() - */ - -static int __init -free_available_memory(unsigned long start, unsigned long end, void *arg) -{ - /* check max_low_pfn */ - if (start >= (max_low_pfn << PAGE_SHIFT)) - return 0; - if (end >= (max_low_pfn << PAGE_SHIFT)) - end = max_low_pfn << PAGE_SHIFT; - if (start < end) - free_bootmem(start, end - start); - - return 0; -} -/* - * Register fully available low RAM pages with the bootmem allocator. - */ -void __init register_bootmem_low_pages(unsigned long max_low_pfn) -{ - int i; - - if (efi_enabled) { - efi_memmap_walk(free_available_memory, NULL); - return; - } - for (i = 0; i < e820.nr_map; i++) { - unsigned long curr_pfn, last_pfn, size; - /* - * Reserve usable low memory - */ - if (e820.map[i].type != E820_RAM) - continue; - /* - * We are rounding up the start address of usable memory: - */ - curr_pfn = PFN_UP(e820.map[i].addr); - if (curr_pfn >= max_low_pfn) - continue; - /* - * ... and at the end of the usable range downwards: - */ - last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); - - if (last_pfn > max_low_pfn) - last_pfn = max_low_pfn; - - /* - * .. finally, did all the rounding and playing - * around just make the area go away? - */ - if (last_pfn <= curr_pfn) - continue; - - size = last_pfn - curr_pfn; - free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); - } -} - -void __init register_memory(void) -{ - unsigned long gapstart, gapsize, round; - unsigned long long last; - int i; - - /* - * Search for the bigest gap in the low 32 bits of the e820 - * memory space. - */ - last = 0x100000000ull; - gapstart = 0x10000000; - gapsize = 0x400000; - i = e820.nr_map; - while (--i >= 0) { - unsigned long long start = e820.map[i].addr; - unsigned long long end = start + e820.map[i].size; - - /* - * Since "last" is at most 4GB, we know we'll - * fit in 32 bits if this condition is true - */ - if (last > end) { - unsigned long gap = last - end; - - if (gap > gapsize) { - gapsize = gap; - gapstart = end; - } - } - if (start < last) - last = start; - } - - /* - * See how much we want to round up: start off with - * rounding to the next 1MB area. - */ - round = 0x100000; - while ((gapsize >> 4) > round) - round += round; - /* Fun with two's complement */ - pci_mem_start = (gapstart + round) & -round; - - printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", - pci_mem_start, gapstart, gapsize); -} - -void __init print_memory_map(char *who) -{ - int i; - - for (i = 0; i < e820.nr_map; i++) { - printk(" %s: %016Lx - %016Lx ", who, - e820.map[i].addr, - e820.map[i].addr + e820.map[i].size); - switch (e820.map[i].type) { - case E820_RAM: printk("(usable)\n"); - break; - case E820_RESERVED: - printk("(reserved)\n"); - break; - case E820_ACPI: - printk("(ACPI data)\n"); - break; - case E820_NVS: - printk("(ACPI NVS)\n"); - break; - default: printk("type %lu\n", e820.map[i].type); - break; - } - } -} - -static __init __always_inline void efi_limit_regions(unsigned long long size) -{ - unsigned long long current_addr = 0; - efi_memory_desc_t *md, *next_md; - void *p, *p1; - int i, j; - - j = 0; - p1 = memmap.map; - for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) { - md = p; - next_md = p1; - current_addr = md->phys_addr + - PFN_PHYS(md->num_pages); - if (is_available_memory(md)) { - if (md->phys_addr >= size) continue; - memcpy(next_md, md, memmap.desc_size); - if (current_addr >= size) { - next_md->num_pages -= - PFN_UP(current_addr-size); - } - p1 += memmap.desc_size; - next_md = p1; - j++; - } else if ((md->attribute & EFI_MEMORY_RUNTIME) == - EFI_MEMORY_RUNTIME) { - /* In order to make runtime services - * available we have to include runtime - * memory regions in memory map */ - memcpy(next_md, md, memmap.desc_size); - p1 += memmap.desc_size; - next_md = p1; - j++; - } - } - memmap.nr_map = j; - memmap.map_end = memmap.map + - (memmap.nr_map * memmap.desc_size); -} - -void __init limit_regions(unsigned long long size) -{ - unsigned long long current_addr; - int i; - - print_memory_map("limit_regions start"); - if (efi_enabled) { - efi_limit_regions(size); - return; - } - for (i = 0; i < e820.nr_map; i++) { - current_addr = e820.map[i].addr + e820.map[i].size; - if (current_addr < size) - continue; - - if (e820.map[i].type != E820_RAM) - continue; - - if (e820.map[i].addr >= size) { - /* - * This region starts past the end of the - * requested size, skip it completely. - */ - e820.nr_map = i; - } else { - e820.nr_map = i + 1; - e820.map[i].size -= current_addr - size; - } - print_memory_map("limit_regions endfor"); - return; - } - print_memory_map("limit_regions endfunc"); -} - - /* - * This function checks if the entire range is mapped with type. - * - * Note: this function only works correct if the e820 table is sorted and - * not-overlapping, which is the case - */ -int __init -e820_all_mapped(unsigned long s, unsigned long e, unsigned type) -{ - u64 start = s; - u64 end = e; - int i; - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - if (type && ei->type != type) - continue; - /* is the region (part) in overlap with the current region ?*/ - if (ei->addr >= end || ei->addr + ei->size <= start) - continue; - /* if the region is at the beginning of we move - * start to the end of the region since it's ok until there - */ - if (ei->addr <= start) - start = ei->addr + ei->size; - /* if start is now at or beyond end, we're done, full - * coverage */ - if (start >= end) - return 1; /* we're done */ - } - return 0; -} - -static int __init parse_memmap(char *arg) -{ - if (!arg) - return -EINVAL; - - if (strcmp(arg, "exactmap") == 0) { -#ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we - * still need to know the real mem - * size before original memory map is - * reset. - */ - find_max_pfn(); - saved_max_pfn = max_pfn; -#endif - e820.nr_map = 0; - user_defined_memmap = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. - */ - unsigned long long start_at, mem_size; - - mem_size = memparse(arg, &arg); - if (*arg == '@') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RAM); - } else if (*arg == '#') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_ACPI); - } else if (*arg == '$') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RESERVED); - } else { - limit_regions(mem_size); - user_defined_memmap = 1; - } - } - return 0; -} -early_param("memmap", parse_memmap); diff --git a/trunk/arch/i386/kernel/efi.c b/trunk/arch/i386/kernel/efi.c index b92c7f0a358a..8b40648d0ef0 100644 --- a/trunk/arch/i386/kernel/efi.c +++ b/trunk/arch/i386/kernel/efi.c @@ -194,24 +194,17 @@ inline int efi_set_rtc_mmss(unsigned long nowtime) return 0; } /* - * This is used during kernel init before runtime - * services have been remapped and also during suspend, therefore, - * we'll need to call both in physical and virtual modes. + * This should only be used during kernel init and before runtime + * services have been remapped, therefore, we'll need to call in physical + * mode. Note, this call isn't used later, so mark it __init. */ -inline unsigned long efi_get_time(void) +inline unsigned long __init efi_get_time(void) { efi_status_t status; efi_time_t eft; efi_time_cap_t cap; - if (efi.get_time) { - /* if we are in virtual mode use remapped function */ - status = efi.get_time(&eft, &cap); - } else { - /* we are in physical mode */ - status = phys_efi_get_time(&eft, &cap); - } - + status = phys_efi_get_time(&eft, &cap); if (status != EFI_SUCCESS) printk("Oops: efitime: can't read time status: 0x%lx\n",status); diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index de34b7fed3c1..5a63d6fdb70e 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -30,13 +30,12 @@ * 18(%esp) - %eax * 1C(%esp) - %ds * 20(%esp) - %es - * 24(%esp) - %gs - * 28(%esp) - orig_eax - * 2C(%esp) - %eip - * 30(%esp) - %cs - * 34(%esp) - %eflags - * 38(%esp) - %oldesp - * 3C(%esp) - %oldss + * 24(%esp) - orig_eax + * 28(%esp) - %eip + * 2C(%esp) - %cs + * 30(%esp) - %eflags + * 34(%esp) - %oldesp + * 38(%esp) - %oldss * * "current" is in register %ebx during any slow entries. */ @@ -49,25 +48,27 @@ #include #include #include -#include #include #include "irq_vectors.h" -/* - * We use macros for low-level operations which need to be overridden - * for paravirtualization. The following will never clobber any registers: - * INTERRUPT_RETURN (aka. "iret") - * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") - * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). - * - * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must - * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). - * Allowing a register to be clobbered can shrink the paravirt replacement - * enough to patch inline, increasing performance. - */ - #define nr_syscalls ((syscall_table_size)/4) +EBX = 0x00 +ECX = 0x04 +EDX = 0x08 +ESI = 0x0C +EDI = 0x10 +EBP = 0x14 +EAX = 0x18 +DS = 0x1C +ES = 0x20 +ORIG_EAX = 0x24 +EIP = 0x28 +CS = 0x2C +EFLAGS = 0x30 +OLDESP = 0x34 +OLDSS = 0x38 + CF_MASK = 0x00000001 TF_MASK = 0x00000100 IF_MASK = 0x00000200 @@ -75,16 +76,23 @@ DF_MASK = 0x00000400 NT_MASK = 0x00004000 VM_MASK = 0x00020000 +/* These are replaces for paravirtualization */ +#define DISABLE_INTERRUPTS cli +#define ENABLE_INTERRUPTS sti +#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit +#define INTERRUPT_RETURN iret +#define GET_CR0_INTO_EAX movl %cr0, %eax + #ifdef CONFIG_PREEMPT -#define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF +#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF #else -#define preempt_stop(clobbers) +#define preempt_stop #define resume_kernel restore_nocheck #endif .macro TRACE_IRQS_IRET #ifdef CONFIG_TRACE_IRQFLAGS - testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off? + testl $IF_MASK,EFLAGS(%esp) # interrupts off? jz 1f TRACE_IRQS_ON 1: @@ -99,9 +107,6 @@ VM_MASK = 0x00020000 #define SAVE_ALL \ cld; \ - pushl %gs; \ - CFI_ADJUST_CFA_OFFSET 4;\ - /*CFI_REL_OFFSET gs, 0;*/\ pushl %es; \ CFI_ADJUST_CFA_OFFSET 4;\ /*CFI_REL_OFFSET es, 0;*/\ @@ -131,9 +136,7 @@ VM_MASK = 0x00020000 CFI_REL_OFFSET ebx, 0;\ movl $(__USER_DS), %edx; \ movl %edx, %ds; \ - movl %edx, %es; \ - movl $(__KERNEL_PDA), %edx; \ - movl %edx, %gs + movl %edx, %es; #define RESTORE_INT_REGS \ popl %ebx; \ @@ -166,22 +169,17 @@ VM_MASK = 0x00020000 2: popl %es; \ CFI_ADJUST_CFA_OFFSET -4;\ /*CFI_RESTORE es;*/\ -3: popl %gs; \ - CFI_ADJUST_CFA_OFFSET -4;\ - /*CFI_RESTORE gs;*/\ -.pushsection .fixup,"ax"; \ -4: movl $0,(%esp); \ +.section .fixup,"ax"; \ +3: movl $0,(%esp); \ jmp 1b; \ -5: movl $0,(%esp); \ +4: movl $0,(%esp); \ jmp 2b; \ -6: movl $0,(%esp); \ - jmp 3b; \ +.previous; \ .section __ex_table,"a";\ .align 4; \ - .long 1b,4b; \ - .long 2b,5b; \ - .long 3b,6b; \ -.popsection + .long 1b,3b; \ + .long 2b,4b; \ +.previous #define RING0_INT_FRAME \ CFI_STARTPROC simple;\ @@ -200,18 +198,18 @@ VM_MASK = 0x00020000 #define RING0_PTREGS_FRAME \ CFI_STARTPROC simple;\ CFI_SIGNAL_FRAME;\ - CFI_DEF_CFA esp, PT_OLDESP-PT_EBX;\ - /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/\ - CFI_OFFSET eip, PT_EIP-PT_OLDESP;\ - /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/\ - /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/\ - CFI_OFFSET eax, PT_EAX-PT_OLDESP;\ - CFI_OFFSET ebp, PT_EBP-PT_OLDESP;\ - CFI_OFFSET edi, PT_EDI-PT_OLDESP;\ - CFI_OFFSET esi, PT_ESI-PT_OLDESP;\ - CFI_OFFSET edx, PT_EDX-PT_OLDESP;\ - CFI_OFFSET ecx, PT_ECX-PT_OLDESP;\ - CFI_OFFSET ebx, PT_EBX-PT_OLDESP + CFI_DEF_CFA esp, OLDESP-EBX;\ + /*CFI_OFFSET cs, CS-OLDESP;*/\ + CFI_OFFSET eip, EIP-OLDESP;\ + /*CFI_OFFSET es, ES-OLDESP;*/\ + /*CFI_OFFSET ds, DS-OLDESP;*/\ + CFI_OFFSET eax, EAX-OLDESP;\ + CFI_OFFSET ebp, EBP-OLDESP;\ + CFI_OFFSET edi, EDI-OLDESP;\ + CFI_OFFSET esi, ESI-OLDESP;\ + CFI_OFFSET edx, EDX-OLDESP;\ + CFI_OFFSET ecx, ECX-OLDESP;\ + CFI_OFFSET ebx, EBX-OLDESP ENTRY(ret_from_fork) CFI_STARTPROC @@ -239,18 +237,17 @@ ENTRY(ret_from_fork) ALIGN RING0_PTREGS_FRAME ret_from_exception: - preempt_stop(CLBR_ANY) + preempt_stop ret_from_intr: GET_THREAD_INFO(%ebp) check_userspace: - movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS - movb PT_CS(%esp), %al + movl EFLAGS(%esp), %eax # mix EFLAGS and CS + movb CS(%esp), %al andl $(VM_MASK | SEGMENT_RPL_MASK), %eax cmpl $USER_RPL, %eax jb resume_kernel # not returning to v8086 or userspace - ENTRY(resume_userspace) - DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt + DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx @@ -261,14 +258,14 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) - DISABLE_INTERRUPTS(CLBR_ANY) + DISABLE_INTERRUPTS cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched: movl TI_flags(%ebp), %ecx # need_resched set ? testb $_TIF_NEED_RESCHED, %cl jz restore_all - testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off (exception path) ? + testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ? jz restore_all call preempt_schedule_irq jmp need_resched @@ -290,7 +287,7 @@ sysenter_past_esp: * No need to follow this irqs on/off section: the syscall * disabled irqs and here we enable it straight after entry: */ - ENABLE_INTERRUPTS(CLBR_NONE) + ENABLE_INTERRUPTS pushl $(__USER_DS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ss, 0*/ @@ -334,27 +331,20 @@ sysenter_past_esp: cmpl $(nr_syscalls), %eax jae syscall_badsys call *sys_call_table(,%eax,4) - movl %eax,PT_EAX(%esp) - DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX) + movl %eax,EAX(%esp) + DISABLE_INTERRUPTS TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx jne syscall_exit_work /* if something modifies registers it must also disable sysexit */ - movl PT_EIP(%esp), %edx - movl PT_OLDESP(%esp), %ecx + movl EIP(%esp), %edx + movl OLDESP(%esp), %ecx xorl %ebp,%ebp TRACE_IRQS_ON -1: mov PT_GS(%esp), %gs ENABLE_INTERRUPTS_SYSEXIT CFI_ENDPROC -.pushsection .fixup,"ax" -2: movl $0,PT_GS(%esp) - jmp 1b -.section __ex_table,"a" - .align 4 - .long 1b,2b -.popsection + # system call handler stub ENTRY(system_call) @@ -363,7 +353,7 @@ ENTRY(system_call) CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) - testl $TF_MASK,PT_EFLAGS(%esp) + testl $TF_MASK,EFLAGS(%esp) jz no_singlestep orl $_TIF_SINGLESTEP,TI_flags(%ebp) no_singlestep: @@ -375,9 +365,9 @@ no_singlestep: jae syscall_badsys syscall_call: call *sys_call_table(,%eax,4) - movl %eax,PT_EAX(%esp) # store the return value + movl %eax,EAX(%esp) # store the return value syscall_exit: - DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt + DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -386,12 +376,12 @@ syscall_exit: jne syscall_exit_work restore_all: - movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS - # Warning: PT_OLDSS(%esp) contains the wrong/random values if we + movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS + # Warning: OLDSS(%esp) contains the wrong/random values if we # are returning to the kernel. # See comments in process.c:copy_thread() for details. - movb PT_OLDSS(%esp), %ah - movb PT_CS(%esp), %al + movb OLDSS(%esp), %ah + movb CS(%esp), %al andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax CFI_REMEMBER_STATE @@ -400,13 +390,13 @@ restore_nocheck: TRACE_IRQS_IRET restore_nocheck_notrace: RESTORE_REGS - addl $4, %esp # skip orig_eax/error_code + addl $4, %esp CFI_ADJUST_CFA_OFFSET -4 1: INTERRUPT_RETURN .section .fixup,"ax" iret_exc: TRACE_IRQS_ON - ENABLE_INTERRUPTS(CLBR_NONE) + ENABLE_INTERRUPTS pushl $0 # no error code pushl $do_iret_error jmp error_code @@ -418,42 +408,33 @@ iret_exc: CFI_RESTORE_STATE ldt_ss: - larl PT_OLDSS(%esp), %eax + larl OLDSS(%esp), %eax jnz restore_nocheck testl $0x00400000, %eax # returning to 32bit stack? jnz restore_nocheck # allright, normal return - -#ifdef CONFIG_PARAVIRT - /* - * The kernel can't run on a non-flat stack if paravirt mode - * is active. Rather than try to fixup the high bits of - * ESP, bypass this code entirely. This may break DOSemu - * and/or Wine support in a paravirt VM, although the option - * is still available to implement the setting of the high - * 16-bits in the INTERRUPT_RETURN paravirt-op. - */ - cmpl $0, paravirt_ops+PARAVIRT_enabled - jne restore_nocheck -#endif - /* If returning to userspace with 16bit stack, * try to fix the higher word of ESP, as the CPU * won't restore it. * This is an "official" bug of all the x86-compatible * CPUs, which we can try to work around to make * dosemu and wine happy. */ - movl PT_OLDESP(%esp), %eax - movl %esp, %edx - call patch_espfix_desc - pushl $__ESPFIX_SS - CFI_ADJUST_CFA_OFFSET 4 - pushl %eax - CFI_ADJUST_CFA_OFFSET 4 - DISABLE_INTERRUPTS(CLBR_EAX) + subl $8, %esp # reserve space for switch16 pointer + CFI_ADJUST_CFA_OFFSET 8 + DISABLE_INTERRUPTS TRACE_IRQS_OFF - lss (%esp), %esp - CFI_ADJUST_CFA_OFFSET -8 - jmp restore_nocheck + movl %esp, %eax + /* Set up the 16bit stack frame with switch32 pointer on top, + * and a switch16 pointer on top of the current frame. */ + call setup_x86_bogus_stack + CFI_ADJUST_CFA_OFFSET -8 # frame has moved + TRACE_IRQS_IRET + RESTORE_REGS + lss 20+4(%esp), %esp # switch to 16bit stack +1: INTERRUPT_RETURN +.section __ex_table,"a" + .align 4 + .long 1b,iret_exc +.previous CFI_ENDPROC # perform work that needs to be done immediately before resumption @@ -464,7 +445,7 @@ work_pending: jz work_notifysig work_resched: call schedule - DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt + DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -477,8 +458,7 @@ work_resched: work_notifysig: # deal with pending signals and # notify-resume requests -#ifdef CONFIG_VM86 - testl $VM_MASK, PT_EFLAGS(%esp) + testl $VM_MASK, EFLAGS(%esp) movl %esp, %eax jne work_notifysig_v86 # returning to kernel-space or # vm86-space @@ -488,30 +468,29 @@ work_notifysig: # deal with pending signals and ALIGN work_notifysig_v86: +#ifdef CONFIG_VM86 pushl %ecx # save ti_flags for do_notify_resume CFI_ADJUST_CFA_OFFSET 4 call save_v86_state # %eax contains pt_regs pointer popl %ecx CFI_ADJUST_CFA_OFFSET -4 movl %eax, %esp -#else - movl %esp, %eax -#endif xorl %edx, %edx call do_notify_resume jmp resume_userspace_sig +#endif # perform syscall exit tracing ALIGN syscall_trace_entry: - movl $-ENOSYS,PT_EAX(%esp) + movl $-ENOSYS,EAX(%esp) movl %esp, %eax xorl %edx,%edx call do_syscall_trace cmpl $0, %eax jne resume_userspace # ret != 0 -> running under PTRACE_SYSEMU, # so must skip actual syscall - movl PT_ORIG_EAX(%esp), %eax + movl ORIG_EAX(%esp), %eax cmpl $(nr_syscalls), %eax jnae syscall_call jmp syscall_exit @@ -522,7 +501,7 @@ syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending TRACE_IRQS_ON - ENABLE_INTERRUPTS(CLBR_ANY) # could let do_syscall_trace() call + ENABLE_INTERRUPTS # could let do_syscall_trace() call # schedule() instead movl %esp, %eax movl $1, %edx @@ -536,38 +515,39 @@ syscall_fault: CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) - movl $-EFAULT,PT_EAX(%esp) + movl $-EFAULT,EAX(%esp) jmp resume_userspace syscall_badsys: - movl $-ENOSYS,PT_EAX(%esp) + movl $-ENOSYS,EAX(%esp) jmp resume_userspace CFI_ENDPROC #define FIXUP_ESPFIX_STACK \ - /* since we are on a wrong stack, we cant make it a C code :( */ \ - movl %gs:PDA_cpu, %ebx; \ - PER_CPU(cpu_gdt_descr, %ebx); \ - movl GDS_address(%ebx), %ebx; \ - GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ - addl %esp, %eax; \ - pushl $__KERNEL_DS; \ - CFI_ADJUST_CFA_OFFSET 4; \ + movl %esp, %eax; \ + /* switch to 32bit stack using the pointer on top of 16bit stack */ \ + lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \ + /* copy data from 16bit stack to 32bit stack */ \ + call fixup_x86_bogus_stack; \ + /* put ESP to the proper location */ \ + movl %eax, %esp; +#define UNWIND_ESPFIX_STACK \ pushl %eax; \ CFI_ADJUST_CFA_OFFSET 4; \ - lss (%esp), %esp; \ - CFI_ADJUST_CFA_OFFSET -8; -#define UNWIND_ESPFIX_STACK \ movl %ss, %eax; \ - /* see if on espfix stack */ \ + /* see if on 16bit stack */ \ cmpw $__ESPFIX_SS, %ax; \ - jne 27f; \ - movl $__KERNEL_DS, %eax; \ + je 28f; \ +27: popl %eax; \ + CFI_ADJUST_CFA_OFFSET -4; \ +.section .fixup,"ax"; \ +28: movl $__KERNEL_DS, %eax; \ movl %eax, %ds; \ movl %eax, %es; \ - /* switch to normal stack */ \ + /* switch to 32bit stack */ \ FIXUP_ESPFIX_STACK; \ -27:; + jmp 27b; \ +.previous /* * Build the entry stubs and pointer table with @@ -628,16 +608,13 @@ KPROBE_ENTRY(page_fault) CFI_ADJUST_CFA_OFFSET 4 ALIGN error_code: - /* the function address is in %gs's slot on the stack */ - pushl %es - CFI_ADJUST_CFA_OFFSET 4 - /*CFI_REL_OFFSET es, 0*/ pushl %ds CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ds, 0*/ pushl %eax CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eax, 0 + xorl %eax, %eax pushl %ebp CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET ebp, 0 @@ -650,6 +627,7 @@ error_code: pushl %edx CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET edx, 0 + decl %eax # eax = -1 pushl %ecx CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET ecx, 0 @@ -657,20 +635,18 @@ error_code: CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET ebx, 0 cld - pushl %gs + pushl %es CFI_ADJUST_CFA_OFFSET 4 - /*CFI_REL_OFFSET gs, 0*/ - movl $(__KERNEL_PDA), %ecx - movl %ecx, %gs + /*CFI_REL_OFFSET es, 0*/ UNWIND_ESPFIX_STACK popl %ecx CFI_ADJUST_CFA_OFFSET -4 /*CFI_REGISTER es, ecx*/ - movl PT_GS(%esp), %edi # get the function address - movl PT_ORIG_EAX(%esp), %edx # get the error code - movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart - mov %ecx, PT_GS(%esp) - /*CFI_REL_OFFSET gs, ES*/ + movl ES(%esp), %edi # get the function address + movl ORIG_EAX(%esp), %edx # get the error code + movl %eax, ORIG_EAX(%esp) + movl %ecx, ES(%esp) + /*CFI_REL_OFFSET es, ES*/ movl $(__USER_DS), %ecx movl %ecx, %ds movl %ecx, %es @@ -706,7 +682,7 @@ ENTRY(device_not_available) GET_CR0_INTO_EAX testl $0x4, %eax # EM (math emulation bit) jne device_not_available_emulate - preempt_stop(CLBR_ANY) + preempt_stop call math_state_restore jmp ret_from_exception device_not_available_emulate: @@ -778,7 +754,7 @@ KPROBE_ENTRY(nmi) cmpw $__ESPFIX_SS, %ax popl %eax CFI_ADJUST_CFA_OFFSET -4 - je nmi_espfix_stack + je nmi_16bit_stack cmpl $sysenter_entry,(%esp) je nmi_stack_fixup pushl %eax @@ -821,7 +797,7 @@ nmi_debug_stack_check: FIX_STACK(24,nmi_stack_correct, 1) jmp nmi_stack_correct -nmi_espfix_stack: +nmi_16bit_stack: /* We have a RING0_INT_FRAME here. * * create the pointer to lss back @@ -830,6 +806,7 @@ nmi_espfix_stack: CFI_ADJUST_CFA_OFFSET 4 pushl %esp CFI_ADJUST_CFA_OFFSET 4 + movzwl %sp, %esp addw $4, (%esp) /* copy the iret frame of 12 bytes */ .rept 3 @@ -840,11 +817,11 @@ nmi_espfix_stack: CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL FIXUP_ESPFIX_STACK # %eax == %esp + CFI_ADJUST_CFA_OFFSET -20 # the frame has now moved xorl %edx,%edx # zero error code call do_nmi RESTORE_REGS - lss 12+4(%esp), %esp # back to espfix stack - CFI_ADJUST_CFA_OFFSET -24 + lss 12+4(%esp), %esp # back to 16bit stack 1: INTERRUPT_RETURN CFI_ENDPROC .section __ex_table,"a" @@ -853,19 +830,6 @@ nmi_espfix_stack: .previous KPROBE_END(nmi) -#ifdef CONFIG_PARAVIRT -ENTRY(native_iret) -1: iret -.section __ex_table,"a" - .align 4 - .long 1b,iret_exc -.previous - -ENTRY(native_irq_enable_sysexit) - sti - sysexit -#endif - KPROBE_ENTRY(int3) RING0_INT_FRAME pushl $-1 # mark this as an int @@ -985,27 +949,26 @@ ENTRY(arch_unwind_init_running) movl 4(%esp), %edx movl (%esp), %ecx leal 4(%esp), %eax - movl %ebx, PT_EBX(%edx) + movl %ebx, EBX(%edx) xorl %ebx, %ebx - movl %ebx, PT_ECX(%edx) - movl %ebx, PT_EDX(%edx) - movl %esi, PT_ESI(%edx) - movl %edi, PT_EDI(%edx) - movl %ebp, PT_EBP(%edx) - movl %ebx, PT_EAX(%edx) - movl $__USER_DS, PT_DS(%edx) - movl $__USER_DS, PT_ES(%edx) - movl $0, PT_GS(%edx) - movl %ebx, PT_ORIG_EAX(%edx) - movl %ecx, PT_EIP(%edx) + movl %ebx, ECX(%edx) + movl %ebx, EDX(%edx) + movl %esi, ESI(%edx) + movl %edi, EDI(%edx) + movl %ebp, EBP(%edx) + movl %ebx, EAX(%edx) + movl $__USER_DS, DS(%edx) + movl $__USER_DS, ES(%edx) + movl %ebx, ORIG_EAX(%edx) + movl %ecx, EIP(%edx) movl 12(%esp), %ecx - movl $__KERNEL_CS, PT_CS(%edx) - movl %ebx, PT_EFLAGS(%edx) - movl %eax, PT_OLDESP(%edx) + movl $__KERNEL_CS, CS(%edx) + movl %ebx, EFLAGS(%edx) + movl %eax, OLDESP(%edx) movl 8(%esp), %eax movl %ecx, 8(%esp) - movl PT_EBX(%edx), %ebx - movl $__KERNEL_DS, PT_OLDSS(%edx) + movl EBX(%edx), %ebx + movl $__KERNEL_DS, OLDSS(%edx) jmpl *%eax CFI_ENDPROC ENDPROC(arch_unwind_init_running) diff --git a/trunk/arch/i386/kernel/head.S b/trunk/arch/i386/kernel/head.S index edef5084ce17..ca31f18d277c 100644 --- a/trunk/arch/i386/kernel/head.S +++ b/trunk/arch/i386/kernel/head.S @@ -55,12 +55,6 @@ */ ENTRY(startup_32) -#ifdef CONFIG_PARAVIRT - movl %cs, %eax - testl $0x3, %eax - jnz startup_paravirt -#endif - /* * Set segments to known values. */ @@ -308,7 +302,6 @@ is386: movl $2,%ecx # set MP movl %eax,%cr0 call check_x87 - call setup_pda lgdt cpu_gdt_descr lidt idt_descr ljmp $(__KERNEL_CS),$1f @@ -319,13 +312,10 @@ is386: movl $2,%ecx # set MP movl %eax,%ds movl %eax,%es - xorl %eax,%eax # Clear FS and LDT + xorl %eax,%eax # Clear FS/GS and LDT movl %eax,%fs + movl %eax,%gs lldt %ax - - movl $(__KERNEL_PDA),%eax - mov %eax,%gs - cld # gcc2 wants the direction flag cleared at all times pushl $0 # fake return address for unwinder #ifdef CONFIG_SMP @@ -355,23 +345,6 @@ check_x87: .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ ret -/* - * Point the GDT at this CPU's PDA. On boot this will be - * cpu_gdt_table and boot_pda; for secondary CPUs, these will be - * that CPU's GDT and PDA. - */ -setup_pda: - /* get the PDA pointer */ - movl start_pda, %eax - - /* slot the PDA address into the GDT */ - mov cpu_gdt_descr+2, %ecx - mov %ax, (__KERNEL_PDA+0+2)(%ecx) /* base & 0x0000ffff */ - shr $16, %eax - mov %al, (__KERNEL_PDA+4+0)(%ecx) /* base & 0x00ff0000 */ - mov %ah, (__KERNEL_PDA+4+3)(%ecx) /* base & 0xff000000 */ - ret - /* * setup_idt * @@ -492,33 +465,6 @@ ignore_int: #endif iret -#ifdef CONFIG_PARAVIRT -startup_paravirt: - cld - movl $(init_thread_union+THREAD_SIZE),%esp - - /* We take pains to preserve all the regs. */ - pushl %edx - pushl %ecx - pushl %eax - - /* paravirt.o is last in link, and that probe fn never returns */ - pushl $__start_paravirtprobe -1: - movl 0(%esp), %eax - pushl (%eax) - movl 8(%esp), %eax - call *(%esp) - popl %eax - - movl 4(%esp), %eax - movl 8(%esp), %ecx - movl 12(%esp), %edx - - addl $4, (%esp) - jmp 1b -#endif - /* * Real beginning of normal "text" segment */ @@ -538,8 +484,6 @@ ENTRY(empty_zero_page) * This starts the data section. */ .data -ENTRY(start_pda) - .long boot_pda ENTRY(stack_start) .long init_thread_union+THREAD_SIZE @@ -581,7 +525,7 @@ idt_descr: # boot GDT descriptor (later on used by CPU#0): .word 0 # 32 bit align gdt_desc.address -ENTRY(cpu_gdt_descr) +cpu_gdt_descr: .word GDT_ENTRIES*8-1 .long cpu_gdt_table @@ -640,8 +584,8 @@ ENTRY(cpu_gdt_table) .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */ .quad 0x004092000000ffff /* 0xc8 APM DS data */ - .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ - .quad 0x00cf92000000ffff /* 0xd8 - PDA */ + .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */ + .quad 0x0000000000000000 /* 0xd8 - unused */ .quad 0x0000000000000000 /* 0xe0 - unused */ .quad 0x0000000000000000 /* 0xe8 - unused */ .quad 0x0000000000000000 /* 0xf0 - unused */ diff --git a/trunk/arch/i386/kernel/hpet.c b/trunk/arch/i386/kernel/hpet.c index 45a8685bb60b..17647a530b2f 100644 --- a/trunk/arch/i386/kernel/hpet.c +++ b/trunk/arch/i386/kernel/hpet.c @@ -34,7 +34,6 @@ static int __init init_hpet_clocksource(void) unsigned long hpet_period; void __iomem* hpet_base; u64 tmp; - int err; if (!is_hpet_enabled()) return -ENODEV; @@ -62,11 +61,7 @@ static int __init init_hpet_clocksource(void) do_div(tmp, FSEC_PER_NSEC); clocksource_hpet.mult = (u32)tmp; - err = clocksource_register(&clocksource_hpet); - if (err) - iounmap(hpet_base); - - return err; + return clocksource_register(&clocksource_hpet); } module_init(init_hpet_clocksource); diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index c8d45821c788..62996cd17084 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -381,10 +381,7 @@ void __init init_ISA_irqs (void) } } -/* Overridden in paravirt.c */ -void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); - -void __init native_init_IRQ(void) +void __init init_IRQ(void) { int i; diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index e21dcde0790e..3b7a63e0ed1a 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -154,20 +153,14 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) * the interrupt, and we need to make sure the entry is fully populated * before that happens. */ -static void -__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) { + unsigned long flags; union entry_union eu; eu.entry = e; + spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x11 + 2*pin, eu.w2); io_apic_write(apic, 0x10 + 2*pin, eu.w1); -} - -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - __ioapic_write_entry(apic, pin, e); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -843,7 +836,8 @@ static int __init find_isa_irq_pin(int irq, int type) if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || mp_bus_id_to_type[lbus] == MP_BUS_EISA || - mp_bus_id_to_type[lbus] == MP_BUS_MCA + mp_bus_id_to_type[lbus] == MP_BUS_MCA || + mp_bus_id_to_type[lbus] == MP_BUS_NEC98 ) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) @@ -862,7 +856,8 @@ static int __init find_isa_irq_apic(int irq, int type) if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || mp_bus_id_to_type[lbus] == MP_BUS_EISA || - mp_bus_id_to_type[lbus] == MP_BUS_MCA + mp_bus_id_to_type[lbus] == MP_BUS_MCA || + mp_bus_id_to_type[lbus] == MP_BUS_NEC98 ) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) @@ -992,6 +987,12 @@ static int EISA_ELCR(unsigned int irq) #define default_MCA_trigger(idx) (1) #define default_MCA_polarity(idx) (0) +/* NEC98 interrupts are always polarity zero edge triggered, + * when listed as conforming in the MP table. */ + +#define default_NEC98_trigger(idx) (0) +#define default_NEC98_polarity(idx) (0) + static int __init MPBIOS_polarity(int idx) { int bus = mp_irqs[idx].mpc_srcbus; @@ -1026,6 +1027,11 @@ static int __init MPBIOS_polarity(int idx) polarity = default_MCA_polarity(idx); break; } + case MP_BUS_NEC98: /* NEC 98 pin */ + { + polarity = default_NEC98_polarity(idx); + break; + } default: { printk(KERN_WARNING "broken BIOS!!\n"); @@ -1095,6 +1101,11 @@ static int MPBIOS_trigger(int idx) trigger = default_MCA_trigger(idx); break; } + case MP_BUS_NEC98: /* NEC 98 pin */ + { + trigger = default_NEC98_trigger(idx); + break; + } default: { printk(KERN_WARNING "broken BIOS!!\n"); @@ -1156,6 +1167,7 @@ static int pin_2_irq(int idx, int apic, int pin) case MP_BUS_ISA: /* ISA pin */ case MP_BUS_EISA: case MP_BUS_MCA: + case MP_BUS_NEC98: { irq = mp_irqs[idx].mpc_srcbusirq; break; @@ -1223,7 +1235,7 @@ static inline int IO_APIC_irq_trigger(int irq) } /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ -static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; +u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; static int __assign_irq_vector(int irq) { @@ -1348,8 +1360,8 @@ static void __init setup_IO_APIC_irqs(void) if (!apic && (irq < 16)) disable_8259A_irq(irq); } + ioapic_write_entry(apic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); - __ioapic_write_entry(apic, pin, entry); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -1914,15 +1926,6 @@ static void __init setup_ioapic_ids_from_mpc(void) static void __init setup_ioapic_ids_from_mpc(void) { } #endif -static int no_timer_check __initdata; - -static int __init notimercheck(char *s) -{ - no_timer_check = 1; - return 1; -} -__setup("no_timer_check", notimercheck); - /* * There is a nasty bug in some older SMP boards, their mptable lies * about the timer IRQ. We do the following to work around the situation: @@ -1931,13 +1934,10 @@ __setup("no_timer_check", notimercheck); * - if this function detects that timer IRQs are defunct, then we fall * back to ISA timer IRQs */ -int __init timer_irq_works(void) +static int __init timer_irq_works(void) { unsigned long t1 = jiffies; - if (no_timer_check) - return 1; - local_irq_enable(); /* Let ten ticks pass... */ mdelay((10 * 1000) / HZ); @@ -2161,15 +2161,9 @@ static inline void unlock_ExtINT_logic(void) unsigned char save_control, save_freq_select; pin = find_isa_irq_pin(8, mp_INT); - if (pin == -1) { - WARN_ON_ONCE(1); - return; - } apic = find_isa_irq_apic(8, mp_INT); - if (apic == -1) { - WARN_ON_ONCE(1); + if (pin == -1) return; - } entry0 = ioapic_read_entry(apic, pin); clear_IO_APIC_pin(apic, pin); @@ -2214,7 +2208,7 @@ int timer_uses_ioapic_pin_0; * is so screwy. Thanks to Brian Perkins for testing/hacking this beast * fanatically on his truly buggy board. */ -static inline void __init check_timer(void) +static inline void check_timer(void) { int apic1, pin1, apic2, pin2; int vector; @@ -2862,8 +2856,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a if (!ioapic && (irq < 16)) disable_8259A_irq(irq); + ioapic_write_entry(ioapic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); - __ioapic_write_entry(ioapic, pin, entry); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); diff --git a/trunk/arch/i386/kernel/kprobes.c b/trunk/arch/i386/kernel/kprobes.c index af1d53344993..fc79e1e859c4 100644 --- a/trunk/arch/i386/kernel/kprobes.c +++ b/trunk/arch/i386/kernel/kprobes.c @@ -184,7 +184,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1)); + free_insn_slot(p->ainsn.insn); mutex_unlock(&kprobe_mutex); } @@ -333,7 +333,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) return 1; ss_probe: -#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM) +#ifndef CONFIG_PREEMPT if (p->ainsn.boostable == 1 && !p->post_handler){ /* Boost up -- we can execute copied instructions directly */ reset_current_kprobe(); diff --git a/trunk/arch/i386/kernel/ldt.c b/trunk/arch/i386/kernel/ldt.c index b410e5fb034f..445211eb2d57 100644 --- a/trunk/arch/i386/kernel/ldt.c +++ b/trunk/arch/i386/kernel/ldt.c @@ -160,14 +160,16 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) { int err; unsigned long size; + void *address; err = 0; + address = &default_ldt[0]; size = 5*sizeof(struct desc_struct); if (size > bytecount) size = bytecount; err = size; - if (clear_user(ptr, size)) + if (copy_to_user(ptr, address, size)) err = -EFAULT; return err; diff --git a/trunk/arch/i386/kernel/mca.c b/trunk/arch/i386/kernel/mca.c index b83672b89527..eb57a851789d 100644 --- a/trunk/arch/i386/kernel/mca.c +++ b/trunk/arch/i386/kernel/mca.c @@ -283,9 +283,10 @@ static int __init mca_init(void) bus->f.mca_transform_memory = mca_dummy_transform_memory; /* get the motherboard device */ - mca_dev = kzalloc(sizeof(struct mca_device), GFP_KERNEL); + mca_dev = kmalloc(sizeof(struct mca_device), GFP_KERNEL); if(unlikely(!mca_dev)) goto out_nomem; + memset(mca_dev, 0, sizeof(struct mca_device)); /* * We do not expect many MCA interrupts during initialization, @@ -309,9 +310,11 @@ static int __init mca_init(void) mca_dev->slot = MCA_MOTHERBOARD; mca_register_device(MCA_PRIMARY_BUS, mca_dev); - mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); + mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC); if(unlikely(!mca_dev)) goto out_unlock_nomem; + memset(mca_dev, 0, sizeof(struct mca_device)); + /* Put motherboard into video setup mode, read integrated video * POS registers, and turn motherboard setup off. @@ -346,9 +349,10 @@ static int __init mca_init(void) } if(which_scsi) { /* found a scsi card */ - mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); + mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC); if(unlikely(!mca_dev)) goto out_unlock_nomem; + memset(mca_dev, 0, sizeof(struct mca_device)); for(j = 0; j < 8; j++) mca_dev->pos[j] = pos[j]; @@ -374,9 +378,10 @@ static int __init mca_init(void) if(!mca_read_and_store_pos(pos)) continue; - mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); + mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC); if(unlikely(!mca_dev)) goto out_unlock_nomem; + memset(mca_dev, 0, sizeof(struct mca_device)); for(j=0; j<8; j++) mca_dev->pos[j]=pos[j]; diff --git a/trunk/arch/i386/kernel/microcode.c b/trunk/arch/i386/kernel/microcode.c index 972346604f9d..23f5984d0654 100644 --- a/trunk/arch/i386/kernel/microcode.c +++ b/trunk/arch/i386/kernel/microcode.c @@ -703,6 +703,7 @@ static struct sysdev_driver mc_sysdev_driver = { .resume = mc_sysdev_resume, }; +#ifdef CONFIG_HOTPLUG_CPU static __cpuinit int mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { @@ -725,6 +726,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) static struct notifier_block mc_cpu_notifier = { .notifier_call = mc_cpu_callback, }; +#endif static int __init microcode_init (void) { diff --git a/trunk/arch/i386/kernel/module.c b/trunk/arch/i386/kernel/module.c index d7d9c8b23f72..470cf97e7cd3 100644 --- a/trunk/arch/i386/kernel/module.c +++ b/trunk/arch/i386/kernel/module.c @@ -108,8 +108,7 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, - *para = NULL; + const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { @@ -119,8 +118,6 @@ int module_finalize(const Elf_Ehdr *hdr, alt = s; if (!strcmp(".smp_locks", secstrings + s->sh_name)) locks= s; - if (!strcmp(".parainstructions", secstrings + s->sh_name)) - para = s; } if (alt) { @@ -135,12 +132,6 @@ int module_finalize(const Elf_Ehdr *hdr, lseg, lseg + locks->sh_size, tseg, tseg + text->sh_size); } - - if (para) { - void *pseg = (void *)para->sh_addr; - apply_paravirt(pseg, pseg + para->sh_size); - } - return 0; } diff --git a/trunk/arch/i386/kernel/mpparse.c b/trunk/arch/i386/kernel/mpparse.c index 2ce67228dff8..442aaf8c77eb 100644 --- a/trunk/arch/i386/kernel/mpparse.c +++ b/trunk/arch/i386/kernel/mpparse.c @@ -249,6 +249,8 @@ static void __init MP_bus_info (struct mpc_config_bus *m) mp_current_pci_id++; } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; + } else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) { + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_NEC98; } else { printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); } diff --git a/trunk/arch/i386/kernel/msr.c b/trunk/arch/i386/kernel/msr.c index 1d1a56cae340..a773f776c9ea 100644 --- a/trunk/arch/i386/kernel/msr.c +++ b/trunk/arch/i386/kernel/msr.c @@ -195,6 +195,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf, { const u32 __user *tmp = (const u32 __user *)buf; u32 data[2]; + size_t rv; u32 reg = *ppos; int cpu = iminor(file->f_dentry->d_inode); int err; @@ -202,7 +203,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf, if (count % 8) return -EINVAL; /* Invalid chunk size */ - for (; count; count -= 8) { + for (rv = 0; count; count -= 8) { if (copy_from_user(&data, tmp, 8)) return -EFAULT; err = do_wrmsr(cpu, reg, data[0], data[1]); @@ -249,6 +250,7 @@ static int msr_device_create(int i) return err; } +#ifdef CONFIG_HOTPLUG_CPU static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -269,6 +271,7 @@ static struct notifier_block __cpuinitdata msr_class_cpu_notifier = { .notifier_call = msr_class_cpu_callback, }; +#endif static int __init msr_init(void) { diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index f5bc7e1be801..eaafe233a5da 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -43,8 +42,6 @@ int nmi_watchdog_enabled; static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner); static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]); -static cpumask_t backtrace_mask = CPU_MASK_NONE; - /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ @@ -870,16 +867,14 @@ static unsigned int void touch_nmi_watchdog (void) { - if (nmi_watchdog > 0) { - unsigned cpu; + int i; - /* - * Just reset the alert counters, (other CPUs might be - * spinning on locks we hold): - */ - for_each_present_cpu (cpu) - alert_counter[cpu] = 0; - } + /* + * Just reset the alert counters, (other CPUs might be + * spinning on locks we hold): + */ + for_each_possible_cpu(i) + alert_counter[i] = 0; /* * Tickle the softlockup detector too: @@ -912,16 +907,6 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) touched = 1; } - if (cpu_isset(cpu, backtrace_mask)) { - static DEFINE_SPINLOCK(lock); /* Serialise the printks */ - - spin_lock(&lock); - printk("NMI backtrace for cpu %d\n", cpu); - dump_stack(); - spin_unlock(&lock); - cpu_clear(cpu, backtrace_mask); - } - sum = per_cpu(irq_stat, cpu).apic_timer_irqs; /* if the apic timer isn't firing, this cpu isn't doing much */ @@ -1048,19 +1033,6 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif -void __trigger_all_cpu_backtrace(void) -{ - int i; - - backtrace_mask = cpu_online_map; - /* Wait for up to 10 seconds for all CPUs to do the backtrace */ - for (i = 0; i < 10 * 1000; i++) { - if (cpus_empty(backtrace_mask)) - break; - mdelay(1); - } -} - EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); diff --git a/trunk/arch/i386/kernel/paravirt.c b/trunk/arch/i386/kernel/paravirt.c deleted file mode 100644 index 3dceab5828f1..000000000000 --- a/trunk/arch/i386/kernel/paravirt.c +++ /dev/null @@ -1,569 +0,0 @@ -/* Paravirtualization interfaces - Copyright (C) 2006 Rusty Russell IBM Corporation - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* nop stub */ -static void native_nop(void) -{ -} - -static void __init default_banner(void) -{ - printk(KERN_INFO "Booting paravirtualized kernel on %s\n", - paravirt_ops.name); -} - -char *memory_setup(void) -{ - return paravirt_ops.memory_setup(); -} - -/* Simple instruction patching code. */ -#define DEF_NATIVE(name, code) \ - extern const char start_##name[], end_##name[]; \ - asm("start_" #name ": " code "; end_" #name ":") -DEF_NATIVE(cli, "cli"); -DEF_NATIVE(sti, "sti"); -DEF_NATIVE(popf, "push %eax; popf"); -DEF_NATIVE(pushf, "pushf; pop %eax"); -DEF_NATIVE(pushf_cli, "pushf; pop %eax; cli"); -DEF_NATIVE(iret, "iret"); -DEF_NATIVE(sti_sysexit, "sti; sysexit"); - -static const struct native_insns -{ - const char *start, *end; -} native_insns[] = { - [PARAVIRT_IRQ_DISABLE] = { start_cli, end_cli }, - [PARAVIRT_IRQ_ENABLE] = { start_sti, end_sti }, - [PARAVIRT_RESTORE_FLAGS] = { start_popf, end_popf }, - [PARAVIRT_SAVE_FLAGS] = { start_pushf, end_pushf }, - [PARAVIRT_SAVE_FLAGS_IRQ_DISABLE] = { start_pushf_cli, end_pushf_cli }, - [PARAVIRT_INTERRUPT_RETURN] = { start_iret, end_iret }, - [PARAVIRT_STI_SYSEXIT] = { start_sti_sysexit, end_sti_sysexit }, -}; - -static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) -{ - unsigned int insn_len; - - /* Don't touch it if we don't have a replacement */ - if (type >= ARRAY_SIZE(native_insns) || !native_insns[type].start) - return len; - - insn_len = native_insns[type].end - native_insns[type].start; - - /* Similarly if we can't fit replacement. */ - if (len < insn_len) - return len; - - memcpy(insns, native_insns[type].start, insn_len); - return insn_len; -} - -static fastcall unsigned long native_get_debugreg(int regno) -{ - unsigned long val = 0; /* Damn you, gcc! */ - - switch (regno) { - case 0: - asm("movl %%db0, %0" :"=r" (val)); break; - case 1: - asm("movl %%db1, %0" :"=r" (val)); break; - case 2: - asm("movl %%db2, %0" :"=r" (val)); break; - case 3: - asm("movl %%db3, %0" :"=r" (val)); break; - case 6: - asm("movl %%db6, %0" :"=r" (val)); break; - case 7: - asm("movl %%db7, %0" :"=r" (val)); break; - default: - BUG(); - } - return val; -} - -static fastcall void native_set_debugreg(int regno, unsigned long value) -{ - switch (regno) { - case 0: - asm("movl %0,%%db0" : /* no output */ :"r" (value)); - break; - case 1: - asm("movl %0,%%db1" : /* no output */ :"r" (value)); - break; - case 2: - asm("movl %0,%%db2" : /* no output */ :"r" (value)); - break; - case 3: - asm("movl %0,%%db3" : /* no output */ :"r" (value)); - break; - case 6: - asm("movl %0,%%db6" : /* no output */ :"r" (value)); - break; - case 7: - asm("movl %0,%%db7" : /* no output */ :"r" (value)); - break; - default: - BUG(); - } -} - -void init_IRQ(void) -{ - paravirt_ops.init_IRQ(); -} - -static fastcall void native_clts(void) -{ - asm volatile ("clts"); -} - -static fastcall unsigned long native_read_cr0(void) -{ - unsigned long val; - asm volatile("movl %%cr0,%0\n\t" :"=r" (val)); - return val; -} - -static fastcall void native_write_cr0(unsigned long val) -{ - asm volatile("movl %0,%%cr0": :"r" (val)); -} - -static fastcall unsigned long native_read_cr2(void) -{ - unsigned long val; - asm volatile("movl %%cr2,%0\n\t" :"=r" (val)); - return val; -} - -static fastcall void native_write_cr2(unsigned long val) -{ - asm volatile("movl %0,%%cr2": :"r" (val)); -} - -static fastcall unsigned long native_read_cr3(void) -{ - unsigned long val; - asm volatile("movl %%cr3,%0\n\t" :"=r" (val)); - return val; -} - -static fastcall void native_write_cr3(unsigned long val) -{ - asm volatile("movl %0,%%cr3": :"r" (val)); -} - -static fastcall unsigned long native_read_cr4(void) -{ - unsigned long val; - asm volatile("movl %%cr4,%0\n\t" :"=r" (val)); - return val; -} - -static fastcall unsigned long native_read_cr4_safe(void) -{ - unsigned long val; - /* This could fault if %cr4 does not exist */ - asm("1: movl %%cr4, %0 \n" - "2: \n" - ".section __ex_table,\"a\" \n" - ".long 1b,2b \n" - ".previous \n" - : "=r" (val): "0" (0)); - return val; -} - -static fastcall void native_write_cr4(unsigned long val) -{ - asm volatile("movl %0,%%cr4": :"r" (val)); -} - -static fastcall unsigned long native_save_fl(void) -{ - unsigned long f; - asm volatile("pushfl ; popl %0":"=g" (f): /* no input */); - return f; -} - -static fastcall void native_restore_fl(unsigned long f) -{ - asm volatile("pushl %0 ; popfl": /* no output */ - :"g" (f) - :"memory", "cc"); -} - -static fastcall void native_irq_disable(void) -{ - asm volatile("cli": : :"memory"); -} - -static fastcall void native_irq_enable(void) -{ - asm volatile("sti": : :"memory"); -} - -static fastcall void native_safe_halt(void) -{ - asm volatile("sti; hlt": : :"memory"); -} - -static fastcall void native_halt(void) -{ - asm volatile("hlt": : :"memory"); -} - -static fastcall void native_wbinvd(void) -{ - asm volatile("wbinvd": : :"memory"); -} - -static fastcall unsigned long long native_read_msr(unsigned int msr, int *err) -{ - unsigned long long val; - - asm volatile("2: rdmsr ; xorl %0,%0\n" - "1:\n\t" - ".section .fixup,\"ax\"\n\t" - "3: movl %3,%0 ; jmp 1b\n\t" - ".previous\n\t" - ".section __ex_table,\"a\"\n" - " .align 4\n\t" - " .long 2b,3b\n\t" - ".previous" - : "=r" (*err), "=A" (val) - : "c" (msr), "i" (-EFAULT)); - - return val; -} - -static fastcall int native_write_msr(unsigned int msr, unsigned long long val) -{ - int err; - asm volatile("2: wrmsr ; xorl %0,%0\n" - "1:\n\t" - ".section .fixup,\"ax\"\n\t" - "3: movl %4,%0 ; jmp 1b\n\t" - ".previous\n\t" - ".section __ex_table,\"a\"\n" - " .align 4\n\t" - " .long 2b,3b\n\t" - ".previous" - : "=a" (err) - : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), - "i" (-EFAULT)); - return err; -} - -static fastcall unsigned long long native_read_tsc(void) -{ - unsigned long long val; - asm volatile("rdtsc" : "=A" (val)); - return val; -} - -static fastcall unsigned long long native_read_pmc(void) -{ - unsigned long long val; - asm volatile("rdpmc" : "=A" (val)); - return val; -} - -static fastcall void native_load_tr_desc(void) -{ - asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); -} - -static fastcall void native_load_gdt(const struct Xgt_desc_struct *dtr) -{ - asm volatile("lgdt %0"::"m" (*dtr)); -} - -static fastcall void native_load_idt(const struct Xgt_desc_struct *dtr) -{ - asm volatile("lidt %0"::"m" (*dtr)); -} - -static fastcall void native_store_gdt(struct Xgt_desc_struct *dtr) -{ - asm ("sgdt %0":"=m" (*dtr)); -} - -static fastcall void native_store_idt(struct Xgt_desc_struct *dtr) -{ - asm ("sidt %0":"=m" (*dtr)); -} - -static fastcall unsigned long native_store_tr(void) -{ - unsigned long tr; - asm ("str %0":"=r" (tr)); - return tr; -} - -static fastcall void native_load_tls(struct thread_struct *t, unsigned int cpu) -{ -#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i] - C(0); C(1); C(2); -#undef C -} - -static inline void native_write_dt_entry(void *dt, int entry, u32 entry_low, u32 entry_high) -{ - u32 *lp = (u32 *)((char *)dt + entry*8); - lp[0] = entry_low; - lp[1] = entry_high; -} - -static fastcall void native_write_ldt_entry(void *dt, int entrynum, u32 low, u32 high) -{ - native_write_dt_entry(dt, entrynum, low, high); -} - -static fastcall void native_write_gdt_entry(void *dt, int entrynum, u32 low, u32 high) -{ - native_write_dt_entry(dt, entrynum, low, high); -} - -static fastcall void native_write_idt_entry(void *dt, int entrynum, u32 low, u32 high) -{ - native_write_dt_entry(dt, entrynum, low, high); -} - -static fastcall void native_load_esp0(struct tss_struct *tss, - struct thread_struct *thread) -{ - tss->esp0 = thread->esp0; - - /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->ss1 != thread->sysenter_cs)) { - tss->ss1 = thread->sysenter_cs; - wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); - } -} - -static fastcall void native_io_delay(void) -{ - asm volatile("outb %al,$0x80"); -} - -static fastcall void native_flush_tlb(void) -{ - __native_flush_tlb(); -} - -/* - * Global pages have to be flushed a bit differently. Not a real - * performance problem because this does not happen often. - */ -static fastcall void native_flush_tlb_global(void) -{ - __native_flush_tlb_global(); -} - -static fastcall void native_flush_tlb_single(u32 addr) -{ - __native_flush_tlb_single(addr); -} - -#ifndef CONFIG_X86_PAE -static fastcall void native_set_pte(pte_t *ptep, pte_t pteval) -{ - *ptep = pteval; -} - -static fastcall void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval) -{ - *ptep = pteval; -} - -static fastcall void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) -{ - *pmdp = pmdval; -} - -#else /* CONFIG_X86_PAE */ - -static fastcall void native_set_pte(pte_t *ptep, pte_t pte) -{ - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} - -static fastcall void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) -{ - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} - -static fastcall void native_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) -{ - ptep->pte_low = 0; - smp_wmb(); - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} - -static fastcall void native_set_pte_atomic(pte_t *ptep, pte_t pteval) -{ - set_64bit((unsigned long long *)ptep,pte_val(pteval)); -} - -static fastcall void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) -{ - set_64bit((unsigned long long *)pmdp,pmd_val(pmdval)); -} - -static fastcall void native_set_pud(pud_t *pudp, pud_t pudval) -{ - *pudp = pudval; -} - -static fastcall void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - ptep->pte_low = 0; - smp_wmb(); - ptep->pte_high = 0; -} - -static fastcall void native_pmd_clear(pmd_t *pmd) -{ - u32 *tmp = (u32 *)pmd; - *tmp = 0; - smp_wmb(); - *(tmp + 1) = 0; -} -#endif /* CONFIG_X86_PAE */ - -/* These are in entry.S */ -extern fastcall void native_iret(void); -extern fastcall void native_irq_enable_sysexit(void); - -static int __init print_banner(void) -{ - paravirt_ops.banner(); - return 0; -} -core_initcall(print_banner); - -/* We simply declare start_kernel to be the paravirt probe of last resort. */ -paravirt_probe(start_kernel); - -struct paravirt_ops paravirt_ops = { - .name = "bare hardware", - .paravirt_enabled = 0, - .kernel_rpl = 0, - - .patch = native_patch, - .banner = default_banner, - .arch_setup = native_nop, - .memory_setup = machine_specific_memory_setup, - .get_wallclock = native_get_wallclock, - .set_wallclock = native_set_wallclock, - .time_init = time_init_hook, - .init_IRQ = native_init_IRQ, - - .cpuid = native_cpuid, - .get_debugreg = native_get_debugreg, - .set_debugreg = native_set_debugreg, - .clts = native_clts, - .read_cr0 = native_read_cr0, - .write_cr0 = native_write_cr0, - .read_cr2 = native_read_cr2, - .write_cr2 = native_write_cr2, - .read_cr3 = native_read_cr3, - .write_cr3 = native_write_cr3, - .read_cr4 = native_read_cr4, - .read_cr4_safe = native_read_cr4_safe, - .write_cr4 = native_write_cr4, - .save_fl = native_save_fl, - .restore_fl = native_restore_fl, - .irq_disable = native_irq_disable, - .irq_enable = native_irq_enable, - .safe_halt = native_safe_halt, - .halt = native_halt, - .wbinvd = native_wbinvd, - .read_msr = native_read_msr, - .write_msr = native_write_msr, - .read_tsc = native_read_tsc, - .read_pmc = native_read_pmc, - .load_tr_desc = native_load_tr_desc, - .set_ldt = native_set_ldt, - .load_gdt = native_load_gdt, - .load_idt = native_load_idt, - .store_gdt = native_store_gdt, - .store_idt = native_store_idt, - .store_tr = native_store_tr, - .load_tls = native_load_tls, - .write_ldt_entry = native_write_ldt_entry, - .write_gdt_entry = native_write_gdt_entry, - .write_idt_entry = native_write_idt_entry, - .load_esp0 = native_load_esp0, - - .set_iopl_mask = native_set_iopl_mask, - .io_delay = native_io_delay, - .const_udelay = __const_udelay, - -#ifdef CONFIG_X86_LOCAL_APIC - .apic_write = native_apic_write, - .apic_write_atomic = native_apic_write_atomic, - .apic_read = native_apic_read, -#endif - - .flush_tlb_user = native_flush_tlb, - .flush_tlb_kernel = native_flush_tlb_global, - .flush_tlb_single = native_flush_tlb_single, - - .set_pte = native_set_pte, - .set_pte_at = native_set_pte_at, - .set_pmd = native_set_pmd, - .pte_update = (void *)native_nop, - .pte_update_defer = (void *)native_nop, -#ifdef CONFIG_X86_PAE - .set_pte_atomic = native_set_pte_atomic, - .set_pte_present = native_set_pte_present, - .set_pud = native_set_pud, - .pte_clear = native_pte_clear, - .pmd_clear = native_pmd_clear, -#endif - - .irq_enable_sysexit = native_irq_enable_sysexit, - .iret = native_iret, -}; -EXPORT_SYMBOL(paravirt_ops); diff --git a/trunk/arch/i386/kernel/pci-dma.c b/trunk/arch/i386/kernel/pci-dma.c index 41af692c1584..5c8c6ef1fc5e 100644 --- a/trunk/arch/i386/kernel/pci-dma.c +++ b/trunk/arch/i386/kernel/pci-dma.c @@ -92,12 +92,14 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, if (!mem_base) goto out; - dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); + dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); if (!dev->dma_mem) goto out; - dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); + memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem)); + dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL); if (!dev->dma_mem->bitmap) goto free1_out; + memset(dev->dma_mem->bitmap, 0, bitmap_size); dev->dma_mem->virt_base = mem_base; dev->dma_mem->device_base = device_addr; diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index 99308510a17c..dd53c58f64f1 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -56,7 +56,6 @@ #include #include -#include asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); @@ -100,18 +99,22 @@ EXPORT_SYMBOL(enable_hlt); */ void default_idle(void) { + local_irq_enable(); + if (!hlt_counter && boot_cpu_data.hlt_works_ok) { current_thread_info()->status &= ~TS_POLLING; smp_mb__after_clear_bit(); - local_irq_disable(); - if (!need_resched()) - safe_halt(); /* enables interrupts racelessly */ - else - local_irq_enable(); + while (!need_resched()) { + local_irq_disable(); + if (!need_resched()) + safe_halt(); + else + local_irq_enable(); + } current_thread_info()->status |= TS_POLLING; } else { - /* loop is done by the caller */ - cpu_relax(); + while (!need_resched()) + cpu_relax(); } } #ifdef CONFIG_APM_MODULE @@ -125,7 +128,14 @@ EXPORT_SYMBOL(default_idle); */ static void poll_idle (void) { - cpu_relax(); + local_irq_enable(); + + asm volatile( + "2:" + "testl %0, %1;" + "rep; nop;" + "je 2b;" + : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); } #ifdef CONFIG_HOTPLUG_CPU @@ -246,7 +256,8 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) static void mwait_idle(void) { local_irq_enable(); - mwait_idle_with_hints(0, 0); + while (!need_resched()) + mwait_idle_with_hints(0, 0); } void __devinit select_idle_routine(const struct cpuinfo_x86 *c) @@ -303,8 +314,8 @@ void show_regs(struct pt_regs * regs) regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", regs->esi, regs->edi, regs->ebp); - printk(" DS: %04x ES: %04x GS: %04x\n", - 0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xgs); + printk(" DS: %04x ES: %04x\n", + 0xffff & regs->xds,0xffff & regs->xes); cr0 = read_cr0(); cr2 = read_cr2(); @@ -335,7 +346,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) regs.xds = __USER_DS; regs.xes = __USER_DS; - regs.xgs = __KERNEL_PDA; regs.orig_eax = -1; regs.eip = (unsigned long) kernel_thread_helper; regs.xcs = __KERNEL_CS | get_kernel_rpl(); @@ -421,6 +431,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, p->thread.eip = (unsigned long) ret_from_fork; savesegment(fs,p->thread.fs); + savesegment(gs,p->thread.gs); tsk = current; if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) { @@ -497,7 +508,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump) dump->regs.ds = regs->xds; dump->regs.es = regs->xes; savesegment(fs,dump->regs.fs); - dump->regs.gs = regs->xgs; + savesegment(gs,dump->regs.gs); dump->regs.orig_eax = regs->orig_eax; dump->regs.eip = regs->eip; dump->regs.cs = regs->xcs; @@ -637,27 +648,22 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas __unlazy_fpu(prev_p); - - /* we're going to use this soon, after a few expensive things */ - if (next_p->fpu_counter > 5) - prefetch(&next->i387.fxsave); - /* * Reload esp0. */ load_esp0(tss, next); /* - * Save away %fs. No need to save %gs, as it was saved on the - * stack on entry. No need to save %es and %ds, as those are - * always kernel segments while inside the kernel. Doing this - * before setting the new TLS descriptors avoids the situation - * where we temporarily have non-reloadable segments in %fs - * and %gs. This could be an issue if the NMI handler ever - * used %fs or %gs (it does not today), or if the kernel is - * running inside of a hypervisor layer. + * Save away %fs and %gs. No need to save %es and %ds, as + * those are always kernel segments while inside the kernel. + * Doing this before setting the new TLS descriptors avoids + * the situation where we temporarily have non-reloadable + * segments in %fs and %gs. This could be an issue if the + * NMI handler ever used %fs or %gs (it does not today), or + * if the kernel is running inside of a hypervisor layer. */ savesegment(fs, prev->fs); + savesegment(gs, prev->gs); /* * Load the per-thread Thread-Local Storage descriptor. @@ -665,14 +671,22 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas load_TLS(next, cpu); /* - * Restore %fs if needed. + * Restore %fs and %gs if needed. * - * Glibc normally makes %fs be zero. + * Glibc normally makes %fs be zero, and %gs is one of + * the TLS segments. */ if (unlikely(prev->fs | next->fs)) loadsegment(fs, next->fs); - write_pda(pcurrent, next_p); + if (prev->gs | next->gs) + loadsegment(gs, next->gs); + + /* + * Restore IOPL if needed. + */ + if (unlikely(prev->iopl != next->iopl)) + set_iopl_mask(next->iopl); /* * Now maybe handle debug registers and/or IO bitmaps @@ -683,13 +697,6 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas disable_tsc(prev_p, next_p); - /* If the task has used fpu the last 5 timeslices, just do a full - * restore of the math state immediately to avoid the trap; the - * chances of needing FPU soon are obviously high now - */ - if (next_p->fpu_counter > 5) - math_state_restore(); - return prev_p; } diff --git a/trunk/arch/i386/kernel/ptrace.c b/trunk/arch/i386/kernel/ptrace.c index f3f94ac5736a..775f50e9395b 100644 --- a/trunk/arch/i386/kernel/ptrace.c +++ b/trunk/arch/i386/kernel/ptrace.c @@ -94,9 +94,13 @@ static int putreg(struct task_struct *child, return -EIO; child->thread.fs = value; return 0; + case GS: + if (value && (value & 3) != 3) + return -EIO; + child->thread.gs = value; + return 0; case DS: case ES: - case GS: if (value && (value & 3) != 3) return -EIO; value &= 0xffff; @@ -112,8 +116,8 @@ static int putreg(struct task_struct *child, value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; break; } - if (regno > ES*4) - regno -= 1*4; + if (regno > GS*4) + regno -= 2*4; put_stack_long(child, regno - sizeof(struct pt_regs), value); return 0; } @@ -127,16 +131,18 @@ static unsigned long getreg(struct task_struct *child, case FS: retval = child->thread.fs; break; + case GS: + retval = child->thread.gs; + break; case DS: case ES: - case GS: case SS: case CS: retval = 0xffff; /* fall through */ default: - if (regno > ES*4) - regno -= 1*4; + if (regno > GS*4) + regno -= 2*4; regno = regno - sizeof(struct pt_regs); retval &= get_stack_long(child, regno); } diff --git a/trunk/arch/i386/kernel/quirks.c b/trunk/arch/i386/kernel/quirks.c index a01320a7b636..9f6ab1789bb0 100644 --- a/trunk/arch/i386/kernel/quirks.c +++ b/trunk/arch/i386/kernel/quirks.c @@ -3,23 +3,10 @@ */ #include #include -#include -#include -#include #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) -static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev) -{ -#ifdef CONFIG_X86_64 - if (genapic != &apic_flat) - panic("APIC mode must be flat on this system\n"); -#elif defined(CONFIG_X86_GENERICARCH) - if (genapic != &apic_default) - panic("APIC mode must be default(flat) on this system. Use apic=default\n"); -#endif -} -void __init quirk_intel_irqbalance(void) +static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) { u8 config, rev; u32 word; @@ -29,18 +16,18 @@ void __init quirk_intel_irqbalance(void) * based platforms. * Disable SW irqbalance/affinity on those platforms. */ - rev = read_pci_config_byte(0, 0, 0, PCI_CLASS_REVISION); + pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); if (rev > 0x9) return; printk(KERN_INFO "Intel E7520/7320/7525 detected."); - /* enable access to config space */ - config = read_pci_config_byte(0, 0, 0, 0xf4); - write_pci_config_byte(0, 0, 0, 0xf4, config|0x2); + /* enable access to config space*/ + pci_read_config_byte(dev, 0xf4, &config); + pci_write_config_byte(dev, 0xf4, config|0x2); /* read xTPR register */ - word = read_pci_config_16(0, 0, 0x40, 0x4c); + raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); if (!(word & (1 << 13))) { printk(KERN_INFO "Disabling irq balancing and affinity\n"); @@ -50,25 +37,14 @@ void __init quirk_intel_irqbalance(void) noirqdebug_setup(""); #ifdef CONFIG_PROC_FS no_irq_affinity = 1; -#endif -#ifdef CONFIG_HOTPLUG_CPU - printk(KERN_INFO "Disabling cpu hotplug control\n"); - enable_cpu_hotplug = 0; -#endif -#ifdef CONFIG_X86_64 - /* force the genapic selection to flat mode so that - * interrupts can be redirected to more than one CPU. - */ - genapic_force = &apic_flat; #endif } - /* put back the original value for config space */ + /* put back the original value for config space*/ if (!(config & 0x2)) - write_pci_config_byte(0, 0, 0, 0xf4, config); + pci_write_config_byte(dev, 0xf4, config); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, verify_quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, verify_quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, verify_quirk_intel_irqbalance); - +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); #endif diff --git a/trunk/arch/i386/kernel/reboot.c b/trunk/arch/i386/kernel/reboot.c index 3514b4153f7f..84278e0093a2 100644 --- a/trunk/arch/i386/kernel/reboot.c +++ b/trunk/arch/i386/kernel/reboot.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 79df6e612dbd..141041dde74d 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -63,6 +63,9 @@ #include #include +/* Forward Declaration. */ +void __init find_max_pfn(void); + /* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* address, and must not be in the .bss segment! */ @@ -73,8 +76,11 @@ int disable_pse __devinitdata = 0; /* * Machine setup.. */ -extern struct resource code_resource; -extern struct resource data_resource; + +#ifdef CONFIG_EFI +int efi_enabled = 0; +EXPORT_SYMBOL(efi_enabled); +#endif /* cpu data as detected by the assembly code in head.S */ struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; @@ -93,6 +99,12 @@ unsigned int machine_submodel_id; unsigned int BIOS_revision; unsigned int mca_pentium_flag; +/* For PCI or other memory-mapped resources */ +unsigned long pci_mem_start = 0x10000000; +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pci_mem_start); +#endif + /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; @@ -122,6 +134,7 @@ struct ist_info ist_info; defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) EXPORT_SYMBOL(ist_info); #endif +struct e820map e820; extern void early_cpu_init(void); extern int root_mountflags; @@ -136,6 +149,516 @@ static char command_line[COMMAND_LINE_SIZE]; unsigned char __initdata boot_params[PARAM_SIZE]; +static struct resource data_resource = { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource code_resource = { + .name = "Kernel code", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource system_rom_resource = { + .name = "System ROM", + .start = 0xf0000, + .end = 0xfffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource extension_rom_resource = { + .name = "Extension ROM", + .start = 0xe0000, + .end = 0xeffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource adapter_rom_resources[] = { { + .name = "Adapter ROM", + .start = 0xc8000, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +} }; + +static struct resource video_rom_resource = { + .name = "Video ROM", + .start = 0xc0000, + .end = 0xc7fff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource video_ram_resource = { + .name = "Video RAM area", + .start = 0xa0000, + .end = 0xbffff, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource standard_io_resources[] = { { + .name = "dma1", + .start = 0x0000, + .end = 0x001f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic1", + .start = 0x0020, + .end = 0x0021, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "timer0", + .start = 0x0040, + .end = 0x0043, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "timer1", + .start = 0x0050, + .end = 0x0053, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "keyboard", + .start = 0x0060, + .end = 0x006f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma page reg", + .start = 0x0080, + .end = 0x008f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic2", + .start = 0x00a0, + .end = 0x00a1, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma2", + .start = 0x00c0, + .end = 0x00df, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "fpu", + .start = 0x00f0, + .end = 0x00ff, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +} }; + +#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) + +static int __init romchecksum(unsigned char *rom, unsigned long length) +{ + unsigned char *p, sum = 0; + + for (p = rom; p < rom + length; p++) + sum += *p; + return sum == 0; +} + +static void __init probe_roms(void) +{ + unsigned long start, length, upper; + unsigned char *rom; + int i; + + /* video rom */ + upper = adapter_rom_resources[0].start; + for (start = video_rom_resource.start; start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + video_rom_resource.start = start; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* if checksum okay, trust length byte */ + if (length && romchecksum(rom, length)) + video_rom_resource.end = start + length - 1; + + request_resource(&iomem_resource, &video_rom_resource); + break; + } + + start = (video_rom_resource.end + 1 + 2047) & ~2047UL; + if (start < upper) + start = upper; + + /* system rom */ + request_resource(&iomem_resource, &system_rom_resource); + upper = system_rom_resource.start; + + /* check for extension rom (ignore length byte!) */ + rom = isa_bus_to_virt(extension_rom_resource.start); + if (romsignature(rom)) { + length = extension_rom_resource.end - extension_rom_resource.start + 1; + if (romchecksum(rom, length)) { + request_resource(&iomem_resource, &extension_rom_resource); + upper = extension_rom_resource.start; + } + } + + /* check for adapter roms on 2k boundaries */ + for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* but accept any length that fits if checksum okay */ + if (!length || start + length > upper || !romchecksum(rom, length)) + continue; + + adapter_rom_resources[i].start = start; + adapter_rom_resources[i].end = start + length - 1; + request_resource(&iomem_resource, &adapter_rom_resources[i]); + + start = adapter_rom_resources[i++].end & ~2047UL; + } +} + +static void __init limit_regions(unsigned long long size) +{ + unsigned long long current_addr = 0; + int i; + + if (efi_enabled) { + efi_memory_desc_t *md; + void *p; + + for (p = memmap.map, i = 0; p < memmap.map_end; + p += memmap.desc_size, i++) { + md = p; + current_addr = md->phys_addr + (md->num_pages << 12); + if (md->type == EFI_CONVENTIONAL_MEMORY) { + if (current_addr >= size) { + md->num_pages -= + (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); + memmap.nr_map = i + 1; + return; + } + } + } + } + for (i = 0; i < e820.nr_map; i++) { + current_addr = e820.map[i].addr + e820.map[i].size; + if (current_addr < size) + continue; + + if (e820.map[i].type != E820_RAM) + continue; + + if (e820.map[i].addr >= size) { + /* + * This region starts past the end of the + * requested size, skip it completely. + */ + e820.nr_map = i; + } else { + e820.nr_map = i + 1; + e820.map[i].size -= current_addr - size; + } + return; + } +} + +void __init add_memory_region(unsigned long long start, + unsigned long long size, int type) +{ + int x; + + if (!efi_enabled) { + x = e820.nr_map; + + if (x == E820MAX) { + printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); + return; + } + + e820.map[x].addr = start; + e820.map[x].size = size; + e820.map[x].type = type; + e820.nr_map++; + } +} /* add_memory_region */ + +#define E820_DEBUG 1 + +static void __init print_memory_map(char *who) +{ + int i; + + for (i = 0; i < e820.nr_map; i++) { + printk(" %s: %016Lx - %016Lx ", who, + e820.map[i].addr, + e820.map[i].addr + e820.map[i].size); + switch (e820.map[i].type) { + case E820_RAM: printk("(usable)\n"); + break; + case E820_RESERVED: + printk("(reserved)\n"); + break; + case E820_ACPI: + printk("(ACPI data)\n"); + break; + case E820_NVS: + printk("(ACPI NVS)\n"); + break; + default: printk("type %lu\n", e820.map[i].type); + break; + } + } +} + +/* + * Sanitize the BIOS e820 map. + * + * Some e820 responses include overlapping entries. The following + * replaces the original e820 map with a new one, removing overlaps. + * + */ +struct change_member { + struct e820entry *pbios; /* pointer to original bios entry */ + unsigned long long addr; /* address for this change point */ +}; +static struct change_member change_point_list[2*E820MAX] __initdata; +static struct change_member *change_point[2*E820MAX] __initdata; +static struct e820entry *overlap_list[E820MAX] __initdata; +static struct e820entry new_bios[E820MAX] __initdata; + +int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) +{ + struct change_member *change_tmp; + unsigned long current_type, last_type; + unsigned long long last_addr; + int chgidx, still_changing; + int overlap_entries; + int new_bios_entry; + int old_nr, new_nr, chg_nr; + int i; + + /* + Visually we're performing the following (1,2,3,4 = memory types)... + + Sample memory map (w/overlaps): + ____22__________________ + ______________________4_ + ____1111________________ + _44_____________________ + 11111111________________ + ____________________33__ + ___________44___________ + __________33333_________ + ______________22________ + ___________________2222_ + _________111111111______ + _____________________11_ + _________________4______ + + Sanitized equivalent (no overlap): + 1_______________________ + _44_____________________ + ___1____________________ + ____22__________________ + ______11________________ + _________1______________ + __________3_____________ + ___________44___________ + _____________33_________ + _______________2________ + ________________1_______ + _________________4______ + ___________________2____ + ____________________33__ + ______________________4_ + */ + + /* if there's only one memory region, don't bother */ + if (*pnr_map < 2) + return -1; + + old_nr = *pnr_map; + + /* bail out if we find any unreasonable addresses in bios map */ + for (i=0; iaddr = biosmap[i].addr; + change_point[chgidx++]->pbios = &biosmap[i]; + change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; + change_point[chgidx++]->pbios = &biosmap[i]; + } + } + chg_nr = chgidx; /* true number of change-points */ + + /* sort change-point list by memory addresses (low -> high) */ + still_changing = 1; + while (still_changing) { + still_changing = 0; + for (i=1; i < chg_nr; i++) { + /* if > , swap */ + /* or, if current= & last=, swap */ + if ((change_point[i]->addr < change_point[i-1]->addr) || + ((change_point[i]->addr == change_point[i-1]->addr) && + (change_point[i]->addr == change_point[i]->pbios->addr) && + (change_point[i-1]->addr != change_point[i-1]->pbios->addr)) + ) + { + change_tmp = change_point[i]; + change_point[i] = change_point[i-1]; + change_point[i-1] = change_tmp; + still_changing=1; + } + } + } + + /* create a new bios memory map, removing overlaps */ + overlap_entries=0; /* number of entries in the overlap table */ + new_bios_entry=0; /* index for creating new bios map entries */ + last_type = 0; /* start with undefined memory type */ + last_addr = 0; /* start with 0 as last starting address */ + /* loop through change-points, determining affect on the new bios map */ + for (chgidx=0; chgidx < chg_nr; chgidx++) + { + /* keep track of all overlapping bios entries */ + if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) + { + /* add map entry to overlap list (> 1 entry implies an overlap) */ + overlap_list[overlap_entries++]=change_point[chgidx]->pbios; + } + else + { + /* remove entry from list (order independent, so swap with last) */ + for (i=0; ipbios) + overlap_list[i] = overlap_list[overlap_entries-1]; + } + overlap_entries--; + } + /* if there are overlapping entries, decide which "type" to use */ + /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ + current_type = 0; + for (i=0; itype > current_type) + current_type = overlap_list[i]->type; + /* continue building up new bios map based on this information */ + if (current_type != last_type) { + if (last_type != 0) { + new_bios[new_bios_entry].size = + change_point[chgidx]->addr - last_addr; + /* move forward only if the new size was non-zero */ + if (new_bios[new_bios_entry].size != 0) + if (++new_bios_entry >= E820MAX) + break; /* no more space left for new bios entries */ + } + if (current_type != 0) { + new_bios[new_bios_entry].addr = change_point[chgidx]->addr; + new_bios[new_bios_entry].type = current_type; + last_addr=change_point[chgidx]->addr; + } + last_type = current_type; + } + } + new_nr = new_bios_entry; /* retain count for new bios entries */ + + /* copy new bios mapping into original location */ + memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); + *pnr_map = new_nr; + + return 0; +} + +/* + * Copy the BIOS e820 map into a safe place. + * + * Sanity-check it while we're at it.. + * + * If we're lucky and live on a modern system, the setup code + * will have given us a memory map that we can use to properly + * set up memory. If we aren't, we'll fake a memory map. + * + * We check to see that the memory map contains at least 2 elements + * before we'll use it, because the detection code in setup.S may + * not be perfect and most every PC known to man has two memory + * regions: one from 0 to 640k, and one from 1mb up. (The IBM + * thinkpad 560x, for example, does not cooperate with the memory + * detection code.) + */ +int __init copy_e820_map(struct e820entry * biosmap, int nr_map) +{ + /* Only one memory region (or negative)? Ignore it */ + if (nr_map < 2) + return -1; + + do { + unsigned long long start = biosmap->addr; + unsigned long long size = biosmap->size; + unsigned long long end = start + size; + unsigned long type = biosmap->type; + + /* Overflow in 64 bits? Ignore the memory map. */ + if (start > end) + return -1; + + /* + * Some BIOSes claim RAM in the 640k - 1M region. + * Not right. Fix it up. + */ + if (type == E820_RAM) { + if (start < 0x100000ULL && end > 0xA0000ULL) { + if (start < 0xA0000ULL) + add_memory_region(start, 0xA0000ULL-start, type); + if (end <= 0x100000ULL) + continue; + start = 0x100000ULL; + size = end - start; + } + } + add_memory_region(start, size, type); + } while (biosmap++,--nr_map); + return 0; +} + #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE @@ -159,7 +682,7 @@ static inline void copy_edd(void) } #endif -int __initdata user_defined_memmap = 0; +static int __initdata user_defined_memmap = 0; /* * "mem=nopentium" disables the 4MB page tables. @@ -196,6 +719,51 @@ static int __init parse_mem(char *arg) } early_param("mem", parse_mem); +static int __init parse_memmap(char *arg) +{ + if (!arg) + return -EINVAL; + + if (strcmp(arg, "exactmap") == 0) { +#ifdef CONFIG_CRASH_DUMP + /* If we are doing a crash dump, we + * still need to know the real mem + * size before original memory map is + * reset. + */ + find_max_pfn(); + saved_max_pfn = max_pfn; +#endif + e820.nr_map = 0; + user_defined_memmap = 1; + } else { + /* If the user specifies memory size, we + * limit the BIOS-provided memory map to + * that size. exactmap can be used to specify + * the exact map. mem=number can be used to + * trim the existing memory map. + */ + unsigned long long start_at, mem_size; + + mem_size = memparse(arg, &arg); + if (*arg == '@') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, E820_RAM); + } else if (*arg == '#') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, E820_ACPI); + } else if (*arg == '$') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, E820_RESERVED); + } else { + limit_regions(mem_size); + user_defined_memmap = 1; + } + } + return 0; +} +early_param("memmap", parse_memmap); + #ifdef CONFIG_PROC_VMCORE /* elfcorehdr= specifies the location of elf core header * stored by the crashed kernel. @@ -259,6 +827,90 @@ static int __init parse_reservetop(char *arg) } early_param("reservetop", parse_reservetop); +/* + * Callback for efi_memory_walk. + */ +static int __init +efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) +{ + unsigned long *max_pfn = arg, pfn; + + if (start < end) { + pfn = PFN_UP(end -1); + if (pfn > *max_pfn) + *max_pfn = pfn; + } + return 0; +} + +static int __init +efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) +{ + memory_present(0, PFN_UP(start), PFN_DOWN(end)); + return 0; +} + + /* + * This function checks if the entire range is mapped with type. + * + * Note: this function only works correct if the e820 table is sorted and + * not-overlapping, which is the case + */ +int __init +e820_all_mapped(unsigned long s, unsigned long e, unsigned type) +{ + u64 start = s; + u64 end = e; + int i; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + if (type && ei->type != type) + continue; + /* is the region (part) in overlap with the current region ?*/ + if (ei->addr >= end || ei->addr + ei->size <= start) + continue; + /* if the region is at the beginning of we move + * start to the end of the region since it's ok until there + */ + if (ei->addr <= start) + start = ei->addr + ei->size; + /* if start is now at or beyond end, we're done, full + * coverage */ + if (start >= end) + return 1; /* we're done */ + } + return 0; +} + +/* + * Find the highest page frame number we have available + */ +void __init find_max_pfn(void) +{ + int i; + + max_pfn = 0; + if (efi_enabled) { + efi_memmap_walk(efi_find_max_pfn, &max_pfn); + efi_memmap_walk(efi_memory_present_wrapper, NULL); + return; + } + + for (i = 0; i < e820.nr_map; i++) { + unsigned long start, end; + /* RAM? */ + if (e820.map[i].type != E820_RAM) + continue; + start = PFN_UP(e820.map[i].addr); + end = PFN_DOWN(e820.map[i].addr + e820.map[i].size); + if (start >= end) + continue; + if (end > max_pfn) + max_pfn = end; + memory_present(0, start, end); + } +} + /* * Determine low and high memory ranges: */ @@ -318,6 +970,68 @@ unsigned long __init find_max_low_pfn(void) return max_low_pfn; } +/* + * Free all available memory for boot time allocation. Used + * as a callback function by efi_memory_walk() + */ + +static int __init +free_available_memory(unsigned long start, unsigned long end, void *arg) +{ + /* check max_low_pfn */ + if (start >= (max_low_pfn << PAGE_SHIFT)) + return 0; + if (end >= (max_low_pfn << PAGE_SHIFT)) + end = max_low_pfn << PAGE_SHIFT; + if (start < end) + free_bootmem(start, end - start); + + return 0; +} +/* + * Register fully available low RAM pages with the bootmem allocator. + */ +static void __init register_bootmem_low_pages(unsigned long max_low_pfn) +{ + int i; + + if (efi_enabled) { + efi_memmap_walk(free_available_memory, NULL); + return; + } + for (i = 0; i < e820.nr_map; i++) { + unsigned long curr_pfn, last_pfn, size; + /* + * Reserve usable low memory + */ + if (e820.map[i].type != E820_RAM) + continue; + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(e820.map[i].addr); + if (curr_pfn >= max_low_pfn) + continue; + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); + + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + + /* + * .. finally, did all the rounding and playing + * around just make the area go away? + */ + if (last_pfn <= curr_pfn) + continue; + + size = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + } +} + /* * workaround for Dell systems that neglect to reserve EBDA */ @@ -404,8 +1118,8 @@ void __init setup_bootmem_allocator(void) * the (very unlikely) case of us accidentally initializing the * bootmem allocator with an invalid RAM area. */ - reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + - bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text)); + reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) + + bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START)); /* * reserve physical page 0 - it's a special BIOS page on many boxes, @@ -448,7 +1162,8 @@ void __init setup_bootmem_allocator(void) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem(INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET; + initrd_start = + INITRD_START ? INITRD_START + PAGE_OFFSET : 0; initrd_end = initrd_start+INITRD_SIZE; } else { @@ -485,6 +1200,126 @@ void __init remapped_pgdat_init(void) } } +/* + * Request address space for all standard RAM and ROM resources + * and also for regions reported as reserved by the e820. + */ +static void __init +legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) +{ + int i; + + probe_roms(); + for (i = 0; i < e820.nr_map; i++) { + struct resource *res; +#ifndef CONFIG_RESOURCES_64BIT + if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) + continue; +#endif + res = kzalloc(sizeof(struct resource), GFP_ATOMIC); + switch (e820.map[i].type) { + case E820_RAM: res->name = "System RAM"; break; + case E820_ACPI: res->name = "ACPI Tables"; break; + case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; + default: res->name = "reserved"; + } + res->start = e820.map[i].addr; + res->end = res->start + e820.map[i].size - 1; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&iomem_resource, res)) { + kfree(res); + continue; + } + if (e820.map[i].type == E820_RAM) { + /* + * We don't know which RAM region contains kernel data, + * so we try it repeatedly and let the resource manager + * test it. + */ + request_resource(res, code_resource); + request_resource(res, data_resource); +#ifdef CONFIG_KEXEC + request_resource(res, &crashk_res); +#endif + } + } +} + +/* + * Request address space for all standard resources + * + * This is called just before pcibios_init(), which is also a + * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). + */ +static int __init request_standard_resources(void) +{ + int i; + + printk("Setting up standard PCI resources\n"); + if (efi_enabled) + efi_initialize_iomem_resources(&code_resource, &data_resource); + else + legacy_init_iomem_resources(&code_resource, &data_resource); + + /* EFI systems may still have VGA */ + request_resource(&iomem_resource, &video_ram_resource); + + /* request I/O space for devices used on all i[345]86 PCs */ + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + request_resource(&ioport_resource, &standard_io_resources[i]); + return 0; +} + +subsys_initcall(request_standard_resources); + +static void __init register_memory(void) +{ + unsigned long gapstart, gapsize, round; + unsigned long long last; + int i; + + /* + * Search for the bigest gap in the low 32 bits of the e820 + * memory space. + */ + last = 0x100000000ull; + gapstart = 0x10000000; + gapsize = 0x400000; + i = e820.nr_map; + while (--i >= 0) { + unsigned long long start = e820.map[i].addr; + unsigned long long end = start + e820.map[i].size; + + /* + * Since "last" is at most 4GB, we know we'll + * fit in 32 bits if this condition is true + */ + if (last > end) { + unsigned long gap = last - end; + + if (gap > gapsize) { + gapsize = gap; + gapstart = end; + } + } + if (start < last) + last = start; + } + + /* + * See how much we want to round up: start off with + * rounding to the next 1MB area. + */ + round = 0x100000; + while ((gapsize >> 4) > round) + round += round; + /* Fun with two's complement */ + pci_mem_start = (gapstart + round) & -round; + + printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", + pci_mem_start, gapstart, gapsize); +} + #ifdef CONFIG_MCA static void set_mca_bus(int x) { @@ -494,12 +1329,6 @@ static void set_mca_bus(int x) static void set_mca_bus(int x) { } #endif -/* Overridden in paravirt.c if CONFIG_PARAVIRT */ -char * __attribute__((weak)) memory_setup(void) -{ - return machine_specific_memory_setup(); -} - /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -552,7 +1381,7 @@ void __init setup_arch(char **cmdline_p) efi_init(); else { printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - print_memory_map(memory_setup()); + print_memory_map(machine_specific_memory_setup()); } copy_edd(); diff --git a/trunk/arch/i386/kernel/signal.c b/trunk/arch/i386/kernel/signal.c index 65d7620eaa09..43002cfb40c4 100644 --- a/trunk/arch/i386/kernel/signal.c +++ b/trunk/arch/i386/kernel/signal.c @@ -128,7 +128,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax X86_EFLAGS_TF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \ X86_EFLAGS_AF | X86_EFLAGS_PF | X86_EFLAGS_CF) - COPY_SEG(gs); + GET_SEG(gs); GET_SEG(fs); COPY_SEG(es); COPY_SEG(ds); @@ -244,7 +244,9 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, { int tmp, err = 0; - err |= __put_user(regs->xgs, (unsigned int __user *)&sc->gs); + tmp = 0; + savesegment(gs, tmp); + err |= __put_user(tmp, (unsigned int __user *)&sc->gs); savesegment(fs, tmp); err |= __put_user(tmp, (unsigned int __user *)&sc->fs); diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index 5285aff8367f..31e5c6573aae 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -321,6 +321,7 @@ static inline void leave_mm (unsigned long cpu) fastcall void smp_invalidate_interrupt(struct pt_regs *regs) { + struct pt_regs *old_regs = set_irq_regs(regs); unsigned long cpu; cpu = get_cpu(); @@ -351,6 +352,7 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs) smp_mb__after_clear_bit(); out: put_cpu_no_resched(); + set_irq_regs(old_regs); } static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, @@ -605,11 +607,14 @@ void smp_send_stop(void) */ fastcall void smp_reschedule_interrupt(struct pt_regs *regs) { + struct pt_regs *old_regs = set_irq_regs(regs); ack_APIC_irq(); + set_irq_regs(old_regs); } fastcall void smp_call_function_interrupt(struct pt_regs *regs) { + struct pt_regs *old_regs = set_irq_regs(regs); void (*func) (void *info) = call_data->func; void *info = call_data->info; int wait = call_data->wait; @@ -632,6 +637,7 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs) mb(); atomic_inc(&call_data->finished); } + set_irq_regs(old_regs); } /* @@ -693,10 +699,6 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, put_cpu(); return -EBUSY; } - - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); - spin_lock_bh(&call_lock); __smp_call_function_single(cpu, func, info, nonatomic, wait); spin_unlock_bh(&call_lock); diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 4bf0e3c83b8b..02a9b66b6ac3 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -33,11 +33,6 @@ * Dave Jones : Report invalid combinations of Athlon CPUs. * Rusty Russell : Hacked into shape for new "hotplug" boot process. */ - -/* SMP boot always wants to use real time delay to allow sufficient time for - * the APs to come online */ -#define USE_REAL_TIME_DELAY - #include #include #include @@ -57,8 +52,6 @@ #include #include #include -#include -#include #include #include @@ -543,11 +536,11 @@ set_cpu_sibling_map(int cpu) static void __devinit start_secondary(void *unused) { /* - * Don't put *anything* before secondary_cpu_init(), SMP + * Dont put anything before smp_callin(), SMP * booting is too fragile that we want to limit the * things done here to the most necessary things. */ - secondary_cpu_init(); + cpu_init(); preempt_disable(); smp_callin(); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) @@ -606,16 +599,13 @@ void __devinit initialize_secondary(void) "movl %0,%%esp\n\t" "jmp *%1" : - :"m" (current->thread.esp),"m" (current->thread.eip)); + :"r" (current->thread.esp),"r" (current->thread.eip)); } -/* Static state in head.S used to set up a CPU */ extern struct { void * esp; unsigned short ss; } stack_start; -extern struct i386_pda *start_pda; -extern struct Xgt_desc_struct cpu_gdt_descr; #ifdef CONFIG_NUMA @@ -946,6 +936,9 @@ static int __devinit do_boot_cpu(int apicid, int cpu) unsigned long start_eip; unsigned short nmi_high = 0, nmi_low = 0; + ++cpucount; + alternatives_smp_switch(1); + /* * We can't use kernel_thread since we must avoid to * reschedule the child. @@ -953,30 +946,15 @@ static int __devinit do_boot_cpu(int apicid, int cpu) idle = alloc_idle_task(cpu); if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); - - /* Pre-allocate and initialize the CPU's GDT and PDA so it - doesn't have to do any memory allocation during the - delicate CPU-bringup phase. */ - if (!init_gdt(cpu, idle)) { - printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); - return -1; /* ? */ - } - idle->thread.eip = (unsigned long) start_secondary; /* start_eip had better be page-aligned! */ start_eip = setup_trampoline(); - ++cpucount; - alternatives_smp_switch(1); - /* So we see what's up */ printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); /* Stack for startup_32 can be just as for start_secondary onwards */ stack_start.esp = (void *) idle->thread.esp; - start_pda = cpu_pda(cpu); - cpu_gdt_descr = per_cpu(cpu_gdt_descr, cpu); - irq_ctx_init(cpu); x86_cpu_to_apicid[cpu] = apicid; @@ -1131,15 +1109,34 @@ static int __cpuinit __smp_prepare_cpu(int cpu) } #endif -static void smp_tune_scheduling(void) +static void smp_tune_scheduling (void) { unsigned long cachesize; /* kB */ + unsigned long bandwidth = 350; /* MB/s */ + /* + * Rough estimation for SMP scheduling, this is the number of + * cycles it takes for a fully memory-limited process to flush + * the SMP-local cache. + * + * (For a P5 this pretty much means we will choose another idle + * CPU almost always at wakeup time (this is due to the small + * L1 cache), on PIIs it's around 50-100 usecs, depending on + * the cache size) + */ - if (cpu_khz) { + if (!cpu_khz) { + /* + * this basically disables processor-affinity + * scheduling on SMP without a TSC. + */ + return; + } else { cachesize = boot_cpu_data.x86_cache_size; - - if (cachesize > 0) - max_cache_size = cachesize * 1024; + if (cachesize == -1) { + cachesize = 16; /* Pentiums, 2x8kB cache */ + bandwidth = 100; + } + max_cache_size = cachesize * 1024; } } @@ -1465,12 +1462,6 @@ int __devinit __cpu_up(unsigned int cpu) cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); - -#ifdef CONFIG_X86_GENERICARCH - if (num_online_cpus() > 8 && genapic == &apic_default) - panic("Default flat APIC routing can't be used with > 8 cpus\n"); -#endif - return 0; } diff --git a/trunk/arch/i386/kernel/sysenter.c b/trunk/arch/i386/kernel/sysenter.c index 7de9117b5a3a..713ba39d32c6 100644 --- a/trunk/arch/i386/kernel/sysenter.c +++ b/trunk/arch/i386/kernel/sysenter.c @@ -27,11 +27,7 @@ * Should the kernel map a VDSO page into processes and pass its * address down to glibc upon exec()? */ -#ifdef CONFIG_PARAVIRT -unsigned int __read_mostly vdso_enabled = 0; -#else unsigned int __read_mostly vdso_enabled = 1; -#endif EXPORT_SYMBOL_GPL(vdso_enabled); @@ -136,7 +132,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) goto up_fail; } - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); if (!vma) { ret = -ENOMEM; goto up_fail; diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index c505b16c0990..78af572fd17c 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -56,7 +56,6 @@ #include #include #include -#include #include "mach_time.h" @@ -117,7 +116,10 @@ static int set_rtc_mmss(unsigned long nowtime) /* gets recalled with irq locally disabled */ /* XXX - does irqsave resolve this? -johnstul */ spin_lock_irqsave(&rtc_lock, flags); - retval = set_wallclock(nowtime); + if (efi_enabled) + retval = efi_set_rtc_mmss(nowtime); + else + retval = mach_set_rtc_mmss(nowtime); spin_unlock_irqrestore(&rtc_lock, flags); return retval; @@ -221,7 +223,10 @@ unsigned long get_cmos_time(void) spin_lock_irqsave(&rtc_lock, flags); - retval = get_wallclock(); + if (efi_enabled) + retval = efi_get_time(); + else + retval = mach_get_cmos_time(); spin_unlock_irqrestore(&rtc_lock, flags); @@ -365,7 +370,7 @@ static void __init hpet_time_init(void) printk("Using HPET for base-timer\n"); } - do_time_init(); + time_init_hook(); } #endif @@ -387,5 +392,5 @@ void __init time_init(void) do_settimeofday(&ts); - do_time_init(); + time_init_hook(); } diff --git a/trunk/arch/i386/kernel/time_hpet.c b/trunk/arch/i386/kernel/time_hpet.c index 1e4702dfcd01..1a2a979cf6a3 100644 --- a/trunk/arch/i386/kernel/time_hpet.c +++ b/trunk/arch/i386/kernel/time_hpet.c @@ -132,20 +132,14 @@ int __init hpet_enable(void) * the single HPET timer for system time. */ #ifdef CONFIG_HPET_EMULATE_RTC - if (!(id & HPET_ID_NUMBER)) { - iounmap(hpet_virt_address); - hpet_virt_address = NULL; + if (!(id & HPET_ID_NUMBER)) return -1; - } #endif hpet_period = hpet_readl(HPET_PERIOD); - if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) { - iounmap(hpet_virt_address); - hpet_virt_address = NULL; + if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) return -1; - } /* * 64 bit math @@ -162,11 +156,8 @@ int __init hpet_enable(void) hpet_use_timer = id & HPET_ID_LEGSUP; - if (hpet_timer_stop_set_go(hpet_tick)) { - iounmap(hpet_virt_address); - hpet_virt_address = NULL; + if (hpet_timer_stop_set_go(hpet_tick)) return -1; - } use_hpet = 1; diff --git a/trunk/arch/i386/kernel/topology.c b/trunk/arch/i386/kernel/topology.c index 79cf608e14ca..07d6da36a825 100644 --- a/trunk/arch/i386/kernel/topology.c +++ b/trunk/arch/i386/kernel/topology.c @@ -40,18 +40,14 @@ int arch_register_cpu(int num) * restrictions and assumptions in kernel. This basically * doesnt add a control file, one cannot attempt to offline * BSP. - * - * Also certain PCI quirks require not to enable hotplug control - * for all CPU's. */ - if (num && enable_cpu_hotplug) - cpu_devices[num].cpu.hotpluggable = 1; + if (!num) + cpu_devices[num].cpu.no_control = 1; return register_cpu(&cpu_devices[num].cpu, num); } #ifdef CONFIG_HOTPLUG_CPU -int enable_cpu_hotplug = 1; void arch_unregister_cpu(int num) { return unregister_cpu(&cpu_devices[num].cpu); diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 68de48e498ca..fe9c5e8e7e6f 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -29,7 +29,6 @@ #include #include #include -#include #ifdef CONFIG_EISA #include @@ -62,6 +61,9 @@ int panic_on_unrecovered_nmi; asmlinkage int system_call(void); +struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 } }; + /* Do we ignore FPU interrupts ? */ char ignore_fpu_irq = 0; @@ -92,7 +94,7 @@ asmlinkage void alignment_check(void); asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); -int kstack_depth_to_print = 24; +static int kstack_depth_to_print = 24; #ifdef CONFIG_STACK_UNWIND static int call_trace = 1; #else @@ -161,25 +163,16 @@ dump_trace_unwind(struct unwind_frame_info *info, void *data) { struct ops_and_data *oad = (struct ops_and_data *)data; int n = 0; - unsigned long sp = UNW_SP(info); - if (arch_unw_user_mode(info)) - return -1; while (unwind(info) == 0 && UNW_PC(info)) { n++; oad->ops->address(oad->data, UNW_PC(info)); if (arch_unw_user_mode(info)) break; - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) - && sp > UNW_SP(info)) - break; - sp = UNW_SP(info); } return n; } -#define MSG(msg) ops->warning(data, msg) - void dump_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, struct stacktrace_ops *ops, void *data) @@ -198,31 +191,29 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (unwind_init_frame_info(&info, task, regs) == 0) unw_ret = dump_trace_unwind(&info, &oad); } else if (task == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, - &oad); + unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); else { if (unwind_init_blocked(&info, task) == 0) unw_ret = dump_trace_unwind(&info, &oad); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s", + ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if (UNW_SP(&info) >= PAGE_OFFSET) { - MSG("Leftover inexact backtrace:"); + ops->warning(data, "Leftover inexact backtrace:\n"); stack = (void *)UNW_SP(&info); if (!stack) return; ebp = UNW_FP(&info); } else - MSG("Full inexact backtrace again:"); + ops->warning(data, "Full inexact backtrace again:\n"); } else if (call_trace >= 1) return; else - MSG("Full inexact backtrace again:"); + ops->warning(data, "Full inexact backtrace again:\n"); } else - MSG("Inexact backtrace:"); + ops->warning(data, "Inexact backtrace:\n"); } if (!stack) { unsigned long dummy; @@ -256,7 +247,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, stack = (unsigned long*)context->previous_esp; if (!stack) break; - touch_nmi_watchdog(); } } EXPORT_SYMBOL(dump_trace); @@ -389,7 +379,7 @@ void show_registers(struct pt_regs *regs) * time of the fault.. */ if (in_kernel) { - u8 *eip; + u8 __user *eip; int code_bytes = 64; unsigned char c; @@ -398,20 +388,18 @@ void show_registers(struct pt_regs *regs) printk(KERN_EMERG "Code: "); - eip = (u8 *)regs->eip - 43; - if (eip < (u8 *)PAGE_OFFSET || - probe_kernel_address(eip, c)) { + eip = (u8 __user *)regs->eip - 43; + if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { /* try starting at EIP */ - eip = (u8 *)regs->eip; + eip = (u8 __user *)regs->eip; code_bytes = 32; } for (i = 0; i < code_bytes; i++, eip++) { - if (eip < (u8 *)PAGE_OFFSET || - probe_kernel_address(eip, c)) { + if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { printk(" Bad EIP value."); break; } - if (eip == (u8 *)regs->eip) + if (eip == (u8 __user *)regs->eip) printk("<%02x> ", c); else printk("%02x ", c); @@ -427,7 +415,7 @@ static void handle_BUG(struct pt_regs *regs) if (eip < PAGE_OFFSET) return; - if (probe_kernel_address((unsigned short *)eip, ud2)) + if (probe_kernel_address((unsigned short __user *)eip, ud2)) return; if (ud2 != 0x0b0f) return; @@ -440,11 +428,11 @@ static void handle_BUG(struct pt_regs *regs) char *file; char c; - if (probe_kernel_address((unsigned short *)(eip + 2), line)) + if (probe_kernel_address((unsigned short __user *)(eip + 2), + line)) break; - if (probe_kernel_address((char **)(eip + 4), file) || - (unsigned long)file < PAGE_OFFSET || - probe_kernel_address(file, c)) + if (__get_user(file, (char * __user *)(eip + 4)) || + (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) file = ""; printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); @@ -464,7 +452,7 @@ void die(const char * str, struct pt_regs * regs, long err) u32 lock_owner; int lock_owner_depth; } die = { - .lock = __SPIN_LOCK_UNLOCKED(die.lock), + .lock = SPIN_LOCK_UNLOCKED, .lock_owner = -1, .lock_owner_depth = 0 }; @@ -719,7 +707,8 @@ mem_parity_error(unsigned char reason, struct pt_regs * regs) { printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " "CPU %d.\n", reason, smp_processor_id()); - printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n"); + printk(KERN_EMERG "You probably have a hardware problem with your RAM " + "chips\n"); if (panic_on_unrecovered_nmi) panic("NMI: Not continuing"); @@ -784,6 +773,7 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg) printk(" on CPU%d, eip %08lx, registers:\n", smp_processor_id(), regs->eip); show_registers(regs); + printk(KERN_EMERG "console shuts up ...\n"); console_silent(); spin_unlock(&nmi_print_lock); bust_spinlocks(0); @@ -1098,24 +1088,49 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, #endif } -fastcall unsigned long patch_espfix_desc(unsigned long uesp, - unsigned long kesp) +fastcall void setup_x86_bogus_stack(unsigned char * stk) +{ + unsigned long *switch16_ptr, *switch32_ptr; + struct pt_regs *regs; + unsigned long stack_top, stack_bot; + unsigned short iret_frame16_off; + int cpu = smp_processor_id(); + /* reserve the space on 32bit stack for the magic switch16 pointer */ + memmove(stk, stk + 8, sizeof(struct pt_regs)); + switch16_ptr = (unsigned long *)(stk + sizeof(struct pt_regs)); + regs = (struct pt_regs *)stk; + /* now the switch32 on 16bit stack */ + stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); + stack_top = stack_bot + CPU_16BIT_STACK_SIZE; + switch32_ptr = (unsigned long *)(stack_top - 8); + iret_frame16_off = CPU_16BIT_STACK_SIZE - 8 - 20; + /* copy iret frame on 16bit stack */ + memcpy((void *)(stack_bot + iret_frame16_off), ®s->eip, 20); + /* fill in the switch pointers */ + switch16_ptr[0] = (regs->esp & 0xffff0000) | iret_frame16_off; + switch16_ptr[1] = __ESPFIX_SS; + switch32_ptr[0] = (unsigned long)stk + sizeof(struct pt_regs) + + 8 - CPU_16BIT_STACK_SIZE; + switch32_ptr[1] = __KERNEL_DS; +} + +fastcall unsigned char * fixup_x86_bogus_stack(unsigned short sp) { + unsigned long *switch32_ptr; + unsigned char *stack16, *stack32; + unsigned long stack_top, stack_bot; + int len; int cpu = smp_processor_id(); - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); - struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address; - unsigned long base = (kesp - uesp) & -THREAD_SIZE; - unsigned long new_kesp = kesp - base; - unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; - __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; - /* Set up base for espfix segment */ - desc &= 0x00f0ff0000000000ULL; - desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) | - ((((__u64)base) << 32) & 0xff00000000000000ULL) | - ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) | - (lim_pages & 0xffff); - *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc; - return new_kesp; + stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); + stack_top = stack_bot + CPU_16BIT_STACK_SIZE; + switch32_ptr = (unsigned long *)(stack_top - 8); + /* copy the data from 16bit stack to 32bit stack */ + len = CPU_16BIT_STACK_SIZE - 8 - sp; + stack16 = (unsigned char *)(stack_bot + sp); + stack32 = (unsigned char *) + (switch32_ptr[0] + CPU_16BIT_STACK_SIZE - 8 - len); + memcpy(stack32, stack16, len); + return stack32; } /* @@ -1128,7 +1143,7 @@ fastcall unsigned long patch_espfix_desc(unsigned long uesp, * Must be called with kernel preemption disabled (in this case, * local interrupts are disabled at the call-site in entry.S). */ -asmlinkage void math_state_restore(void) +asmlinkage void math_state_restore(struct pt_regs regs) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = thread->task; @@ -1138,7 +1153,6 @@ asmlinkage void math_state_restore(void) init_fpu(tsk); restore_fpu(tsk); thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ - tsk->fpu_counter++; } #ifndef CONFIG_MATH_EMULATION diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c index 1bbe45dca7a0..9810c8c90750 100644 --- a/trunk/arch/i386/kernel/tsc.c +++ b/trunk/arch/i386/kernel/tsc.c @@ -13,6 +13,7 @@ #include #include +#include #include #include "mach_timer.h" diff --git a/trunk/arch/i386/kernel/vm86.c b/trunk/arch/i386/kernel/vm86.c index be2f96e67f78..cbcd61d6120b 100644 --- a/trunk/arch/i386/kernel/vm86.c +++ b/trunk/arch/i386/kernel/vm86.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -73,10 +72,10 @@ /* * 8- and 16-bit register defines.. */ -#define AL(regs) (((unsigned char *)&((regs)->pt.eax))[0]) -#define AH(regs) (((unsigned char *)&((regs)->pt.eax))[1]) -#define IP(regs) (*(unsigned short *)&((regs)->pt.eip)) -#define SP(regs) (*(unsigned short *)&((regs)->pt.esp)) +#define AL(regs) (((unsigned char *)&((regs)->eax))[0]) +#define AH(regs) (((unsigned char *)&((regs)->eax))[1]) +#define IP(regs) (*(unsigned short *)&((regs)->eip)) +#define SP(regs) (*(unsigned short *)&((regs)->esp)) /* * virtual flags (16 and 32-bit versions) @@ -90,37 +89,10 @@ #define SAFE_MASK (0xDD5) #define RETURN_MASK (0xDFF) -/* convert kernel_vm86_regs to vm86_regs */ -static int copy_vm86_regs_to_user(struct vm86_regs __user *user, - const struct kernel_vm86_regs *regs) -{ - int ret = 0; - - /* kernel_vm86_regs is missing xfs, so copy everything up to - (but not including) xgs, and then rest after xgs. */ - ret += copy_to_user(user, regs, offsetof(struct kernel_vm86_regs, pt.xgs)); - ret += copy_to_user(&user->__null_gs, ®s->pt.xgs, - sizeof(struct kernel_vm86_regs) - - offsetof(struct kernel_vm86_regs, pt.xgs)); - - return ret; -} - -/* convert vm86_regs to kernel_vm86_regs */ -static int copy_vm86_regs_from_user(struct kernel_vm86_regs *regs, - const struct vm86_regs __user *user, - unsigned extra) -{ - int ret = 0; - - ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.xgs)); - ret += copy_from_user(®s->pt.xgs, &user->__null_gs, - sizeof(struct kernel_vm86_regs) - - offsetof(struct kernel_vm86_regs, pt.xgs) + - extra); - - return ret; -} +#define VM86_REGS_PART2 orig_eax +#define VM86_REGS_SIZE1 \ + ( (unsigned)( & (((struct kernel_vm86_regs *)0)->VM86_REGS_PART2) ) ) +#define VM86_REGS_SIZE2 (sizeof(struct kernel_vm86_regs) - VM86_REGS_SIZE1) struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) @@ -140,8 +112,10 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) printk("no vm86_info: BAD\n"); do_exit(SIGSEGV); } - set_flags(regs->pt.eflags, VEFLAGS, VIF_MASK | current->thread.v86mask); - tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs,regs); + set_flags(regs->eflags, VEFLAGS, VIF_MASK | current->thread.v86mask); + tmp = copy_to_user(¤t->thread.vm86_info->regs,regs, VM86_REGS_SIZE1); + tmp += copy_to_user(¤t->thread.vm86_info->regs.VM86_REGS_PART2, + ®s->VM86_REGS_PART2, VM86_REGS_SIZE2); tmp += put_user(current->thread.screen_bitmap,¤t->thread.vm86_info->screen_bitmap); if (tmp) { printk("vm86: could not access userspace vm86_info\n"); @@ -155,11 +129,9 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) current->thread.saved_esp0 = 0; put_cpu(); - ret = KVM86->regs32; - loadsegment(fs, current->thread.saved_fs); - ret->xgs = current->thread.saved_gs; - + loadsegment(gs, current->thread.saved_gs); + ret = KVM86->regs32; return ret; } @@ -211,9 +183,9 @@ asmlinkage int sys_vm86old(struct pt_regs regs) tsk = current; if (tsk->thread.saved_esp0) goto out; - tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, - offsetof(struct kernel_vm86_struct, vm86plus) - - sizeof(info.regs)); + tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); + tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, + (long)&info.vm86plus - (long)&info.regs.VM86_REGS_PART2); ret = -EFAULT; if (tmp) goto out; @@ -261,9 +233,9 @@ asmlinkage int sys_vm86(struct pt_regs regs) if (tsk->thread.saved_esp0) goto out; v86 = (struct vm86plus_struct __user *)regs.ecx; - tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, - offsetof(struct kernel_vm86_struct, regs32) - - sizeof(info.regs)); + tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); + tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, + (long)&info.regs32 - (long)&info.regs.VM86_REGS_PART2); ret = -EFAULT; if (tmp) goto out; @@ -280,15 +252,15 @@ asmlinkage int sys_vm86(struct pt_regs regs) static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) { struct tss_struct *tss; + long eax; /* * make sure the vm86() system call doesn't try to do anything silly */ - info->regs.pt.xds = 0; - info->regs.pt.xes = 0; - info->regs.pt.xgs = 0; + info->regs.__null_ds = 0; + info->regs.__null_es = 0; -/* we are clearing fs later just before "jmp resume_userspace", - * because it is not saved/restored. +/* we are clearing fs,gs later just before "jmp resume_userspace", + * because starting with Linux 2.1.x they aren't no longer saved/restored */ /* @@ -296,10 +268,10 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk * has set it up safely, so this makes sure interrupt etc flags are * inherited from protected mode. */ - VEFLAGS = info->regs.pt.eflags; - info->regs.pt.eflags &= SAFE_MASK; - info->regs.pt.eflags |= info->regs32->eflags & ~SAFE_MASK; - info->regs.pt.eflags |= VM_MASK; + VEFLAGS = info->regs.eflags; + info->regs.eflags &= SAFE_MASK; + info->regs.eflags |= info->regs32->eflags & ~SAFE_MASK; + info->regs.eflags |= VM_MASK; switch (info->cpu_type) { case CPU_286: @@ -322,7 +294,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk info->regs32->eax = 0; tsk->thread.saved_esp0 = tsk->thread.esp0; savesegment(fs, tsk->thread.saved_fs); - tsk->thread.saved_gs = info->regs32->xgs; + savesegment(gs, tsk->thread.saved_gs); tss = &per_cpu(init_tss, get_cpu()); tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; @@ -334,18 +306,19 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP) mark_screen_rdonly(tsk->mm); + __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t"); + __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax)); /*call audit_syscall_exit since we do not exit via the normal paths */ if (unlikely(current->audit_context)) - audit_syscall_exit(AUDITSC_RESULT(0), 0); + audit_syscall_exit(AUDITSC_RESULT(eax), eax); __asm__ __volatile__( "movl %0,%%esp\n\t" "movl %1,%%ebp\n\t" - "mov %2, %%fs\n\t" "jmp resume_userspace" : /* no outputs */ - :"r" (&info->regs), "r" (task_thread_info(tsk)), "r" (0)); + :"r" (&info->regs), "r" (task_thread_info(tsk))); /* we never return here */ } @@ -375,12 +348,12 @@ static inline void clear_IF(struct kernel_vm86_regs * regs) static inline void clear_TF(struct kernel_vm86_regs * regs) { - regs->pt.eflags &= ~TF_MASK; + regs->eflags &= ~TF_MASK; } static inline void clear_AC(struct kernel_vm86_regs * regs) { - regs->pt.eflags &= ~AC_MASK; + regs->eflags &= ~AC_MASK; } /* It is correct to call set_IF(regs) from the set_vflags_* @@ -397,7 +370,7 @@ static inline void clear_AC(struct kernel_vm86_regs * regs) static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs) { set_flags(VEFLAGS, eflags, current->thread.v86mask); - set_flags(regs->pt.eflags, eflags, SAFE_MASK); + set_flags(regs->eflags, eflags, SAFE_MASK); if (eflags & IF_MASK) set_IF(regs); else @@ -407,7 +380,7 @@ static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs) { set_flags(VFLAGS, flags, current->thread.v86mask); - set_flags(regs->pt.eflags, flags, SAFE_MASK); + set_flags(regs->eflags, flags, SAFE_MASK); if (flags & IF_MASK) set_IF(regs); else @@ -416,7 +389,7 @@ static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_reg static inline unsigned long get_vflags(struct kernel_vm86_regs * regs) { - unsigned long flags = regs->pt.eflags & RETURN_MASK; + unsigned long flags = regs->eflags & RETURN_MASK; if (VEFLAGS & VIF_MASK) flags |= IF_MASK; @@ -520,7 +493,7 @@ static void do_int(struct kernel_vm86_regs *regs, int i, unsigned long __user *intr_ptr; unsigned long segoffs; - if (regs->pt.xcs == BIOSSEG) + if (regs->cs == BIOSSEG) goto cannot_handle; if (is_revectored(i, &KVM86->int_revectored)) goto cannot_handle; @@ -532,9 +505,9 @@ static void do_int(struct kernel_vm86_regs *regs, int i, if ((segoffs >> 16) == BIOSSEG) goto cannot_handle; pushw(ssp, sp, get_vflags(regs), cannot_handle); - pushw(ssp, sp, regs->pt.xcs, cannot_handle); + pushw(ssp, sp, regs->cs, cannot_handle); pushw(ssp, sp, IP(regs), cannot_handle); - regs->pt.xcs = segoffs >> 16; + regs->cs = segoffs >> 16; SP(regs) -= 6; IP(regs) = segoffs & 0xffff; clear_TF(regs); @@ -551,7 +524,7 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno if (VMPI.is_vm86pus) { if ( (trapno==3) || (trapno==1) ) return_to_32bit(regs, VM86_TRAP + (trapno << 8)); - do_int(regs, trapno, (unsigned char __user *) (regs->pt.xss << 4), SP(regs)); + do_int(regs, trapno, (unsigned char __user *) (regs->ss << 4), SP(regs)); return 0; } if (trapno !=1) @@ -587,10 +560,10 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) handle_vm86_trap(regs, 0, 1); \ return; } while (0) - orig_flags = *(unsigned short *)®s->pt.eflags; + orig_flags = *(unsigned short *)®s->eflags; - csp = (unsigned char __user *) (regs->pt.xcs << 4); - ssp = (unsigned char __user *) (regs->pt.xss << 4); + csp = (unsigned char __user *) (regs->cs << 4); + ssp = (unsigned char __user *) (regs->ss << 4); sp = SP(regs); ip = IP(regs); @@ -677,7 +650,7 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) SP(regs) += 6; } IP(regs) = newip; - regs->pt.xcs = newcs; + regs->cs = newcs; CHECK_IF_IN_TRAP; if (data32) { set_vflags_long(newflags, regs); diff --git a/trunk/arch/i386/kernel/vmlinux.lds.S b/trunk/arch/i386/kernel/vmlinux.lds.S index 56e6ad5cb045..c6f84a0322ba 100644 --- a/trunk/arch/i386/kernel/vmlinux.lds.S +++ b/trunk/arch/i386/kernel/vmlinux.lds.S @@ -1,26 +1,13 @@ /* ld script to make i386 Linux kernel * Written by Martin Mares ; - * - * Don't define absolute symbols until and unless you know that symbol - * value is should remain constant even if kernel image is relocated - * at run time. Absolute symbols are not relocated. If symbol value should - * change if kernel is relocated, make the symbol section relative and - * put it inside the section definition. */ -/* Don't define absolute symbols until and unless you know that symbol - * value is should remain constant even if kernel image is relocated - * at run time. Absolute symbols are not relocated. If symbol value should - * change if kernel is relocated, make the symbol section relative and - * put it inside the section definition. - */ #define LOAD_OFFSET __PAGE_OFFSET #include #include #include #include -#include OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) @@ -34,35 +21,34 @@ PHDRS { } SECTIONS { - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; + . = __KERNEL_START; phys_startup_32 = startup_32 - LOAD_OFFSET; /* read-only */ + _text = .; /* Text and read-only data */ .text : AT(ADDR(.text) - LOAD_OFFSET) { - _text = .; /* Text and read-only data */ *(.text) SCHED_TEXT LOCK_TEXT KPROBES_TEXT *(.fixup) *(.gnu.warning) - _etext = .; /* End of text section */ - } :text = 0x9090 + } :text = 0x9090 + + _etext = .; /* End of text section */ . = ALIGN(16); /* Exception table */ - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } + __start___ex_table = .; + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } + __stop___ex_table = .; RODATA . = ALIGN(4); + __tracedata_start = .; .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { - __tracedata_start = .; *(.tracedata) - __tracedata_end = .; } + __tracedata_end = .; /* writeable */ . = ALIGN(4096); @@ -71,19 +57,11 @@ SECTIONS CONSTRUCTORS } :data - .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) { - __start_paravirtprobe = .; - *(.paravirtprobe) - __stop_paravirtprobe = .; - } - . = ALIGN(4096); - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { - __nosave_begin = .; - *(.data.nosave) - . = ALIGN(4096); - __nosave_end = .; - } + __nosave_begin = .; + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; . = ALIGN(4096); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { @@ -97,10 +75,17 @@ SECTIONS /* rarely changed data like cpu maps */ . = ALIGN(32); - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { - *(.data.read_mostly) - _edata = .; /* End of data section */ + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } + _edata = .; /* End of data section */ + +#ifdef CONFIG_STACK_UNWIND + . = ALIGN(4); + .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { + __start_unwind = .; + *(.eh_frame) + __end_unwind = .; } +#endif . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { @@ -109,102 +94,88 @@ SECTIONS /* might get freed after init */ . = ALIGN(4096); + __smp_alt_begin = .; + __smp_alt_instructions = .; .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { - __smp_alt_begin = .; - __smp_alt_instructions = .; *(.smp_altinstructions) - __smp_alt_instructions_end = .; } + __smp_alt_instructions_end = .; . = ALIGN(4); + __smp_locks = .; .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { - __smp_locks = .; *(.smp_locks) - __smp_locks_end = .; } + __smp_locks_end = .; .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { *(.smp_altinstr_replacement) - __smp_alt_end = .; } - /* will be freed after init - * Following ALIGN() is required to make sure no other data falls on the - * same page where __smp_alt_end is pointing as that page might be freed - * after boot. Always make sure that ALIGN() directive is present after - * the section which contains __smp_alt_end. - */ . = ALIGN(4096); + __smp_alt_end = .; /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ + __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { - __init_begin = .; _sinittext = .; *(.init.text) _einittext = .; } .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } . = ALIGN(16); - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } + __setup_start = .; + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } + __setup_end = .; + __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - __initcall_start = .; INITCALLS - __initcall_end = .; } + __initcall_end = .; + __con_initcall_start = .; .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { - __con_initcall_start = .; *(.con_initcall.init) - __con_initcall_end = .; } + __con_initcall_end = .; SECURITY_INIT . = ALIGN(4); + __alt_instructions = .; .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { - __alt_instructions = .; *(.altinstructions) - __alt_instructions_end = .; } + __alt_instructions_end = .; .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { *(.altinstr_replacement) } - . = ALIGN(4); - .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { - __start_parainstructions = .; - *(.parainstructions) - __stop_parainstructions = .; - } /* .exit.text is discard at runtime, not link time, to deal with references from .altinstructions and .eh_frame */ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } . = ALIGN(4096); - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } + __initramfs_start = .; + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } + __initramfs_end = .; . = ALIGN(L1_CACHE_BYTES); - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { - __per_cpu_start = .; - *(.data.percpu) - __per_cpu_end = .; - } + __per_cpu_start = .; + .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } + __per_cpu_end = .; . = ALIGN(4096); + __init_end = .; /* freed after init ends here */ - .bss : AT(ADDR(.bss) - LOAD_OFFSET) { - __init_end = .; - __bss_start = .; /* BSS */ + __bss_start = .; /* BSS */ + .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) { *(.bss.page_aligned) + } + .bss : AT(ADDR(.bss) - LOAD_OFFSET) { *(.bss) - . = ALIGN(4); - __bss_stop = .; - _end = . ; - /* This is where the kernel creates the early boot page tables */ - . = ALIGN(4096); - pg0 = . ; } + . = ALIGN(4); + __bss_stop = .; + + _end = . ; + + /* This is where the kernel creates the early boot page tables */ + . = ALIGN(4096); + pg0 = .; /* Sections to be discarded */ /DISCARD/ : { diff --git a/trunk/arch/i386/mach-generic/probe.c b/trunk/arch/i386/mach-generic/probe.c index a7b3999bb37a..94b1fd9cbe3c 100644 --- a/trunk/arch/i386/mach-generic/probe.c +++ b/trunk/arch/i386/mach-generic/probe.c @@ -45,9 +45,7 @@ static int __init parse_apic(char *arg) return 0; } } - - /* Parsed again by __setup for debug/verbose */ - return 0; + return -ENOENT; } early_param("apic", parse_apic); diff --git a/trunk/arch/i386/mach-voyager/voyager_cat.c b/trunk/arch/i386/mach-voyager/voyager_cat.c index 943a9473b138..f50c6c6ad680 100644 --- a/trunk/arch/i386/mach-voyager/voyager_cat.c +++ b/trunk/arch/i386/mach-voyager/voyager_cat.c @@ -776,7 +776,7 @@ voyager_cat_init(void) for(asic=0; asic < (*modpp)->num_asics; asic++) { int j; voyager_asic_t *asicp = *asicpp - = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++];*/ + = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++];*/ voyager_sp_table_t *sp_table; voyager_at_t *asic_table; voyager_jtt_t *jtag_table; @@ -785,6 +785,7 @@ voyager_cat_init(void) printk("**WARNING** kmalloc failure in cat_init\n"); continue; } + memset(asicp, 0, sizeof(voyager_asic_t)); asicpp = &(asicp->next); asicp->asic_location = asic; sp_table = (voyager_sp_table_t *)(eprom_buf + sp_offset); @@ -850,7 +851,8 @@ voyager_cat_init(void) #endif { - struct resource *res = kzalloc(sizeof(struct resource),GFP_KERNEL); + struct resource *res = kmalloc(sizeof(struct resource),GFP_KERNEL); + memset(res, 0, sizeof(struct resource)); res->name = kmalloc(128, GFP_KERNEL); sprintf((char *)res->name, "Voyager %s Quad CPI", cat_module_name(i)); res->start = qic_addr; diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 55428e656a3f..f3fea2ad50fe 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -28,7 +28,6 @@ #include #include #include -#include /* TLB state -- visible externally, indexed physically */ DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 }; @@ -423,7 +422,6 @@ find_smp_config(void) VOYAGER_SUS_IN_CONTROL_PORT); current_thread_info()->cpu = boot_cpu_id; - write_pda(cpu_number, boot_cpu_id); } /* @@ -460,7 +458,7 @@ start_secondary(void *unused) /* external functions not defined in the headers */ extern void calibrate_delay(void); - secondary_cpu_init(); + cpu_init(); /* OK, we're in the routine */ ack_CPI(VIC_CPU_BOOT_CPI); @@ -580,15 +578,6 @@ do_boot_cpu(__u8 cpu) /* init_tasks (in sched.c) is indexed logically */ stack_start.esp = (void *) idle->thread.esp; - /* Pre-allocate and initialize the CPU's GDT and PDA so it - doesn't have to do any memory allocation during the - delicate CPU-bringup phase. */ - if (!init_gdt(cpu, idle)) { - printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); - cpucount--; - return; - } - irq_ctx_init(cpu); /* Note: Don't modify initial ss override */ @@ -1974,5 +1963,4 @@ void __init smp_setup_processor_id(void) { current_thread_info()->cpu = hard_smp_processor_id(); - write_pda(cpu_number, hard_smp_processor_id()); } diff --git a/trunk/arch/i386/math-emu/fpu_emu.h b/trunk/arch/i386/math-emu/fpu_emu.h index 65120f523853..d62b20a3e660 100644 --- a/trunk/arch/i386/math-emu/fpu_emu.h +++ b/trunk/arch/i386/math-emu/fpu_emu.h @@ -57,7 +57,6 @@ #define TAG_Special Const(2) /* De-normal, + or - infinity, or Not a Number */ #define TAG_Empty Const(3) /* empty */ -#define TAG_Error Const(0x80) /* probably need to abort */ #define LOADED_DATA Const(10101) /* Special st() number to identify loaded data (not on stack). */ diff --git a/trunk/arch/i386/math-emu/fpu_entry.c b/trunk/arch/i386/math-emu/fpu_entry.c index ddf8fa3bbd01..d93f16ef828f 100644 --- a/trunk/arch/i386/math-emu/fpu_entry.c +++ b/trunk/arch/i386/math-emu/fpu_entry.c @@ -742,8 +742,7 @@ int save_i387_soft(void *s387, struct _fpstate __user * buf) S387->fcs &= ~0xf8000000; S387->fos |= 0xffff0000; #endif /* PECULIAR_486 */ - if (__copy_to_user(d, &S387->cwd, 7*4)) - return -1; + __copy_to_user(d, &S387->cwd, 7*4); RE_ENTRANT_CHECK_ON; d += 7*4; diff --git a/trunk/arch/i386/math-emu/fpu_system.h b/trunk/arch/i386/math-emu/fpu_system.h index a3ae28c49ddd..bf26341c8bde 100644 --- a/trunk/arch/i386/math-emu/fpu_system.h +++ b/trunk/arch/i386/math-emu/fpu_system.h @@ -68,7 +68,6 @@ #define FPU_access_ok(x,y,z) if ( !access_ok(x,y,z) ) \ math_abort(FPU_info,SIGSEGV) -#define FPU_abort math_abort(FPU_info, SIGSEGV) #undef FPU_IGNORE_CODE_SEGV #ifdef FPU_IGNORE_CODE_SEGV diff --git a/trunk/arch/i386/math-emu/load_store.c b/trunk/arch/i386/math-emu/load_store.c index eebd6fb1c8a8..85314be2fef8 100644 --- a/trunk/arch/i386/math-emu/load_store.c +++ b/trunk/arch/i386/math-emu/load_store.c @@ -227,8 +227,6 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes, case 027: /* fild m64int */ clear_C1(); loaded_tag = FPU_load_int64((long long __user *)data_address); - if (loaded_tag == TAG_Error) - return 0; FPU_settag0(loaded_tag); break; case 030: /* fstenv m14/28byte */ diff --git a/trunk/arch/i386/math-emu/reg_ld_str.c b/trunk/arch/i386/math-emu/reg_ld_str.c index e976caef6498..f06ed41d191d 100644 --- a/trunk/arch/i386/math-emu/reg_ld_str.c +++ b/trunk/arch/i386/math-emu/reg_ld_str.c @@ -244,8 +244,7 @@ int FPU_load_int64(long long __user *_s) RE_ENTRANT_CHECK_OFF; FPU_access_ok(VERIFY_READ, _s, 8); - if (copy_from_user(&s,_s,8)) - FPU_abort; + copy_from_user(&s,_s,8); RE_ENTRANT_CHECK_ON; if (s == 0) @@ -908,8 +907,7 @@ int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d) RE_ENTRANT_CHECK_OFF; FPU_access_ok(VERIFY_WRITE,d,8); - if (copy_to_user(d, &tll, 8)) - FPU_abort; + copy_to_user(d, &tll, 8); RE_ENTRANT_CHECK_ON; return 1; @@ -1338,8 +1336,7 @@ u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d) I387.soft.fcs &= ~0xf8000000; I387.soft.fos |= 0xffff0000; #endif /* PECULIAR_486 */ - if (__copy_to_user(d, &control_word, 7*4)) - FPU_abort; + __copy_to_user(d, &control_word, 7*4); RE_ENTRANT_CHECK_ON; d += 0x1c; } @@ -1362,11 +1359,9 @@ void fsave(fpu_addr_modes addr_modes, u_char __user *data_address) FPU_access_ok(VERIFY_WRITE,d,80); /* Copy all registers in stack order. */ - if (__copy_to_user(d, register_base+offset, other)) - FPU_abort; + __copy_to_user(d, register_base+offset, other); if ( offset ) - if (__copy_to_user(d+other, register_base, offset)) - FPU_abort; + __copy_to_user(d+other, register_base, offset); RE_ENTRANT_CHECK_ON; finit(); diff --git a/trunk/arch/i386/mm/boot_ioremap.c b/trunk/arch/i386/mm/boot_ioremap.c index 4de95a17a7d4..4de11f508c3a 100644 --- a/trunk/arch/i386/mm/boot_ioremap.c +++ b/trunk/arch/i386/mm/boot_ioremap.c @@ -16,7 +16,6 @@ */ #undef CONFIG_X86_PAE -#undef CONFIG_PARAVIRT #include #include #include diff --git a/trunk/arch/i386/mm/discontig.c b/trunk/arch/i386/mm/discontig.c index 103b76e56a94..ddbdb0336f28 100644 --- a/trunk/arch/i386/mm/discontig.c +++ b/trunk/arch/i386/mm/discontig.c @@ -168,7 +168,7 @@ static void __init allocate_pgdat(int nid) if (nid && node_has_online_mem(nid)) NODE_DATA(nid) = (pg_data_t *)node_remap_start_vaddr[nid]; else { - NODE_DATA(nid) = (pg_data_t *)(pfn_to_kaddr(min_low_pfn)); + NODE_DATA(nid) = (pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT)); min_low_pfn += PFN_UP(sizeof(pg_data_t)); } } diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index aaaa4d225f7e..2581575786c1 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -22,9 +22,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -167,7 +167,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, static int __is_prefetch(struct pt_regs *regs, unsigned long addr) { unsigned long limit; - unsigned char *instr = (unsigned char *)get_segment_eip (regs, &limit); + unsigned long instr = get_segment_eip (regs, &limit); int scan_more = 1; int prefetch = 0; int i; @@ -177,9 +177,9 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) unsigned char instr_hi; unsigned char instr_lo; - if (instr > (unsigned char *)limit) + if (instr > limit) break; - if (probe_kernel_address(instr, opcode)) + if (__get_user(opcode, (unsigned char __user *) instr)) break; instr_hi = opcode & 0xf0; @@ -204,9 +204,9 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) case 0x00: /* Prefetch instruction is 0x0F0D or 0x0F18 */ scan_more = 0; - if (instr > (unsigned char *)limit) + if (instr > limit) break; - if (probe_kernel_address(instr, opcode)) + if (__get_user(opcode, (unsigned char __user *) instr)) break; prefetch = (instr_lo == 0xF) && (opcode == 0x0D || opcode == 0x18); diff --git a/trunk/arch/i386/mm/highmem.c b/trunk/arch/i386/mm/highmem.c index e0fa6cb655a8..f9f647cdbc7b 100644 --- a/trunk/arch/i386/mm/highmem.c +++ b/trunk/arch/i386/mm/highmem.c @@ -32,7 +32,7 @@ void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - pagefault_disable(); + inc_preempt_count(); if (!PageHighMem(page)) return page_address(page); @@ -50,22 +50,26 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); +#ifdef CONFIG_DEBUG_HIGHMEM + if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { + dec_preempt_count(); + preempt_check_resched(); + return; + } + + if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) + BUG(); +#endif /* * Force other mappings to Oops if they'll try to access this pte * without first remap it. Keeping stale mappings around is a bad idea * also, in case the page changes cacheability attributes or becomes * a protected page in a hypervisor. */ - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) - kpte_clear_flush(kmap_pte-idx, vaddr); - else { -#ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(vaddr < PAGE_OFFSET); - BUG_ON(vaddr >= (unsigned long)high_memory); -#endif - } + kpte_clear_flush(kmap_pte-idx, vaddr); - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); } /* This is the same as kmap_atomic() but can map memory that doesn't @@ -76,7 +80,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) enum fixed_addresses idx; unsigned long vaddr; - pagefault_disable(); + inc_preempt_count(); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/trunk/arch/i386/mm/hugetlbpage.c b/trunk/arch/i386/mm/hugetlbpage.c index 34728e4afe48..1719a8141f81 100644 --- a/trunk/arch/i386/mm/hugetlbpage.c +++ b/trunk/arch/i386/mm/hugetlbpage.c @@ -17,113 +17,6 @@ #include #include -static unsigned long page_table_shareable(struct vm_area_struct *svma, - struct vm_area_struct *vma, - unsigned long addr, pgoff_t idx) -{ - unsigned long saddr = ((idx - svma->vm_pgoff) << PAGE_SHIFT) + - svma->vm_start; - unsigned long sbase = saddr & PUD_MASK; - unsigned long s_end = sbase + PUD_SIZE; - - /* - * match the virtual addresses, permission and the alignment of the - * page table page. - */ - if (pmd_index(addr) != pmd_index(saddr) || - vma->vm_flags != svma->vm_flags || - sbase < svma->vm_start || svma->vm_end < s_end) - return 0; - - return saddr; -} - -static int vma_shareable(struct vm_area_struct *vma, unsigned long addr) -{ - unsigned long base = addr & PUD_MASK; - unsigned long end = base + PUD_SIZE; - - /* - * check on proper vm_flags and page table alignment - */ - if (vma->vm_flags & VM_MAYSHARE && - vma->vm_start <= base && end <= vma->vm_end) - return 1; - return 0; -} - -/* - * search for a shareable pmd page for hugetlb. - */ -static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) -{ - struct vm_area_struct *vma = find_vma(mm, addr); - struct address_space *mapping = vma->vm_file->f_mapping; - pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) + - vma->vm_pgoff; - struct prio_tree_iter iter; - struct vm_area_struct *svma; - unsigned long saddr; - pte_t *spte = NULL; - - if (!vma_shareable(vma, addr)) - return; - - spin_lock(&mapping->i_mmap_lock); - vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) { - if (svma == vma) - continue; - - saddr = page_table_shareable(svma, vma, addr, idx); - if (saddr) { - spte = huge_pte_offset(svma->vm_mm, saddr); - if (spte) { - get_page(virt_to_page(spte)); - break; - } - } - } - - if (!spte) - goto out; - - spin_lock(&mm->page_table_lock); - if (pud_none(*pud)) - pud_populate(mm, pud, (unsigned long) spte & PAGE_MASK); - else - put_page(virt_to_page(spte)); - spin_unlock(&mm->page_table_lock); -out: - spin_unlock(&mapping->i_mmap_lock); -} - -/* - * unmap huge page backed by shared pte. - * - * Hugetlb pte page is ref counted at the time of mapping. If pte is shared - * indicated by page_count > 1, unmap is achieved by clearing pud and - * decrementing the ref count. If count == 1, the pte page is not shared. - * - * called with vma->vm_mm->page_table_lock held. - * - * returns: 1 successfully unmapped a shared pte page - * 0 the underlying pte page is not shared, or it is the last user - */ -int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) -{ - pgd_t *pgd = pgd_offset(mm, *addr); - pud_t *pud = pud_offset(pgd, *addr); - - BUG_ON(page_count(virt_to_page(ptep)) == 0); - if (page_count(virt_to_page(ptep)) == 1) - return 0; - - pud_clear(pud); - put_page(virt_to_page(ptep)); - *addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE; - return 1; -} - pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; @@ -132,11 +25,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); - if (pud) { - if (pud_none(*pud)) - huge_pmd_share(mm, addr, pud); + if (pud) pte = (pte_t *) pmd_alloc(mm, pud, addr); - } BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte)); return pte; diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index 84697dfc7348..167416155ee4 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -192,6 +192,8 @@ static inline int page_kills_ppro(unsigned long pagenr) return 0; } +extern int is_available_memory(efi_memory_desc_t *); + int page_is_ram(unsigned long pagenr) { int i; @@ -697,8 +699,8 @@ int remove_memory(u64 start, u64 size) #endif #endif -struct kmem_cache *pgd_cache; -struct kmem_cache *pmd_cache; +kmem_cache_t *pgd_cache; +kmem_cache_t *pmd_cache; void __init pgtable_cache_init(void) { diff --git a/trunk/arch/i386/mm/pageattr.c b/trunk/arch/i386/mm/pageattr.c index ad91528bdc14..8564b6ae17e3 100644 --- a/trunk/arch/i386/mm/pageattr.c +++ b/trunk/arch/i386/mm/pageattr.c @@ -67,17 +67,11 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, return base; } -static void flush_kernel_map(void *arg) +static void flush_kernel_map(void *dummy) { - unsigned long adr = (unsigned long)arg; - - if (adr && cpu_has_clflush) { - int i; - for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) - asm volatile("clflush (%0)" :: "r" (adr + i)); - } else if (boot_cpu_data.x86_model >= 4) + /* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */ + if (boot_cpu_data.x86_model >= 4) wbinvd(); - /* Flush all to work around Errata in early athlons regarding * large page flushing. */ @@ -179,9 +173,9 @@ __change_page_attr(struct page *page, pgprot_t prot) return 0; } -static inline void flush_map(void *adr) +static inline void flush_map(void) { - on_each_cpu(flush_kernel_map, adr, 1, 1); + on_each_cpu(flush_kernel_map, NULL, 1, 1); } /* @@ -223,13 +217,9 @@ void global_flush_tlb(void) spin_lock_irq(&cpa_lock); list_replace_init(&df_list, &l); spin_unlock_irq(&cpa_lock); - if (!cpu_has_clflush) - flush_map(0); - list_for_each_entry_safe(pg, next, &l, lru) { - if (cpu_has_clflush) - flush_map(page_address(pg)); + flush_map(); + list_for_each_entry_safe(pg, next, &l, lru) __free_page(pg); - } } #ifdef CONFIG_DEBUG_PAGEALLOC diff --git a/trunk/arch/i386/mm/pgtable.c b/trunk/arch/i386/mm/pgtable.c index f349eaf450b0..10126e3f8174 100644 --- a/trunk/arch/i386/mm/pgtable.c +++ b/trunk/arch/i386/mm/pgtable.c @@ -95,11 +95,8 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) return; } pte = pte_offset_kernel(pmd, vaddr); - if (pgprot_val(flags)) - /* stored as-is, to permit clearing entries */ - set_pte(pte, pfn_pte(pfn, flags)); - else - pte_clear(&init_mm, vaddr, pte); + /* stored as-is, to permit clearing entries */ + set_pte(pte, pfn_pte(pfn, flags)); /* * It's enough to flush this one mapping. @@ -196,7 +193,7 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) return pte; } -void pmd_ctor(void *pmd, struct kmem_cache *cache, unsigned long flags) +void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags) { memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); } @@ -236,7 +233,7 @@ static inline void pgd_list_del(pgd_t *pgd) set_page_private(next, (unsigned long)pprev); } -void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) +void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) { unsigned long flags; @@ -256,7 +253,7 @@ void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) } /* never called when PTRS_PER_PMD > 1 */ -void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) +void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused) { unsigned long flags; /* can be called from interrupt context */ diff --git a/trunk/arch/i386/pci/early.c b/trunk/arch/i386/pci/early.c index 42df4b6606df..713d6c866cae 100644 --- a/trunk/arch/i386/pci/early.c +++ b/trunk/arch/i386/pci/early.c @@ -45,13 +45,6 @@ void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, outl(val, 0xcfc); } -void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) -{ - PDprintk("%x writing to %x: %x\n", slot, offset, val); - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - outb(val, 0xcfc); -} - int early_pci_allowed(void) { return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == diff --git a/trunk/arch/i386/pci/irq.c b/trunk/arch/i386/pci/irq.c index f2cb942f8281..e65551cd8216 100644 --- a/trunk/arch/i386/pci/irq.c +++ b/trunk/arch/i386/pci/irq.c @@ -764,7 +764,7 @@ static void __init pirq_find_router(struct irq_router *r) DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n", rt->rtr_vendor, rt->rtr_device); - pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); + pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); if (!pirq_router_dev) { DBG(KERN_DEBUG "PCI: Interrupt router not found at " "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); @@ -784,8 +784,6 @@ static void __init pirq_find_router(struct irq_router *r) pirq_router_dev->vendor, pirq_router_dev->device, pci_name(pirq_router_dev)); - - /* The device remains referenced for the kernel lifetime */ } static struct irq_info *pirq_get_info(struct pci_dev *dev) diff --git a/trunk/arch/i386/pci/pcbios.c b/trunk/arch/i386/pci/pcbios.c index 5f5193401bea..ed1512a175ab 100644 --- a/trunk/arch/i386/pci/pcbios.c +++ b/trunk/arch/i386/pci/pcbios.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "pci.h" #include "pci-functions.h" @@ -315,10 +314,6 @@ static struct pci_raw_ops * __devinit pci_find_bios(void) for (check = (union bios32 *) __va(0xe0000); check <= (union bios32 *) __va(0xffff0); ++check) { - long sig; - if (probe_kernel_address(&check->fields.signature, sig)) - continue; - if (check->fields.signature != BIOS32_SIGNATURE) continue; length = check->fields.length * 16; @@ -336,13 +331,11 @@ static struct pci_raw_ops * __devinit pci_find_bios(void) } DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check); if (check->fields.entry >= 0x100000) { - printk("PCI: BIOS32 entry (0x%p) in high memory, " - "cannot use.\n", check); + printk("PCI: BIOS32 entry (0x%p) in high memory, cannot use.\n", check); return NULL; } else { unsigned long bios32_entry = check->fields.entry; - DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", - bios32_entry); + DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", bios32_entry); bios32_indirect.address = bios32_entry + PAGE_OFFSET; if (check_pcibios()) return &pci_bios_access; diff --git a/trunk/arch/i386/power/Makefile b/trunk/arch/i386/power/Makefile index 2de7bbf03cd7..8cfa4e8a719d 100644 --- a/trunk/arch/i386/power/Makefile +++ b/trunk/arch/i386/power/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_PM) += cpu.o -obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o suspend.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o diff --git a/trunk/arch/i386/power/cpu.c b/trunk/arch/i386/power/cpu.c index 2c15500f8713..5a1abeff033b 100644 --- a/trunk/arch/i386/power/cpu.c +++ b/trunk/arch/i386/power/cpu.c @@ -26,8 +26,8 @@ void __save_processor_state(struct saved_context *ctxt) /* * descriptor tables */ - store_gdt(&ctxt->gdt); - store_idt(&ctxt->idt); + store_gdt(&ctxt->gdt_limit); + store_idt(&ctxt->idt_limit); store_tr(ctxt->tr); /* @@ -99,8 +99,8 @@ void __restore_processor_state(struct saved_context *ctxt) * now restore the descriptor tables to their proper values * ltr is done i fix_processor_context(). */ - load_gdt(&ctxt->gdt); - load_idt(&ctxt->idt); + load_gdt(&ctxt->gdt_limit); + load_idt(&ctxt->idt_limit); /* * segment registers diff --git a/trunk/arch/i386/power/suspend.c b/trunk/arch/i386/power/suspend.c deleted file mode 100644 index db5e98d2eb73..000000000000 --- a/trunk/arch/i386/power/suspend.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Suspend support specific for i386 - temporary page tables - * - * Distribute under GPLv2 - * - * Copyright (c) 2006 Rafael J. Wysocki - */ - -#include -#include - -#include -#include -#include - -/* Defined in arch/i386/power/swsusp.S */ -extern int restore_image(void); - -/* Pointer to the temporary resume page tables */ -pgd_t *resume_pg_dir; - -/* The following three functions are based on the analogous code in - * arch/i386/mm/init.c - */ - -/* - * Create a middle page table on a resume-safe page and put a pointer to it in - * the given global directory entry. This only returns the gd entry - * in non-PAE compilation mode, since the middle layer is folded. - */ -static pmd_t *resume_one_md_table_init(pgd_t *pgd) -{ - pud_t *pud; - pmd_t *pmd_table; - -#ifdef CONFIG_X86_PAE - pmd_table = (pmd_t *)get_safe_page(GFP_ATOMIC); - if (!pmd_table) - return NULL; - - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); - pud = pud_offset(pgd, 0); - - BUG_ON(pmd_table != pmd_offset(pud, 0)); -#else - pud = pud_offset(pgd, 0); - pmd_table = pmd_offset(pud, 0); -#endif - - return pmd_table; -} - -/* - * Create a page table on a resume-safe page and place a pointer to it in - * a middle page directory entry. - */ -static pte_t *resume_one_page_table_init(pmd_t *pmd) -{ - if (pmd_none(*pmd)) { - pte_t *page_table = (pte_t *)get_safe_page(GFP_ATOMIC); - if (!page_table) - return NULL; - - set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); - - BUG_ON(page_table != pte_offset_kernel(pmd, 0)); - - return page_table; - } - - return pte_offset_kernel(pmd, 0); -} - -/* - * This maps the physical memory to kernel virtual address space, a total - * of max_low_pfn pages, by creating page tables starting from address - * PAGE_OFFSET. The page tables are allocated out of resume-safe pages. - */ -static int resume_physical_mapping_init(pgd_t *pgd_base) -{ - unsigned long pfn; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - int pgd_idx, pmd_idx; - - pgd_idx = pgd_index(PAGE_OFFSET); - pgd = pgd_base + pgd_idx; - pfn = 0; - - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) { - pmd = resume_one_md_table_init(pgd); - if (!pmd) - return -ENOMEM; - - if (pfn >= max_low_pfn) - continue; - - for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD; pmd++, pmd_idx++) { - if (pfn >= max_low_pfn) - break; - - /* Map with big pages if possible, otherwise create - * normal page tables. - * NOTE: We can mark everything as executable here - */ - if (cpu_has_pse) { - set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC)); - pfn += PTRS_PER_PTE; - } else { - pte_t *max_pte; - - pte = resume_one_page_table_init(pmd); - if (!pte) - return -ENOMEM; - - max_pte = pte + PTRS_PER_PTE; - for (; pte < max_pte; pte++, pfn++) { - if (pfn >= max_low_pfn) - break; - - set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); - } - } - } - } - return 0; -} - -static inline void resume_init_first_level_page_table(pgd_t *pg_dir) -{ -#ifdef CONFIG_X86_PAE - int i; - - /* Init entries of the first-level page table to the zero page */ - for (i = 0; i < PTRS_PER_PGD; i++) - set_pgd(pg_dir + i, - __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); -#endif -} - -int swsusp_arch_resume(void) -{ - int error; - - resume_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); - if (!resume_pg_dir) - return -ENOMEM; - - resume_init_first_level_page_table(resume_pg_dir); - error = resume_physical_mapping_init(resume_pg_dir); - if (error) - return error; - - /* We have got enough memory and from now on we cannot recover */ - restore_image(); - return 0; -} diff --git a/trunk/arch/i386/power/swsusp.S b/trunk/arch/i386/power/swsusp.S index 53662e05b393..8a2b50a0aaad 100644 --- a/trunk/arch/i386/power/swsusp.S +++ b/trunk/arch/i386/power/swsusp.S @@ -28,9 +28,8 @@ ENTRY(swsusp_arch_suspend) call swsusp_save ret -ENTRY(restore_image) - movl resume_pg_dir, %ecx - subl $__PAGE_OFFSET, %ecx +ENTRY(swsusp_arch_resume) + movl $swsusp_pg_dir-__PAGE_OFFSET, %ecx movl %ecx, %cr3 movl restore_pblist, %edx @@ -52,10 +51,6 @@ copy_loop: .p2align 4,,7 done: - /* go back to the original page tables */ - movl $swapper_pg_dir, %ecx - subl $__PAGE_OFFSET, %ecx - movl %ecx, %cr3 /* Flush TLB, including "global" things (vmalloc) */ movl mmu_cr4_features, %eax movl %eax, %edx diff --git a/trunk/arch/ia64/ia32/binfmt_elf32.c b/trunk/arch/ia64/ia32/binfmt_elf32.c index 578737ec7629..daa6b91bc921 100644 --- a/trunk/arch/ia64/ia32/binfmt_elf32.c +++ b/trunk/arch/ia64/ia32/binfmt_elf32.c @@ -91,7 +91,7 @@ ia64_elf32_init (struct pt_regs *regs) * it with privilege level 3 because the IVE uses non-privileged accesses to these * tables. IA-32 segmentation is used to protect against IA-32 accesses to them. */ - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -117,7 +117,7 @@ ia64_elf32_init (struct pt_regs *regs) * code is locked in specific gate page, which is pointed by pretcode * when setup_frame_ia32 */ - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -142,7 +142,7 @@ ia64_elf32_init (struct pt_regs *regs) * Install LDT as anonymous memory. This gives us all-zero segment descriptors * until a task modifies them via modify_ldt(). */ - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -214,7 +214,7 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack) bprm->loader += stack_base; bprm->exec += stack_base; - mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!mpnt) return -ENOMEM; diff --git a/trunk/arch/ia64/ia32/ia32_support.c b/trunk/arch/ia64/ia32/ia32_support.c index 6af400a12ca1..c187743965a0 100644 --- a/trunk/arch/ia64/ia32/ia32_support.c +++ b/trunk/arch/ia64/ia32/ia32_support.c @@ -249,7 +249,7 @@ ia32_init (void) #if PAGE_SHIFT > IA32_PAGE_SHIFT { - extern struct kmem_cache *partial_page_cachep; + extern kmem_cache_t *partial_page_cachep; partial_page_cachep = kmem_cache_create("partial_page_cache", sizeof(struct partial_page), 0, 0, diff --git a/trunk/arch/ia64/ia32/ia32priv.h b/trunk/arch/ia64/ia32/ia32priv.h index cfa0bc0026b5..703a67c934f8 100644 --- a/trunk/arch/ia64/ia32/ia32priv.h +++ b/trunk/arch/ia64/ia32/ia32priv.h @@ -330,6 +330,8 @@ struct old_linux32_dirent { void ia64_elf32_init(struct pt_regs *regs); #define ELF_PLAT_INIT(_r, load_addr) ia64_elf32_init(_r) +#define elf_addr_t u32 + /* This macro yields a bitmask that programs can use to figure out what instruction set this CPU supports. */ #define ELF_HWCAP 0 diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index a4a6e1463af8..9d6a3f210148 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -254,7 +254,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro } /* SLAB cache for partial_page structures */ -struct kmem_cache *partial_page_cachep; +kmem_cache_t *partial_page_cachep; /* * init partial_page_list. diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c index 4d592ee9300b..51217d63285e 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -481,7 +481,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn, 0); + free_insn_slot(p->ainsn.insn); mutex_unlock(&kprobe_mutex); } /* diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index c4c10a0b99d9..0b546e2b36ac 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -952,6 +952,7 @@ remove_palinfo_proc_entries(unsigned int hcpu) } } +#ifdef CONFIG_HOTPLUG_CPU static int palinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -973,6 +974,7 @@ static struct notifier_block palinfo_cpu_notifier = .notifier_call = palinfo_cpu_callback, .priority = 0, }; +#endif static int __init palinfo_init(void) diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index e2321536ee4c..3aaede0d6981 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -2302,7 +2302,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon DPRINT(("smpl_buf @%p\n", smpl_buf)); /* allocate vma */ - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!vma) { DPRINT(("Cannot allocate vma\n")); goto error_kmem; diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index fd607ca51a8d..e63b8ca5344a 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -575,6 +575,7 @@ static struct file_operations salinfo_data_fops = { .write = salinfo_log_write, }; +#ifdef CONFIG_HOTPLUG_CPU static int __devinit salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { @@ -619,6 +620,7 @@ static struct notifier_block salinfo_cpu_notifier = .notifier_call = salinfo_cpu_callback, .priority = 0, }; +#endif /* CONFIG_HOTPLUG_CPU */ static int __init salinfo_init(void) diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index 687500ddb4b8..5629b45e89c6 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -31,11 +31,11 @@ int arch_register_cpu(int num) { #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) /* - * If CPEI can be re-targetted or if this is not - * CPEI target, then it is hotpluggable + * If CPEI cannot be re-targetted, and this is + * CPEI target, then dont create the control file */ - if (can_cpei_retarget() || !is_cpu_cpei_target(num)) - sysfs_cpus[num].cpu.hotpluggable = 1; + if (!can_cpei_retarget() && is_cpu_cpei_target(num)) + sysfs_cpus[num].cpu.no_control = 1; map_cpu_to_node(num, node_cpuid[num].nid); #endif diff --git a/trunk/arch/ia64/mm/hugetlbpage.c b/trunk/arch/ia64/mm/hugetlbpage.c index 0c7e94edc20e..f3a9585e98a8 100644 --- a/trunk/arch/ia64/mm/hugetlbpage.c +++ b/trunk/arch/ia64/mm/hugetlbpage.c @@ -64,11 +64,6 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr) return pte; } -int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) -{ - return 0; -} - #define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; } /* diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index 56dc2024220e..ff87a5cba399 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -156,7 +156,7 @@ ia64_init_addr_space (void) * the problem. When the process attempts to write to the register backing store * for the first time, it will get a SEGFAULT in this case. */ - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -175,7 +175,7 @@ ia64_init_addr_space (void) /* map NaT-page at address zero to speed up speculative dereferencing of NULL: */ if (!(current->personality & MMAP_PAGE_ZERO)) { - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; diff --git a/trunk/arch/m32r/kernel/setup.c b/trunk/arch/m32r/kernel/setup.c index 936205f7aba0..0e7778be33cc 100644 --- a/trunk/arch/m32r/kernel/setup.c +++ b/trunk/arch/m32r/kernel/setup.c @@ -196,7 +196,9 @@ static unsigned long __init setup_memory(void) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem(INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET; + initrd_start = INITRD_START ? + INITRD_START + PAGE_OFFSET : 0; + initrd_end = initrd_start + INITRD_SIZE; printk("initrd:start[%08lx],size[%08lx]\n", initrd_start, INITRD_SIZE); diff --git a/trunk/arch/m32r/kernel/signal.c b/trunk/arch/m32r/kernel/signal.c index 092ea86bb079..b60cea4aebaa 100644 --- a/trunk/arch/m32r/kernel/signal.c +++ b/trunk/arch/m32r/kernel/signal.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/m32r/mm/discontig.c b/trunk/arch/m32r/mm/discontig.c index c7efdb0aefc5..abb34ccd5986 100644 --- a/trunk/arch/m32r/mm/discontig.c +++ b/trunk/arch/m32r/mm/discontig.c @@ -105,7 +105,9 @@ unsigned long __init setup_memory(void) if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) { reserve_bootmem_node(NODE_DATA(0), INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET; + initrd_start = INITRD_START ? + INITRD_START + PAGE_OFFSET : 0; + initrd_end = initrd_start + INITRD_SIZE; printk("initrd:start[%08lx],size[%08lx]\n", initrd_start, INITRD_SIZE); diff --git a/trunk/arch/m68k/amiga/chipram.c b/trunk/arch/m68k/amiga/chipram.c index fa015d801617..de1304c91112 100644 --- a/trunk/arch/m68k/amiga/chipram.c +++ b/trunk/arch/m68k/amiga/chipram.c @@ -52,9 +52,10 @@ void *amiga_chip_alloc(unsigned long size, const char *name) #ifdef DEBUG printk("amiga_chip_alloc: allocate %ld bytes\n", size); #endif - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kmalloc(sizeof(struct resource), GFP_KERNEL); if (!res) return NULL; + memset(res, 0, sizeof(struct resource)); res->name = name; if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) { diff --git a/trunk/arch/m68k/atari/hades-pci.c b/trunk/arch/m68k/atari/hades-pci.c index bee2b1443e36..6ca57b6564da 100644 --- a/trunk/arch/m68k/atari/hades-pci.c +++ b/trunk/arch/m68k/atari/hades-pci.c @@ -375,9 +375,10 @@ struct pci_bus_info * __init init_hades_pci(void) * Allocate memory for bus info structure. */ - bus = kzalloc(sizeof(struct pci_bus_info), GFP_KERNEL); + bus = kmalloc(sizeof(struct pci_bus_info), GFP_KERNEL); if (!bus) return NULL; + memset(bus, 0, sizeof(struct pci_bus_info)); /* * Claim resources. The m68k has no separate I/O space, both diff --git a/trunk/arch/m68k/mm/fault.c b/trunk/arch/m68k/mm/fault.c index 2adbeb16e1b8..911f2ce3f53e 100644 --- a/trunk/arch/m68k/mm/fault.c +++ b/trunk/arch/m68k/mm/fault.c @@ -99,7 +99,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_interrupt() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/trunk/arch/m68knommu/kernel/vmlinux.lds.S b/trunk/arch/m68knommu/kernel/vmlinux.lds.S index 2b2a10da64a4..58afa8be604e 100644 --- a/trunk/arch/m68knommu/kernel/vmlinux.lds.S +++ b/trunk/arch/m68knommu/kernel/vmlinux.lds.S @@ -60,7 +60,6 @@ SECTIONS { #endif .text : { - _text = .; _stext = . ; *(.text) SCHED_TEXT diff --git a/trunk/arch/mips/kernel/binfmt_elfn32.c b/trunk/arch/mips/kernel/binfmt_elfn32.c index 9b34238d41c0..4a9f1ecefaf2 100644 --- a/trunk/arch/mips/kernel/binfmt_elfn32.c +++ b/trunk/arch/mips/kernel/binfmt_elfn32.c @@ -90,6 +90,7 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; +#define elf_addr_t u32 #define elf_caddr_t u32 #define init_elf_binfmt init_elfn32_binfmt diff --git a/trunk/arch/mips/kernel/binfmt_elfo32.c b/trunk/arch/mips/kernel/binfmt_elfo32.c index 993f7ec70f35..e31813779895 100644 --- a/trunk/arch/mips/kernel/binfmt_elfo32.c +++ b/trunk/arch/mips/kernel/binfmt_elfo32.c @@ -92,6 +92,7 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; +#define elf_addr_t u32 #define elf_caddr_t u32 #define init_elf_binfmt init_elf32_binfmt diff --git a/trunk/arch/mips/kernel/irixelf.c b/trunk/arch/mips/kernel/irixelf.c index 1bbefbf43373..ab12c8f01518 100644 --- a/trunk/arch/mips/kernel/irixelf.c +++ b/trunk/arch/mips/kernel/irixelf.c @@ -52,6 +52,10 @@ static struct linux_binfmt irix_format = { irix_core_dump, PAGE_SIZE }; +#ifndef elf_addr_t +#define elf_addr_t unsigned long +#endif + #ifdef DEBUG /* Debugging routines. */ static char *get_elf_p_type(Elf32_Word p_type) @@ -1009,7 +1013,7 @@ static int notesize(struct memelfnote *en) int sz; sz = sizeof(struct elf_note); - sz += roundup(strlen(en->name) + 1, 4); + sz += roundup(strlen(en->name), 4); sz += roundup(en->datasz, 4); return sz; @@ -1028,7 +1032,7 @@ static int writenote(struct memelfnote *men, struct file *file) { struct elf_note en; - en.n_namesz = strlen(men->name) + 1; + en.n_namesz = strlen(men->name); en.n_descsz = men->datasz; en.n_type = men->type; diff --git a/trunk/arch/mips/mm/dma-coherent.c b/trunk/arch/mips/mm/dma-coherent.c index 5697c6e250a3..7fa5fd16e46b 100644 --- a/trunk/arch/mips/mm/dma-coherent.c +++ b/trunk/arch/mips/mm/dma-coherent.c @@ -190,14 +190,14 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +int dma_is_consistent(dma_addr_t dma_addr) { return 1; } EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/trunk/arch/mips/mm/dma-ip27.c b/trunk/arch/mips/mm/dma-ip27.c index f088344db465..8da19fd22ac6 100644 --- a/trunk/arch/mips/mm/dma-ip27.c +++ b/trunk/arch/mips/mm/dma-ip27.c @@ -197,14 +197,14 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +int dma_is_consistent(dma_addr_t dma_addr) { return 1; } EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/trunk/arch/mips/mm/dma-ip32.c b/trunk/arch/mips/mm/dma-ip32.c index b42b6f7456e6..ec54ed0d26ff 100644 --- a/trunk/arch/mips/mm/dma-ip32.c +++ b/trunk/arch/mips/mm/dma-ip32.c @@ -363,15 +363,14 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +int dma_is_consistent(dma_addr_t dma_addr) { return 1; } EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) +void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { if (direction == DMA_NONE) return; diff --git a/trunk/arch/mips/mm/dma-noncoherent.c b/trunk/arch/mips/mm/dma-noncoherent.c index 8cecef0957c3..2eeffe5c2a3a 100644 --- a/trunk/arch/mips/mm/dma-noncoherent.c +++ b/trunk/arch/mips/mm/dma-noncoherent.c @@ -299,15 +299,14 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +int dma_is_consistent(dma_addr_t dma_addr) { return 1; } EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) +void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { if (direction == DMA_NONE) return; diff --git a/trunk/arch/mips/mm/highmem.c b/trunk/arch/mips/mm/highmem.c index 675502ada5a2..99ebf3ccc222 100644 --- a/trunk/arch/mips/mm/highmem.c +++ b/trunk/arch/mips/mm/highmem.c @@ -39,7 +39,7 @@ void *__kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - pagefault_disable(); + inc_preempt_count(); if (!PageHighMem(page)) return page_address(page); @@ -62,7 +62,8 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < FIXADDR_START) { // FIXME - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); return; } @@ -77,7 +78,8 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) local_flush_tlb_one(vaddr); #endif - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); } #ifndef CONFIG_LIMITED_DMA @@ -90,7 +92,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) enum fixed_addresses idx; unsigned long vaddr; - pagefault_disable(); + inc_preempt_count(); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/trunk/arch/parisc/kernel/binfmt_elf32.c b/trunk/arch/parisc/kernel/binfmt_elf32.c index ecb10a4f63c6..1e64e7b88110 100644 --- a/trunk/arch/parisc/kernel/binfmt_elf32.c +++ b/trunk/arch/parisc/kernel/binfmt_elf32.c @@ -75,6 +75,7 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; +#define elf_addr_t unsigned int #define init_elf_binfmt init_elf32_binfmt #define ELF_PLATFORM ("PARISC32\0") diff --git a/trunk/arch/parisc/mm/fault.c b/trunk/arch/parisc/mm/fault.c index 641f9c920eee..64785e46f93b 100644 --- a/trunk/arch/parisc/mm/fault.c +++ b/trunk/arch/parisc/mm/fault.c @@ -152,7 +152,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, const struct exception_table_entry *fix; unsigned long acc_type; - if (in_atomic() || !mm) + if (in_interrupt() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c index d3f2080d2eee..89b03c8da9d2 100644 --- a/trunk/arch/powerpc/kernel/crash.c +++ b/trunk/arch/powerpc/kernel/crash.c @@ -46,6 +46,61 @@ int crashing_cpu = -1; static cpumask_t cpus_in_crash = CPU_MASK_NONE; cpumask_t cpus_in_sr = CPU_MASK_NONE; +static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, + size_t data_len) +{ + struct elf_note note; + + note.n_namesz = strlen(name) + 1; + note.n_descsz = data_len; + note.n_type = type; + memcpy(buf, ¬e, sizeof(note)); + buf += (sizeof(note) +3)/4; + memcpy(buf, name, note.n_namesz); + buf += (note.n_namesz + 3)/4; + memcpy(buf, data, note.n_descsz); + buf += (note.n_descsz + 3)/4; + + return buf; +} + +static void final_note(u32 *buf) +{ + struct elf_note note; + + note.n_namesz = 0; + note.n_descsz = 0; + note.n_type = 0; + memcpy(buf, ¬e, sizeof(note)); +} + +static void crash_save_this_cpu(struct pt_regs *regs, int cpu) +{ + struct elf_prstatus prstatus; + u32 *buf; + + if ((cpu < 0) || (cpu >= NR_CPUS)) + return; + + /* Using ELF notes here is opportunistic. + * I need a well defined structure format + * for the data I pass, and I need tags + * on the data to indicate what information I have + * squirrelled away. ELF notes happen to provide + * all of that that no need to invent something new. + */ + buf = (u32*)per_cpu_ptr(crash_notes, cpu); + if (!buf) + return; + + memset(&prstatus, 0, sizeof(prstatus)); + prstatus.pr_pid = current->pid; + elf_core_copy_regs(&prstatus.pr_reg, regs); + buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, + sizeof(prstatus)); + final_note(buf); +} + #ifdef CONFIG_SMP static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); @@ -58,7 +113,7 @@ void crash_ipi_callback(struct pt_regs *regs) hard_irq_disable(); if (!cpu_isset(cpu, cpus_in_crash)) - crash_save_cpu(regs, cpu); + crash_save_this_cpu(regs, cpu); cpu_set(cpu, cpus_in_crash); /* @@ -251,7 +306,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); - crash_save_cpu(regs, crashing_cpu); + crash_save_this_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); if (ppc_md.kexec_cpu_down) diff --git a/trunk/arch/powerpc/kernel/kprobes.c b/trunk/arch/powerpc/kernel/kprobes.c index 4657563f8813..7b8d12b9026c 100644 --- a/trunk/arch/powerpc/kernel/kprobes.c +++ b/trunk/arch/powerpc/kernel/kprobes.c @@ -85,7 +85,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn, 0); + free_insn_slot(p->ainsn.insn); mutex_unlock(&kprobe_mutex); } diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 7d0f13fecc0e..b9561d300516 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -101,7 +101,7 @@ struct flash_block_list_header { /* just the header of flash_block_list */ static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; /* Use slab cache to guarantee 4k alignment */ -static struct kmem_cache *flash_block_cache = NULL; +static kmem_cache_t *flash_block_cache = NULL; #define FLASH_BLOCK_LIST_VERSION (1UL) @@ -286,7 +286,7 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, } /* constructor for flash_block_cache */ -void rtas_block_ctor(void *ptr, struct kmem_cache *cache, unsigned long flags) +void rtas_block_ctor(void *ptr, kmem_cache_t *cache, unsigned long flags) { memset(ptr, 0, RTAS_BLK_SIZE); } diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index e4ebe1a6228e..320353f0926f 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #endif #include diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index 63ed265b7f09..22123a0d5416 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -239,7 +239,7 @@ static void unregister_cpu_online(unsigned int cpu) struct cpu *c = &per_cpu(cpu_devices, cpu); struct sys_device *s = &c->sysdev; - BUG_ON(!c->hotpluggable); + BUG_ON(c->no_control); if (!firmware_has_feature(FW_FEATURE_ISERIES) && cpu_has_feature(CPU_FTR_SMT)) @@ -424,10 +424,10 @@ static int __init topology_init(void) * CPU. For instance, the boot cpu might never be valid * for hotplugging. */ - if (ppc_md.cpu_die) - c->hotpluggable = 1; + if (!ppc_md.cpu_die) + c->no_control = 1; - if (cpu_online(cpu) || c->hotpluggable) { + if (cpu_online(cpu) || (c->no_control == 0)) { register_cpu(c, cpu); sysdev_create_file(&c->sysdev, &attr_physical_id); diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index a4b28c73bba0..c913ad5cad29 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -264,7 +264,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, /* Allocate a VMA structure and fill it up */ - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); if (vma == NULL) { rc = -ENOMEM; goto fail_mmapsem; diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index 04b98671a060..e8342d867536 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -33,7 +33,6 @@ SECTIONS /* Text and gots */ .text : { - _text = .; *(.text .text.*) SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index 89c836d54809..506d89768d45 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -146,11 +146,6 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) return hugepte_offset(hpdp, addr); } -int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) -{ - return 0; -} - static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp) { pte_t *hugepte = hugepd_page(*hpdp); @@ -1047,7 +1042,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, return err; } -static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) +static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) { memset(addr, 0, kmem_cache_size(cache)); } diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index d12a87ec5ae9..9a178549cbcf 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -141,7 +141,7 @@ static int __init setup_kcore(void) } module_init(setup_kcore); -static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) +static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) { memset(addr, 0, kmem_cache_size(cache)); } @@ -166,9 +166,9 @@ static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { /* Hugepages need one extra cache, initialized in hugetlbpage.c. We * can't put into the tables above, because HPAGE_SHIFT is not compile * time constant. */ -struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+1]; +kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+1]; #else -struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; +kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; #endif void pgtable_cache_init(void) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index e3af9112c026..c7d010749a18 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -40,7 +40,7 @@ #include "spufs.h" -static struct kmem_cache *spufs_inode_cache; +static kmem_cache_t *spufs_inode_cache; char *isolated_loader; static struct inode * @@ -48,7 +48,7 @@ spufs_alloc_inode(struct super_block *sb) { struct spufs_inode_info *ei; - ei = kmem_cache_alloc(spufs_inode_cache, GFP_KERNEL); + ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL); if (!ei) return NULL; @@ -65,7 +65,7 @@ spufs_destroy_inode(struct inode *inode) } static void -spufs_init_once(void *p, struct kmem_cache * cachep, unsigned long flags) +spufs_init_once(void *p, kmem_cache_t * cachep, unsigned long flags) { struct spufs_inode_info *ei = p; diff --git a/trunk/arch/ppc/kernel/vmlinux.lds.S b/trunk/arch/ppc/kernel/vmlinux.lds.S index 61921268a0d0..16e8661e1fec 100644 --- a/trunk/arch/ppc/kernel/vmlinux.lds.S +++ b/trunk/arch/ppc/kernel/vmlinux.lds.S @@ -31,7 +31,6 @@ SECTIONS .plt : { *(.plt) } .text : { - _text = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index b8c237290263..67d5cf9cba83 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -561,6 +561,7 @@ appldata_offline_cpu(int cpu) spin_unlock(&appldata_timer_lock); } +#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit appldata_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) @@ -581,6 +582,7 @@ appldata_cpu_notify(struct notifier_block *self, static struct notifier_block appldata_nb = { .notifier_call = appldata_cpu_notify, }; +#endif /* * appldata_init() diff --git a/trunk/arch/s390/kernel/binfmt_elf32.c b/trunk/arch/s390/kernel/binfmt_elf32.c index 5c46054195cb..9565a2dcfadc 100644 --- a/trunk/arch/s390/kernel/binfmt_elf32.c +++ b/trunk/arch/s390/kernel/binfmt_elf32.c @@ -176,6 +176,7 @@ struct elf_prpsinfo32 #include +#define elf_addr_t u32 /* #define init_elf_binfmt init_elf32_binfmt */ diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index 576368c4f605..67914fe7f317 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -200,7 +200,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn, 0); + free_insn_slot(p->ainsn.insn); mutex_unlock(&kprobe_mutex); } diff --git a/trunk/arch/s390/lib/uaccess_std.c b/trunk/arch/s390/lib/uaccess_std.c index bbaca66fa293..2d549ed2e113 100644 --- a/trunk/arch/s390/lib/uaccess_std.c +++ b/trunk/arch/s390/lib/uaccess_std.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #ifndef __s390x__ @@ -258,7 +258,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old) { int oldval = 0, newval, ret; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -284,7 +284,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old) default: ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); *old = oldval; return ret; } diff --git a/trunk/arch/sh/kernel/cpu/sh4/sq.c b/trunk/arch/sh/kernel/cpu/sh4/sq.c index 0c9ea38d2caa..55f43506995a 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/sq.c +++ b/trunk/arch/sh/kernel/cpu/sh4/sq.c @@ -38,7 +38,7 @@ struct sq_mapping { static struct sq_mapping *sq_mapping_list; static DEFINE_SPINLOCK(sq_mapping_lock); -static struct kmem_cache *sq_cache; +static kmem_cache_t *sq_cache; static unsigned long *sq_bitmap; #define store_queue_barrier() \ diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index f8dd6b7bfab0..696ca75752d9 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -332,7 +332,8 @@ void __init setup_arch(char **cmdline_p) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; + initrd_start = + INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0; initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " diff --git a/trunk/arch/sh/kernel/sh_ksyms.c b/trunk/arch/sh/kernel/sh_ksyms.c index ceee79143401..c706f3bfd897 100644 --- a/trunk/arch/sh/kernel/sh_ksyms.c +++ b/trunk/arch/sh/kernel/sh_ksyms.c @@ -99,6 +99,10 @@ EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(synchronize_irq); #endif +#ifdef CONFIG_PM +EXPORT_SYMBOL(pm_suspend); +#endif + EXPORT_SYMBOL(csum_partial); #ifdef CONFIG_IPV6 EXPORT_SYMBOL(csum_ipv6_magic); diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c index bb1c480a59c7..50d7c4993bef 100644 --- a/trunk/arch/sh/kernel/signal.c +++ b/trunk/arch/sh/kernel/signal.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall.c b/trunk/arch/sh/kernel/vsyscall/vsyscall.c index deb46941f315..075d6cc1a2d7 100644 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall.c +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall.c @@ -97,7 +97,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, goto up_fail; } - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); if (!vma) { ret = -ENOMEM; goto up_fail; diff --git a/trunk/arch/sh/mm/hugetlbpage.c b/trunk/arch/sh/mm/hugetlbpage.c index cf2c2ee35a37..329059d6b54a 100644 --- a/trunk/arch/sh/mm/hugetlbpage.c +++ b/trunk/arch/sh/mm/hugetlbpage.c @@ -63,11 +63,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return pte; } -int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) -{ - return 0; -} - struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) { diff --git a/trunk/arch/sh/mm/pmb.c b/trunk/arch/sh/mm/pmb.c index b60ad83a7635..92e745341e4d 100644 --- a/trunk/arch/sh/mm/pmb.c +++ b/trunk/arch/sh/mm/pmb.c @@ -30,7 +30,7 @@ #define NR_PMB_ENTRIES 16 -static struct kmem_cache *pmb_cache; +static kmem_cache_t *pmb_cache; static unsigned long pmb_map; static struct pmb_entry pmb_init_map[] = { @@ -283,7 +283,7 @@ void pmb_unmap(unsigned long addr) } while (pmbe); } -static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep, unsigned long flags) +static void pmb_cache_ctor(void *pmb, kmem_cache_t *cachep, unsigned long flags) { struct pmb_entry *pmbe = pmb; @@ -297,7 +297,7 @@ static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep, unsigned long f spin_unlock_irq(&pmb_list_lock); } -static void pmb_cache_dtor(void *pmb, struct kmem_cache *cachep, unsigned long flags) +static void pmb_cache_dtor(void *pmb, kmem_cache_t *cachep, unsigned long flags) { spin_lock_irq(&pmb_list_lock); pmb_list_del(pmb); diff --git a/trunk/arch/sh64/kernel/setup.c b/trunk/arch/sh64/kernel/setup.c index b9e7d54d7b85..ffb310e33cef 100644 --- a/trunk/arch/sh64/kernel/setup.c +++ b/trunk/arch/sh64/kernel/setup.c @@ -243,7 +243,9 @@ void __init setup_arch(char **cmdline_p) if (INITRD_START + INITRD_SIZE <= (PFN_PHYS(last_pfn))) { reserve_bootmem_node(NODE_DATA(0), INITRD_START + __MEMORY_START, INITRD_SIZE); - initrd_start = (long) INITRD_START + PAGE_OFFSET + __MEMORY_START; + initrd_start = + (long) INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0; + initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " diff --git a/trunk/arch/sh64/kernel/signal.c b/trunk/arch/sh64/kernel/signal.c index 1666d3efb52e..9e2ffc45c0e0 100644 --- a/trunk/arch/sh64/kernel/signal.c +++ b/trunk/arch/sh64/kernel/signal.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/sh64/mm/fault.c b/trunk/arch/sh64/mm/fault.c index 4f72ab33bb2b..8e2f6c28b739 100644 --- a/trunk/arch/sh64/mm/fault.c +++ b/trunk/arch/sh64/mm/fault.c @@ -154,7 +154,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_interrupt() || !mm) goto no_context; /* TLB misses upon some cache flushes get done under cli() */ diff --git a/trunk/arch/sh64/mm/hugetlbpage.c b/trunk/arch/sh64/mm/hugetlbpage.c index 4b455f611146..187cf01750b8 100644 --- a/trunk/arch/sh64/mm/hugetlbpage.c +++ b/trunk/arch/sh64/mm/hugetlbpage.c @@ -53,11 +53,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return pte; } -int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) -{ - return 0; -} - void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index b73e6b9067ed..5cc5ff7f8824 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -11,7 +11,6 @@ SECTIONS . = 0x10000 + SIZEOF_HEADERS; .text 0xf0004000 : { - _text = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/sparc/mm/highmem.c b/trunk/arch/sparc/mm/highmem.c index 01fc6c254292..4d8ed9c65182 100644 --- a/trunk/arch/sparc/mm/highmem.c +++ b/trunk/arch/sparc/mm/highmem.c @@ -35,7 +35,7 @@ void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - pagefault_disable(); + inc_preempt_count(); if (!PageHighMem(page)) return page_address(page); @@ -70,7 +70,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned long idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < FIXADDR_START) { // FIXME - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); return; } @@ -96,7 +97,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #endif #endif - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); } /* We may be fed a pagetable here by ptep_to_xxx and others. */ diff --git a/trunk/arch/sparc64/kernel/binfmt_elf32.c b/trunk/arch/sparc64/kernel/binfmt_elf32.c index 9ad84ff10a17..a98f3ae175a3 100644 --- a/trunk/arch/sparc64/kernel/binfmt_elf32.c +++ b/trunk/arch/sparc64/kernel/binfmt_elf32.c @@ -141,6 +141,7 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) value->tv_sec = jiffies / HZ; } +#define elf_addr_t u32 #undef start_thread #define start_thread start_thread32 #define init_elf_binfmt init_elf32_binfmt diff --git a/trunk/arch/sparc64/kernel/vmlinux.lds.S b/trunk/arch/sparc64/kernel/vmlinux.lds.S index 4a6063f33e7a..bd9de8c2a2aa 100644 --- a/trunk/arch/sparc64/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc64/kernel/vmlinux.lds.S @@ -13,7 +13,6 @@ SECTIONS . = 0x4000; .text 0x0000000000404000 : { - _text = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/sparc64/mm/hugetlbpage.c b/trunk/arch/sparc64/mm/hugetlbpage.c index 33fd0b265e70..53b9b1f528e5 100644 --- a/trunk/arch/sparc64/mm/hugetlbpage.c +++ b/trunk/arch/sparc64/mm/hugetlbpage.c @@ -235,11 +235,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return pte; } -int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) -{ - return 0; -} - void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index a8e8802eed4d..09cb7fccc03a 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -176,9 +176,9 @@ unsigned long sparc64_kern_sec_context __read_mostly; int bigkernel = 0; -struct kmem_cache *pgtable_cache __read_mostly; +kmem_cache_t *pgtable_cache __read_mostly; -static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) +static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) { clear_page(addr); } diff --git a/trunk/arch/sparc64/mm/tsb.c b/trunk/arch/sparc64/mm/tsb.c index 236d02f41a01..beaa02810f0e 100644 --- a/trunk/arch/sparc64/mm/tsb.c +++ b/trunk/arch/sparc64/mm/tsb.c @@ -239,7 +239,7 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsign } } -static struct kmem_cache *tsb_caches[8] __read_mostly; +static kmem_cache_t *tsb_caches[8] __read_mostly; static const char *tsb_cache_names[8] = { "tsb_8KB", diff --git a/trunk/arch/um/drivers/daemon_kern.c b/trunk/arch/um/drivers/daemon_kern.c index 9c2e7a758f21..824386974f88 100644 --- a/trunk/arch/um/drivers/daemon_kern.c +++ b/trunk/arch/um/drivers/daemon_kern.c @@ -98,4 +98,4 @@ static int register_daemon(void) return 0; } -late_initcall(register_daemon); +__initcall(register_daemon); diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index aa3090d05a8f..426633e5d6e3 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -31,9 +31,9 @@ static irqreturn_t line_interrupt(int irq, void *data) return IRQ_HANDLED; } -static void line_timer_cb(struct work_struct *work) +static void line_timer_cb(void *arg) { - struct line *line = container_of(work, struct line, task.work); + struct line *line = arg; if(!line->throttled) chan_interrupt(&line->chan_list, &line->task, line->tty, @@ -443,7 +443,7 @@ int line_open(struct line *lines, struct tty_struct *tty) * is registered. */ enable_chan(line); - INIT_DELAYED_WORK(&line->task, line_timer_cb); + INIT_WORK(&line->task, line_timer_cb, line); if(!line->sigio){ chan_enable_winch(&line->chan_list, tty); diff --git a/trunk/arch/um/drivers/mcast_kern.c b/trunk/arch/um/drivers/mcast_kern.c index 52ccb7b53cd2..c090fbd464e7 100644 --- a/trunk/arch/um/drivers/mcast_kern.c +++ b/trunk/arch/um/drivers/mcast_kern.c @@ -127,4 +127,4 @@ static int register_mcast(void) return 0; } -late_initcall(register_mcast); +__initcall(register_mcast); diff --git a/trunk/arch/um/drivers/pcap_kern.c b/trunk/arch/um/drivers/pcap_kern.c index e67362acf0e7..6e1ef8558283 100644 --- a/trunk/arch/um/drivers/pcap_kern.c +++ b/trunk/arch/um/drivers/pcap_kern.c @@ -109,4 +109,4 @@ static int register_pcap(void) return 0; } -late_initcall(register_pcap); +__initcall(register_pcap); diff --git a/trunk/arch/um/drivers/slip_kern.c b/trunk/arch/um/drivers/slip_kern.c index 25634bd1f585..788da5439a2d 100644 --- a/trunk/arch/um/drivers/slip_kern.c +++ b/trunk/arch/um/drivers/slip_kern.c @@ -95,4 +95,4 @@ static int register_slip(void) return 0; } -late_initcall(register_slip); +__initcall(register_slip); diff --git a/trunk/arch/um/drivers/slirp_kern.c b/trunk/arch/um/drivers/slirp_kern.c index b3ed8fb874ab..ae322e1c8a87 100644 --- a/trunk/arch/um/drivers/slirp_kern.c +++ b/trunk/arch/um/drivers/slirp_kern.c @@ -119,4 +119,4 @@ static int register_slirp(void) return 0; } -late_initcall(register_slirp); +__initcall(register_slirp); diff --git a/trunk/arch/um/include/chan_kern.h b/trunk/arch/um/include/chan_kern.h index 9003a343e148..572d286ed2c6 100644 --- a/trunk/arch/um/include/chan_kern.h +++ b/trunk/arch/um/include/chan_kern.h @@ -27,7 +27,7 @@ struct chan { void *data; }; -extern void chan_interrupt(struct list_head *chans, struct delayed_work *task, +extern void chan_interrupt(struct list_head *chans, struct work_struct *task, struct tty_struct *tty, int irq); extern int parse_chan_pair(char *str, struct line *line, int device, const struct chan_opts *opts); diff --git a/trunk/arch/um/include/line.h b/trunk/arch/um/include/line.h index 214ee76c40df..7be24811bb30 100644 --- a/trunk/arch/um/include/line.h +++ b/trunk/arch/um/include/line.h @@ -51,7 +51,7 @@ struct line { char *tail; int sigio; - struct delayed_work task; + struct work_struct task; const struct line_driver *driver; int have_irq; }; diff --git a/trunk/arch/um/include/sysdep-i386/ptrace.h b/trunk/arch/um/include/sysdep-i386/ptrace.h index 52b398bcafcf..6670cc992ecb 100644 --- a/trunk/arch/um/include/sysdep-i386/ptrace.h +++ b/trunk/arch/um/include/sysdep-i386/ptrace.h @@ -75,7 +75,7 @@ union uml_pt_regs { #endif #ifdef UML_CONFIG_MODE_SKAS struct skas_regs { - unsigned long regs[MAX_REG_NR]; + unsigned long regs[HOST_FRAME_SIZE]; unsigned long fp[HOST_FP_SIZE]; unsigned long xfp[HOST_XFP_SIZE]; struct faultinfo faultinfo; diff --git a/trunk/arch/um/include/sysdep-i386/stub.h b/trunk/arch/um/include/sysdep-i386/stub.h index 4fffae75ba53..b492b12b4a10 100644 --- a/trunk/arch/um/include/sysdep-i386/stub.h +++ b/trunk/arch/um/include/sysdep-i386/stub.h @@ -9,7 +9,6 @@ #include #include #include -#include #include "stub-data.h" #include "kern_constants.h" #include "uml-config.h" diff --git a/trunk/arch/um/include/sysdep-x86_64/ptrace.h b/trunk/arch/um/include/sysdep-x86_64/ptrace.h index 66cb400c2c92..617bb9efc934 100644 --- a/trunk/arch/um/include/sysdep-x86_64/ptrace.h +++ b/trunk/arch/um/include/sysdep-x86_64/ptrace.h @@ -108,7 +108,7 @@ union uml_pt_regs { * file size, while i386 uses FRAME_SIZE. Therefore, we need * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE. */ - unsigned long regs[MAX_REG_NR]; + unsigned long regs[UM_FRAME_SIZE]; unsigned long fp[HOST_FP_SIZE]; struct faultinfo faultinfo; long syscall; diff --git a/trunk/arch/um/os-Linux/drivers/ethertap_kern.c b/trunk/arch/um/os-Linux/drivers/ethertap_kern.c index 70541821775f..16385e2ada85 100644 --- a/trunk/arch/um/os-Linux/drivers/ethertap_kern.c +++ b/trunk/arch/um/os-Linux/drivers/ethertap_kern.c @@ -105,4 +105,4 @@ static int register_ethertap(void) return 0; } -late_initcall(register_ethertap); +__initcall(register_ethertap); diff --git a/trunk/arch/um/os-Linux/drivers/tuntap_kern.c b/trunk/arch/um/os-Linux/drivers/tuntap_kern.c index 76570a2c25c3..0edbac63c527 100644 --- a/trunk/arch/um/os-Linux/drivers/tuntap_kern.c +++ b/trunk/arch/um/os-Linux/drivers/tuntap_kern.c @@ -90,4 +90,4 @@ static int register_tuntap(void) return 0; } -late_initcall(register_tuntap); +__initcall(register_tuntap); diff --git a/trunk/arch/um/sys-i386/ldt.c b/trunk/arch/um/sys-i386/ldt.c index 49057d8bc668..e299ee5a753d 100644 --- a/trunk/arch/um/sys-i386/ldt.c +++ b/trunk/arch/um/sys-i386/ldt.c @@ -3,6 +3,7 @@ * Licensed under the GPL */ +#include "linux/stddef.h" #include "linux/sched.h" #include "linux/slab.h" #include "linux/types.h" diff --git a/trunk/arch/um/sys-i386/ptrace_user.c b/trunk/arch/um/sys-i386/ptrace_user.c index 01212c88fcc4..5f3cc6685820 100644 --- a/trunk/arch/um/sys-i386/ptrace_user.c +++ b/trunk/arch/um/sys-i386/ptrace_user.c @@ -4,9 +4,9 @@ */ #include -#include #include #include +#include #include "ptrace_user.h" /* Grr, asm/user.h includes asm/ptrace.h, so has to follow ptrace_user.h */ #include diff --git a/trunk/arch/um/sys-i386/user-offsets.c b/trunk/arch/um/sys-i386/user-offsets.c index 447306b20aea..6f4ef2b7fa4a 100644 --- a/trunk/arch/um/sys-i386/user-offsets.c +++ b/trunk/arch/um/sys-i386/user-offsets.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #define DEFINE(sym, val) \ diff --git a/trunk/arch/v850/kernel/vmlinux.lds.S b/trunk/arch/v850/kernel/vmlinux.lds.S index 3a5fd07fe064..88d087f527c9 100644 --- a/trunk/arch/v850/kernel/vmlinux.lds.S +++ b/trunk/arch/v850/kernel/vmlinux.lds.S @@ -90,7 +90,6 @@ /* Kernel text segment, and some constant data areas. */ #define TEXT_CONTENTS \ - _text = .; \ __stext = . ; \ *(.text) \ SCHED_TEXT \ diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index bfbb9bcae123..010d2265f1cf 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -122,7 +122,7 @@ endchoice choice prompt "Processor family" - default GENERIC_CPU + default MK8 config MK8 bool "AMD-Opteron/Athlon64" @@ -130,31 +130,16 @@ config MK8 Optimize for AMD Opteron/Athlon64/Hammer/K8 CPUs. config MPSC - bool "Intel P4 / older Netburst based Xeon" + bool "Intel EM64T" help - Optimize for Intel Pentium 4 and older Nocona/Dempsey Xeon CPUs - with Intel Extended Memory 64 Technology(EM64T). For details see + Optimize for Intel Pentium 4 and Xeon CPUs with Intel + Extended Memory 64 Technology(EM64T). For details see . - Note the the latest Xeons (Xeon 51xx and 53xx) are not based on the - Netburst core and shouldn't use this option. You can distingush them - using the cpu family field - in /proc/cpuinfo. Family 15 is a older Xeon, Family 6 a newer one - (this rule only applies to system that support EM64T) - -config MCORE2 - bool "Intel Core2 / newer Xeon" - help - Optimize for Intel Core2 and newer Xeons (51xx) - You can distingush the newer Xeons from the older ones using - the cpu family field in /proc/cpuinfo. 15 is a older Xeon - (use CONFIG_MPSC then), 6 is a newer one. This rule only - applies to CPUs that support EM64T. config GENERIC_CPU bool "Generic-x86-64" help Generic x86-64 CPU. - Run equally well on all x86-64 CPUs. endchoice @@ -164,12 +149,12 @@ endchoice config X86_L1_CACHE_BYTES int default "128" if GENERIC_CPU || MPSC - default "64" if MK8 || MCORE2 + default "64" if MK8 config X86_L1_CACHE_SHIFT int default "7" if GENERIC_CPU || MPSC - default "6" if MK8 || MCORE2 + default "6" if MK8 config X86_INTERNODE_CACHE_BYTES int @@ -359,6 +344,11 @@ config ARCH_DISCONTIGMEM_ENABLE depends on NUMA default y + +config ARCH_DISCONTIGMEM_ENABLE + def_bool y + depends on NUMA + config ARCH_DISCONTIGMEM_DEFAULT def_bool y depends on NUMA @@ -465,17 +455,6 @@ config CALGARY_IOMMU Normally the kernel will make the right choice by itself. If unsure, say Y. -config CALGARY_IOMMU_ENABLED_BY_DEFAULT - bool "Should Calgary be enabled by default?" - default y - depends on CALGARY_IOMMU - help - Should Calgary be enabled by default? if you choose 'y', Calgary - will be used (if it exists). If you choose 'n', Calgary will not be - used even if it exists. If you choose 'n' and would like to use - Calgary anyway, pass 'iommu=calgary' on the kernel command line. - If unsure, say Y. - # need this always selected by IOMMU for the VIA workaround config SWIOTLB bool diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile index b471b8550d03..6e38d4daeed7 100644 --- a/trunk/arch/x86_64/Makefile +++ b/trunk/arch/x86_64/Makefile @@ -30,10 +30,6 @@ cflags-y := cflags-kernel-y := cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) -# gcc doesn't support -march=core2 yet as of gcc 4.3, but I hope it -# will eventually. Use -mtune=generic as fallback -cflags-$(CONFIG_MCORE2) += \ - $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) cflags-y += -m64 diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 96f226cfb339..0f5d44e86be5 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-git7 -# Wed Dec 6 23:50:47 2006 +# Linux kernel version: 2.6.19-rc2-git4 +# Sat Oct 21 03:38:52 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -47,14 +47,13 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set -CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -88,7 +87,9 @@ CONFIG_STOP_MACHINE=y # Block layer # CONFIG_BLOCK=y +CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set # # IO Schedulers @@ -110,11 +111,10 @@ CONFIG_X86_PC=y # CONFIG_X86_VSMP is not set # CONFIG_MK8 is not set # CONFIG_MPSC is not set -CONFIG_MCORE2=y -# CONFIG_GENERIC_CPU is not set -CONFIG_X86_L1_CACHE_BYTES=64 -CONFIG_X86_L1_CACHE_SHIFT=6 -CONFIG_X86_INTERNODE_CACHE_BYTES=64 +CONFIG_GENERIC_CPU=y +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y # CONFIG_MICROCODE is not set @@ -322,7 +322,6 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -625,7 +624,6 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set @@ -797,7 +795,6 @@ CONFIG_BNX2=y CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set # CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -930,6 +927,10 @@ CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# CONFIG_AGP=y CONFIG_AGP_AMD64=y CONFIG_AGP_INTEL=y @@ -1134,7 +1135,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set -# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1212,7 +1212,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set CONFIG_USB_MON=y diff --git a/trunk/arch/x86_64/ia32/ia32_binfmt.c b/trunk/arch/x86_64/ia32/ia32_binfmt.c index 543ef4f405e9..82ef182de6ae 100644 --- a/trunk/arch/x86_64/ia32/ia32_binfmt.c +++ b/trunk/arch/x86_64/ia32/ia32_binfmt.c @@ -305,6 +305,8 @@ MODULE_AUTHOR("Eric Youngdale, Andi Kleen"); #undef MODULE_DESCRIPTION #undef MODULE_AUTHOR +#define elf_addr_t __u32 + static void elf32_init(struct pt_regs *); #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 @@ -349,7 +351,7 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, bprm->loader += stack_base; bprm->exec += stack_base; - mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!mpnt) return -ENOMEM; diff --git a/trunk/arch/x86_64/ia32/ia32_signal.c b/trunk/arch/x86_64/ia32/ia32_signal.c index ff499ef2a1ba..0e0a266d976f 100644 --- a/trunk/arch/x86_64/ia32/ia32_signal.c +++ b/trunk/arch/x86_64/ia32/ia32_signal.c @@ -584,11 +584,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->rdx = (unsigned long) &frame->info; regs->rcx = (unsigned long) &frame->uc; - /* Make -mregparm=3 work */ - regs->rax = sig; - regs->rdx = (unsigned long) &frame->info; - regs->rcx = (unsigned long) &frame->uc; - asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); diff --git a/trunk/arch/x86_64/ia32/syscall32.c b/trunk/arch/x86_64/ia32/syscall32.c index 3e5ed20cba45..3a01329473ab 100644 --- a/trunk/arch/x86_64/ia32/syscall32.c +++ b/trunk/arch/x86_64/ia32/syscall32.c @@ -49,7 +49,7 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) struct mm_struct *mm = current->mm; int ret; - vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!vma) return -ENOMEM; diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index 124b2d27b4ac..4d9d5ed942b2 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -46,12 +45,6 @@ int apic_calibrate_pmtmr __initdata; int disable_apic_timer __initdata; -static struct resource *ioapic_resources; -static struct resource lapic_resource = { - .name = "Local APIC", - .flags = IORESOURCE_MEM | IORESOURCE_BUSY, -}; - /* * cpu_mask that denotes the CPUs that needs timer interrupt coming in as * IPIs in place of local APIC timers @@ -140,6 +133,7 @@ void clear_local_APIC(void) apic_write(APIC_LVTERR, APIC_LVT_MASKED); if (maxlvt >= 4) apic_write(APIC_LVTPC, APIC_LVT_MASKED); + v = GET_APIC_VERSION(apic_read(APIC_LVR)); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); } @@ -458,30 +452,23 @@ static struct { static int lapic_suspend(struct sys_device *dev, pm_message_t state) { unsigned long flags; - int maxlvt; if (!apic_pm_state.active) return 0; - maxlvt = get_maxlvt(); - apic_pm_state.apic_id = apic_read(APIC_ID); apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); apic_pm_state.apic_ldr = apic_read(APIC_LDR); apic_pm_state.apic_dfr = apic_read(APIC_DFR); apic_pm_state.apic_spiv = apic_read(APIC_SPIV); apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); - if (maxlvt >= 4) - apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); + apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); -#ifdef CONFIG_X86_MCE_INTEL - if (maxlvt >= 5) - apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); -#endif + apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); local_irq_save(flags); disable_local_APIC(); local_irq_restore(flags); @@ -492,13 +479,10 @@ static int lapic_resume(struct sys_device *dev) { unsigned int l, h; unsigned long flags; - int maxlvt; if (!apic_pm_state.active) return 0; - maxlvt = get_maxlvt(); - local_irq_save(flags); rdmsr(MSR_IA32_APICBASE, l, h); l &= ~MSR_IA32_APICBASE_BASE; @@ -512,12 +496,8 @@ static int lapic_resume(struct sys_device *dev) apic_write(APIC_SPIV, apic_pm_state.apic_spiv); apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); -#ifdef CONFIG_X86_MCE_INTEL - if (maxlvt >= 5) - apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); -#endif - if (maxlvt >= 4) - apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); + apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); + apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); apic_write(APIC_TMICT, apic_pm_state.apic_tmict); @@ -605,64 +585,6 @@ static int __init detect_init_APIC (void) return 0; } -#ifdef CONFIG_X86_IO_APIC -static struct resource * __init ioapic_setup_resources(void) -{ -#define IOAPIC_RESOURCE_NAME_SIZE 11 - unsigned long n; - struct resource *res; - char *mem; - int i; - - if (nr_ioapics <= 0) - return NULL; - - n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); - n *= nr_ioapics; - - mem = alloc_bootmem(n); - res = (void *)mem; - - if (mem != NULL) { - memset(mem, 0, n); - mem += sizeof(struct resource) * nr_ioapics; - - for (i = 0; i < nr_ioapics; i++) { - res[i].name = mem; - res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; - sprintf(mem, "IOAPIC %u", i); - mem += IOAPIC_RESOURCE_NAME_SIZE; - } - } - - ioapic_resources = res; - - return res; -} - -static int __init ioapic_insert_resources(void) -{ - int i; - struct resource *r = ioapic_resources; - - if (!r) { - printk("IO APIC resources could be not be allocated.\n"); - return -1; - } - - for (i = 0; i < nr_ioapics; i++) { - insert_resource(&iomem_resource, r); - r++; - } - - return 0; -} - -/* Insert the IO APIC resources after PCI initialization has occured to handle - * IO APICS that are mapped in on a BAR in PCI space. */ -late_initcall(ioapic_insert_resources); -#endif - void __init init_apic_mappings(void) { unsigned long apic_phys; @@ -682,11 +604,6 @@ void __init init_apic_mappings(void) apic_mapped = 1; apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); - /* Put local APIC into the resource map. */ - lapic_resource.start = apic_phys; - lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; - insert_resource(&iomem_resource, &lapic_resource); - /* * Fetch the APIC ID of the BSP in case we have a * default configuration (or the MP table is broken). @@ -696,9 +613,7 @@ void __init init_apic_mappings(void) { unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; int i; - struct resource *ioapic_res; - ioapic_res = ioapic_setup_resources(); for (i = 0; i < nr_ioapics; i++) { if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; @@ -710,12 +625,6 @@ void __init init_apic_mappings(void) apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", __fix_to_virt(idx), ioapic_phys); idx++; - - if (ioapic_res != NULL) { - ioapic_res->start = ioapic_phys; - ioapic_res->end = ioapic_phys + (4 * 1024) - 1; - ioapic_res++; - } } } } @@ -735,9 +644,10 @@ void __init init_apic_mappings(void) static void __setup_APIC_LVTT(unsigned int clocks) { - unsigned int lvtt_value, tmp_value; + unsigned int lvtt_value, tmp_value, ver; int cpu = smp_processor_id(); + ver = GET_APIC_VERSION(apic_read(APIC_LVR)); lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) diff --git a/trunk/arch/x86_64/kernel/crash.c b/trunk/arch/x86_64/kernel/crash.c index 95a7a2c13131..3525f884af82 100644 --- a/trunk/arch/x86_64/kernel/crash.c +++ b/trunk/arch/x86_64/kernel/crash.c @@ -28,6 +28,71 @@ /* This keeps a track of which one is crashing cpu. */ static int crashing_cpu; +static u32 *append_elf_note(u32 *buf, char *name, unsigned type, + void *data, size_t data_len) +{ + struct elf_note note; + + note.n_namesz = strlen(name) + 1; + note.n_descsz = data_len; + note.n_type = type; + memcpy(buf, ¬e, sizeof(note)); + buf += (sizeof(note) +3)/4; + memcpy(buf, name, note.n_namesz); + buf += (note.n_namesz + 3)/4; + memcpy(buf, data, note.n_descsz); + buf += (note.n_descsz + 3)/4; + + return buf; +} + +static void final_note(u32 *buf) +{ + struct elf_note note; + + note.n_namesz = 0; + note.n_descsz = 0; + note.n_type = 0; + memcpy(buf, ¬e, sizeof(note)); +} + +static void crash_save_this_cpu(struct pt_regs *regs, int cpu) +{ + struct elf_prstatus prstatus; + u32 *buf; + + if ((cpu < 0) || (cpu >= NR_CPUS)) + return; + + /* Using ELF notes here is opportunistic. + * I need a well defined structure format + * for the data I pass, and I need tags + * on the data to indicate what information I have + * squirrelled away. ELF notes happen to provide + * all of that, no need to invent something new. + */ + + buf = (u32*)per_cpu_ptr(crash_notes, cpu); + + if (!buf) + return; + + memset(&prstatus, 0, sizeof(prstatus)); + prstatus.pr_pid = current->pid; + elf_core_copy_regs(&prstatus.pr_reg, regs); + buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, + sizeof(prstatus)); + final_note(buf); +} + +static void crash_save_self(struct pt_regs *regs) +{ + int cpu; + + cpu = smp_processor_id(); + crash_save_this_cpu(regs, cpu); +} + #ifdef CONFIG_SMP static atomic_t waiting_for_crash_ipi; @@ -52,7 +117,7 @@ static int crash_nmi_callback(struct notifier_block *self, return NOTIFY_STOP; local_irq_disable(); - crash_save_cpu(regs, cpu); + crash_save_this_cpu(regs, cpu); disable_local_APIC(); atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ @@ -131,5 +196,5 @@ void machine_crash_shutdown(struct pt_regs *regs) disable_IO_APIC(); - crash_save_cpu(regs, smp_processor_id()); + crash_save_self(regs); } diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c index 829698f6d049..68273bff58cc 100644 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ b/trunk/arch/x86_64/kernel/early-quirks.c @@ -69,18 +69,11 @@ static void nvidia_bugs(void) static void ati_bugs(void) { -} - -static void intel_bugs(void) -{ - u16 device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); - -#ifdef CONFIG_SMP - if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || - device == PCI_DEVICE_ID_INTEL_E7520_MCH || - device == PCI_DEVICE_ID_INTEL_E7525_MCH) - quirk_intel_irqbalance(); -#endif + if (timer_over_8254 == 1) { + timer_over_8254 = 0; + printk(KERN_INFO + "ATI board detected. Disabling timer routing over 8254.\n"); + } } struct chipset { @@ -92,7 +85,6 @@ static struct chipset early_qrk[] = { { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, - { PCI_VENDOR_ID_INTEL, intel_bugs}, {} }; diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index 601d332c4b79..7d401b00d822 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -230,6 +230,7 @@ ENTRY(system_call) CFI_REL_OFFSET rip,RIP-ARGOFFSET GET_THREAD_INFO(%rcx) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx) + CFI_REMEMBER_STATE jnz tracesys cmpq $__NR_syscall_max,%rax ja badsys @@ -240,6 +241,7 @@ ENTRY(system_call) * Syscall return path ending with SYSRET (fast path) * Has incomplete stack frame and undefined top of stack. */ + .globl ret_from_sys_call ret_from_sys_call: movl $_TIF_ALLWORK_MASK,%edi /* edi: flagmask */ @@ -249,8 +251,8 @@ sysret_check: TRACE_IRQS_OFF movl threadinfo_flags(%rcx),%edx andl %edi,%edx - jnz sysret_careful CFI_REMEMBER_STATE + jnz sysret_careful /* * sysretq will re-enable interrupts: */ @@ -263,10 +265,10 @@ sysret_check: swapgs sysretq - CFI_RESTORE_STATE /* Handle reschedules */ /* edx: work, edi: workmask */ sysret_careful: + CFI_RESTORE_STATE bt $TIF_NEED_RESCHED,%edx jnc sysret_signal TRACE_IRQS_ON @@ -304,6 +306,7 @@ badsys: /* Do syscall tracing */ tracesys: + CFI_RESTORE_STATE SAVE_REST movq $-ENOSYS,RAX(%rsp) FIXUP_TOP_OF_STACK %rdi @@ -319,13 +322,32 @@ tracesys: call *sys_call_table(,%rax,8) 1: movq %rax,RAX-ARGOFFSET(%rsp) /* Use IRET because user could have changed frame */ + jmp int_ret_from_sys_call + CFI_ENDPROC +END(system_call) /* * Syscall return path ending with IRET. * Has correct top of stack, but partial stack frame. - */ - .globl int_ret_from_sys_call -int_ret_from_sys_call: + */ +ENTRY(int_ret_from_sys_call) + CFI_STARTPROC simple + CFI_SIGNAL_FRAME + CFI_DEF_CFA rsp,SS+8-ARGOFFSET + /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ + CFI_REL_OFFSET rsp,RSP-ARGOFFSET + /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/ + /*CFI_REL_OFFSET cs,CS-ARGOFFSET*/ + CFI_REL_OFFSET rip,RIP-ARGOFFSET + CFI_REL_OFFSET rdx,RDX-ARGOFFSET + CFI_REL_OFFSET rcx,RCX-ARGOFFSET + CFI_REL_OFFSET rax,RAX-ARGOFFSET + CFI_REL_OFFSET rdi,RDI-ARGOFFSET + CFI_REL_OFFSET rsi,RSI-ARGOFFSET + CFI_REL_OFFSET r8,R8-ARGOFFSET + CFI_REL_OFFSET r9,R9-ARGOFFSET + CFI_REL_OFFSET r10,R10-ARGOFFSET + CFI_REL_OFFSET r11,R11-ARGOFFSET cli TRACE_IRQS_OFF testl $3,CS-ARGOFFSET(%rsp) @@ -372,6 +394,8 @@ int_very_careful: popq %rdi CFI_ADJUST_CFA_OFFSET -8 andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi + cli + TRACE_IRQS_OFF jmp int_restore_rest int_signal: @@ -387,7 +411,7 @@ int_restore_rest: TRACE_IRQS_OFF jmp int_with_check CFI_ENDPROC -END(system_call) +END(int_ret_from_sys_call) /* * Certain special system calls that need to save a complete full stack frame. diff --git a/trunk/arch/x86_64/kernel/genapic.c b/trunk/arch/x86_64/kernel/genapic.c index b007433f96bb..8e78a75d1866 100644 --- a/trunk/arch/x86_64/kernel/genapic.c +++ b/trunk/arch/x86_64/kernel/genapic.c @@ -33,7 +33,7 @@ extern struct genapic apic_flat; extern struct genapic apic_physflat; struct genapic *genapic = &apic_flat; -struct genapic *genapic_force; + /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. @@ -46,13 +46,6 @@ void __init clustered_apic_check(void) u8 cluster_cnt[NUM_APIC_CLUSTERS]; int max_apic = 0; - /* genapic selection can be forced because of certain quirks. - */ - if (genapic_force) { - genapic = genapic_force; - goto print; - } - #if defined(CONFIG_ACPI) /* * Some x86_64 machines use physical APIC mode regardless of how many diff --git a/trunk/arch/x86_64/kernel/head64.c b/trunk/arch/x86_64/kernel/head64.c index cc230b93cd1c..9561eb3c5b5c 100644 --- a/trunk/arch/x86_64/kernel/head64.c +++ b/trunk/arch/x86_64/kernel/head64.c @@ -57,12 +57,10 @@ void __init x86_64_start_kernel(char * real_mode_data) { int i; - /* clear bss before set_intr_gate with early_idt_handler */ - clear_bss(); - - for (i = 0; i < IDT_ENTRIES; i++) + for (i = 0; i < 256; i++) set_intr_gate(i, early_idt_handler); asm volatile("lidt %0" :: "m" (idt_descr)); + clear_bss(); early_printk("Kernel alive\n"); diff --git a/trunk/arch/x86_64/kernel/i387.c b/trunk/arch/x86_64/kernel/i387.c index 1d58c13bc6bc..3aa1e9bb781d 100644 --- a/trunk/arch/x86_64/kernel/i387.c +++ b/trunk/arch/x86_64/kernel/i387.c @@ -82,8 +82,11 @@ int save_i387(struct _fpstate __user *buf) struct task_struct *tsk = current; int err = 0; - BUILD_BUG_ON(sizeof(struct user_i387_struct) != - sizeof(tsk->thread.i387.fxsave)); + { + extern void bad_user_i387_struct(void); + if (sizeof(struct user_i387_struct) != sizeof(tsk->thread.i387.fxsave)) + bad_user_i387_struct(); + } if ((unsigned long)buf % 16) printk("save_i387: bad fpstate %p\n",buf); diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index d73c79e821f1..c4ef801b765b 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -76,8 +76,7 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf) IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) -/* for the irq vectors */ -static void (*interrupt[NR_VECTORS - FIRST_EXTERNAL_VECTOR])(void) = { +void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x2), IRQLIST_16(0x3), IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 2a1dcd5f69c2..c80081a6ba41 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -55,6 +55,10 @@ int sis_apic_bug; /* not actually supported, dummy for compile */ static int no_timer_check; +static int disable_timer_pin_1 __initdata; + +int timer_over_8254 __initdata = 1; + /* Where if anywhere is the i8259 connect in external int mode */ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; @@ -174,20 +178,14 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) * the interrupt, and we need to make sure the entry is fully populated * before that happens. */ -static void -__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) { + unsigned long flags; union entry_union eu; eu.entry = e; + spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x11 + 2*pin, eu.w2); io_apic_write(apic, 0x10 + 2*pin, eu.w1); -} - -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - __ioapic_write_entry(apic, pin, e); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -350,6 +348,29 @@ static int __init disable_ioapic_setup(char *str) } early_param("noapic", disable_ioapic_setup); +/* Actually the next is obsolete, but keep it for paranoid reasons -AK */ +static int __init disable_timer_pin_setup(char *arg) +{ + disable_timer_pin_1 = 1; + return 1; +} +__setup("disable_timer_pin_1", disable_timer_pin_setup); + +static int __init setup_disable_8254_timer(char *s) +{ + timer_over_8254 = -1; + return 1; +} +static int __init setup_enable_8254_timer(char *s) +{ + timer_over_8254 = 2; + return 1; +} + +__setup("disable_8254_timer", setup_disable_8254_timer); +__setup("enable_8254_timer", setup_enable_8254_timer); + + /* * Find the IRQ entry number of a certain pin. */ @@ -729,22 +750,6 @@ static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) return vector; } -static void __clear_irq_vector(int irq) -{ - cpumask_t mask; - int cpu, vector; - - BUG_ON(!irq_vector[irq]); - - vector = irq_vector[irq]; - cpus_and(mask, irq_domain[irq], cpu_online_map); - for_each_cpu_mask(cpu, mask) - per_cpu(vector_irq, cpu)[vector] = -1; - - irq_vector[irq] = 0; - irq_domain[irq] = CPU_MASK_NONE; -} - void __setup_vector_irq(int cpu) { /* Initialize vector_irq on a new cpu */ @@ -789,66 +794,28 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) handle_edge_irq, "edge"); } } -static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq) -{ - struct IO_APIC_route_entry entry; - int vector; - unsigned long flags; - - - /* - * add it to the IO-APIC irq-routing table: - */ - memset(&entry,0,sizeof(entry)); - - entry.delivery_mode = INT_DELIVERY_MODE; - entry.dest_mode = INT_DEST_MODE; - entry.mask = 0; /* enable IRQ */ - entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); - - entry.trigger = irq_trigger(idx); - entry.polarity = irq_polarity(idx); - - if (irq_trigger(idx)) { - entry.trigger = 1; - entry.mask = 1; - entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); - } - - if (!apic && !IO_APIC_IRQ(irq)) - return; - - if (IO_APIC_IRQ(irq)) { - cpumask_t mask; - vector = assign_irq_vector(irq, TARGET_CPUS, &mask); - if (vector < 0) - return; - - entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask); - entry.vector = vector; - - ioapic_register_intr(irq, vector, IOAPIC_AUTO); - if (!apic && (irq < 16)) - disable_8259A_irq(irq); - } - - ioapic_write_entry(apic, pin, entry); - - spin_lock_irqsave(&ioapic_lock, flags); - set_native_irq_info(irq, TARGET_CPUS); - spin_unlock_irqrestore(&ioapic_lock, flags); - -} static void __init setup_IO_APIC_irqs(void) { - int apic, pin, idx, irq, first_notcon = 1; + struct IO_APIC_route_entry entry; + int apic, pin, idx, irq, first_notcon = 1, vector; + unsigned long flags; apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); for (apic = 0; apic < nr_ioapics; apic++) { for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { + /* + * add it to the IO-APIC irq-routing table: + */ + memset(&entry,0,sizeof(entry)); + + entry.delivery_mode = INT_DELIVERY_MODE; + entry.dest_mode = INT_DEST_MODE; + entry.mask = 0; /* enable IRQ */ + entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); + idx = find_irq_entry(apic,pin,mp_INT); if (idx == -1) { if (first_notcon) { @@ -859,11 +826,39 @@ static void __init setup_IO_APIC_irqs(void) continue; } + entry.trigger = irq_trigger(idx); + entry.polarity = irq_polarity(idx); + + if (irq_trigger(idx)) { + entry.trigger = 1; + entry.mask = 1; + entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); + } + irq = pin_2_irq(idx, apic, pin); add_pin_to_irq(irq, apic, pin); - setup_IO_APIC_irq(apic, pin, idx, irq); + if (!apic && !IO_APIC_IRQ(irq)) + continue; + + if (IO_APIC_IRQ(irq)) { + cpumask_t mask; + vector = assign_irq_vector(irq, TARGET_CPUS, &mask); + if (vector < 0) + continue; + + entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask); + entry.vector = vector; + + ioapic_register_intr(irq, vector, IOAPIC_AUTO); + if (!apic && (irq < 16)) + disable_8259A_irq(irq); + } + ioapic_write_entry(apic, pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + set_native_irq_info(irq, TARGET_CPUS); + spin_unlock_irqrestore(&ioapic_lock, flags); } } @@ -1568,33 +1563,10 @@ static inline void unlock_ExtINT_logic(void) * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ * is so screwy. Thanks to Brian Perkins for testing/hacking this beast * fanatically on his truly buggy board. + * + * FIXME: really need to revamp this for modern platforms only. */ - -static int try_apic_pin(int apic, int pin, char *msg) -{ - apic_printk(APIC_VERBOSE, KERN_INFO - "..TIMER: trying IO-APIC=%d PIN=%d %s", - apic, pin, msg); - - /* - * Ok, does IRQ0 through the IOAPIC work? - */ - if (!no_timer_check && timer_irq_works()) { - nmi_watchdog_default(); - if (nmi_watchdog == NMI_IO_APIC) { - disable_8259A_irq(0); - setup_nmi(); - enable_8259A_irq(0); - } - return 1; - } - clear_IO_APIC_pin(apic, pin); - apic_printk(APIC_QUIET, KERN_ERR " .. failed\n"); - return 0; -} - -/* The function from hell */ -static void check_timer(void) +static inline void check_timer(void) { int apic1, pin1, apic2, pin2; int vector; @@ -1615,43 +1587,61 @@ static void check_timer(void) */ apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); + if (timer_over_8254 > 0) + enable_8259A_irq(0); pin1 = find_isa_irq_pin(0, mp_INT); apic1 = find_isa_irq_apic(0, mp_INT); pin2 = ioapic_i8259.pin; apic2 = ioapic_i8259.apic; - /* Do this first, otherwise we get double interrupts on ATI boards */ - if ((pin1 != -1) && try_apic_pin(apic1, pin1,"with 8259 IRQ0 disabled")) - return; + apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", + vector, apic1, pin1, apic2, pin2); - /* Now try again with IRQ0 8259A enabled. - Assumes timer is on IO-APIC 0 ?!? */ - enable_8259A_irq(0); - unmask_IO_APIC_irq(0); - if (try_apic_pin(apic1, pin1, "with 8259 IRQ0 enabled")) - return; - disable_8259A_irq(0); - - /* Always try pin0 and pin2 on APIC 0 to handle buggy timer overrides - on Nvidia boards */ - if (!(apic1 == 0 && pin1 == 0) && - try_apic_pin(0, 0, "fallback with 8259 IRQ0 disabled")) - return; - if (!(apic1 == 0 && pin1 == 2) && - try_apic_pin(0, 2, "fallback with 8259 IRQ0 disabled")) - return; + if (pin1 != -1) { + /* + * Ok, does IRQ0 through the IOAPIC work? + */ + unmask_IO_APIC_irq(0); + if (!no_timer_check && timer_irq_works()) { + nmi_watchdog_default(); + if (nmi_watchdog == NMI_IO_APIC) { + disable_8259A_irq(0); + setup_nmi(); + enable_8259A_irq(0); + } + if (disable_timer_pin_1 > 0) + clear_IO_APIC_pin(0, pin1); + return; + } + clear_IO_APIC_pin(apic1, pin1); + apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: 8254 timer not " + "connected to IO-APIC\n"); + } - /* Then try pure 8259A routing on the 8259 as reported by BIOS*/ - enable_8259A_irq(0); + apic_printk(APIC_VERBOSE,KERN_INFO "...trying to set up timer (IRQ0) " + "through the 8259A ... "); if (pin2 != -1) { + apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...", + apic2, pin2); + /* + * legacy devices should be connected to IO APIC #0 + */ setup_ExtINT_IRQ0_pin(apic2, pin2, vector); - if (try_apic_pin(apic2,pin2,"8259A broadcast ExtINT from BIOS")) + if (timer_irq_works()) { + apic_printk(APIC_VERBOSE," works.\n"); + nmi_watchdog_default(); + if (nmi_watchdog == NMI_IO_APIC) { + setup_nmi(); + } return; + } + /* + * Cleanup, just in case ... + */ + clear_IO_APIC_pin(apic2, pin2); } - - /* Tried all possibilities to go through the IO-APIC. Now come the - really cheesy fallbacks. */ + apic_printk(APIC_VERBOSE," failed.\n"); if (nmi_watchdog == NMI_IO_APIC) { printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); @@ -1847,7 +1837,7 @@ void destroy_irq(unsigned int irq) dynamic_irq_cleanup(irq); spin_lock_irqsave(&vector_lock, flags); - __clear_irq_vector(irq); + irq_vector[irq] = 0; spin_unlock_irqrestore(&vector_lock, flags); } @@ -2149,15 +2139,7 @@ void __init setup_ioapic_dest(void) if (irq_entry == -1) continue; irq = pin_2_irq(irq_entry, ioapic, pin); - - /* setup_IO_APIC_irqs could fail to get vector for some device - * when you have too many devices, because at that time only boot - * cpu is online. - */ - if(!irq_vector[irq]) - setup_IO_APIC_irq(ioapic, pin, irq_entry, irq); - else - set_ioapic_affinity_irq(irq, TARGET_CPUS); + set_ioapic_affinity_irq(irq, TARGET_CPUS); } } diff --git a/trunk/arch/x86_64/kernel/irq.c b/trunk/arch/x86_64/kernel/irq.c index 0c06af6c13bc..e46c55856d40 100644 --- a/trunk/arch/x86_64/kernel/irq.c +++ b/trunk/arch/x86_64/kernel/irq.c @@ -120,7 +120,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) if (likely(irq < NR_IRQS)) generic_handle_irq(irq); - else if (printk_ratelimit()) + else printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n", __func__, smp_processor_id(), vector); diff --git a/trunk/arch/x86_64/kernel/kprobes.c b/trunk/arch/x86_64/kernel/kprobes.c index 209c8c0bec71..ac241567e682 100644 --- a/trunk/arch/x86_64/kernel/kprobes.c +++ b/trunk/arch/x86_64/kernel/kprobes.c @@ -224,7 +224,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn, 0); + free_insn_slot(p->ainsn.insn); mutex_unlock(&kprobe_mutex); } diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index ac085038af29..c7587fc39015 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -641,6 +641,7 @@ static __cpuinit int mce_create_device(unsigned int cpu) return err; } +#ifdef CONFIG_HOTPLUG_CPU static void mce_remove_device(unsigned int cpu) { int i; @@ -651,7 +652,6 @@ static void mce_remove_device(unsigned int cpu) sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_tolerant); sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_check_interval); sysdev_unregister(&per_cpu(device_mce,cpu)); - memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject)); } /* Get notified when a cpu comes on/off. Be hotplug friendly. */ @@ -674,6 +674,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) static struct notifier_block mce_cpu_notifier = { .notifier_call = mce_cpu_callback, }; +#endif static __init int mce_init_device(void) { diff --git a/trunk/arch/x86_64/kernel/mce_amd.c b/trunk/arch/x86_64/kernel/mce_amd.c index fa09debad4b7..883fe747f64c 100644 --- a/trunk/arch/x86_64/kernel/mce_amd.c +++ b/trunk/arch/x86_64/kernel/mce_amd.c @@ -551,6 +551,7 @@ static __cpuinit int threshold_create_device(unsigned int cpu) return err; } +#ifdef CONFIG_HOTPLUG_CPU /* * let's be hotplug friendly. * in case of multiple core processors, the first core always takes ownership @@ -593,14 +594,12 @@ static void threshold_remove_bank(unsigned int cpu, int bank) sprintf(name, "threshold_bank%i", bank); -#ifdef CONFIG_SMP /* sibling symlink */ if (shared_bank[bank] && b->blocks->cpu != cpu) { sysfs_remove_link(&per_cpu(device_mce, cpu).kobj, name); per_cpu(threshold_banks, cpu)[bank] = NULL; return; } -#endif /* remove all sibling symlinks before unregistering */ for_each_cpu_mask(i, b->cpus) { @@ -657,6 +656,7 @@ static int threshold_cpu_callback(struct notifier_block *nfb, static struct notifier_block threshold_cpu_notifier = { .notifier_call = threshold_cpu_callback, }; +#endif /* CONFIG_HOTPLUG_CPU */ static __init int threshold_init_device(void) { diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 08072568847d..b147ab19fbd4 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -35,6 +35,8 @@ int smp_found_config; unsigned int __initdata maxcpus = NR_CPUS; +int acpi_found_madt; + /* * Various Linux-internal data structures created from the * MP-table. diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 27e95e7922c1..7af9cb3e2d99 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -12,15 +12,14 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ -#include #include #include #include #include #include +#include #include #include -#include #include #include @@ -42,8 +41,6 @@ int panic_on_unrecovered_nmi; static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner); static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]); -static cpumask_t backtrace_mask = CPU_MASK_NONE; - /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ @@ -785,7 +782,6 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) { int sum; int touched = 0; - int cpu = smp_processor_id(); struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); u64 dummy; int rc=0; @@ -803,16 +799,6 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) touched = 1; } - if (cpu_isset(cpu, backtrace_mask)) { - static DEFINE_SPINLOCK(lock); /* Serialise the printks */ - - spin_lock(&lock); - printk("NMI backtrace for cpu %d\n", cpu); - dump_stack(); - spin_unlock(&lock); - cpu_clear(cpu, backtrace_mask); - } - #ifdef CONFIG_X86_MCE /* Could check oops_in_progress here too, but it's safer not too */ @@ -945,19 +931,6 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif -void __trigger_all_cpu_backtrace(void) -{ - int i; - - backtrace_mask = cpu_online_map; - /* Wait for up to 10 seconds for all CPUs to do the backtrace */ - for (i = 0; i < 10 * 1000; i++) { - if (cpus_empty(backtrace_mask)) - break; - mdelay(1); - } -} - EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); diff --git a/trunk/arch/x86_64/kernel/pci-calgary.c b/trunk/arch/x86_64/kernel/pci-calgary.c index 3215675ab128..37a770859e71 100644 --- a/trunk/arch/x86_64/kernel/pci-calgary.c +++ b/trunk/arch/x86_64/kernel/pci-calgary.c @@ -41,13 +41,6 @@ #include #include #include -#include - -#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT -int use_calgary __read_mostly = 1; -#else -int use_calgary __read_mostly = 0; -#endif /* CONFIG_CALGARY_DEFAULT_ENABLED */ #define PCI_DEVICE_ID_IBM_CALGARY 0x02a1 #define PCI_VENDOR_DEVICE_ID_CALGARY \ @@ -122,35 +115,14 @@ static const unsigned long phb_offsets[] = { 0xB000 /* PHB3 */ }; -/* PHB debug registers */ - -static const unsigned long phb_debug_offsets[] = { - 0x4000 /* PHB 0 DEBUG */, - 0x5000 /* PHB 1 DEBUG */, - 0x6000 /* PHB 2 DEBUG */, - 0x7000 /* PHB 3 DEBUG */ -}; - -/* - * STUFF register for each debug PHB, - * byte 1 = start bus number, byte 2 = end bus number - */ - -#define PHB_DEBUG_STUFF_OFFSET 0x0020 - unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; static int translate_empty_slots __read_mostly = 0; static int calgary_detected __read_mostly = 0; -static struct rio_table_hdr *rio_table_hdr __initdata; -static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; -static struct rio_detail *rio_devs[MAX_NUMNODES * 4] __initdata; - struct calgary_bus_info { void *tce_space; unsigned char translation_disabled; signed char phbid; - void __iomem *bbar; }; static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; @@ -503,11 +475,6 @@ static struct dma_mapping_ops calgary_dma_ops = { .unmap_sg = calgary_unmap_sg, }; -static inline void __iomem * busno_to_bbar(unsigned char num) -{ - return bus_info[num].bbar; -} - static inline int busno_to_phbid(unsigned char num) { return bus_info[num].phbid; @@ -653,9 +620,14 @@ static void __init calgary_reserve_peripheral_mem_2(struct pci_dev *dev) static void __init calgary_reserve_regions(struct pci_dev *dev) { unsigned int npages; + void __iomem *bbar; + unsigned char busnum; u64 start; struct iommu_table *tbl = dev->sysdata; + bbar = tbl->bbar; + busnum = dev->bus->number; + /* reserve bad_dma_address in case it's a legal address */ iommu_range_reserve(tbl, bad_dma_address, 1); @@ -768,7 +740,7 @@ static void __init calgary_increase_split_completion_timeout(void __iomem *bbar, { u64 val64; void __iomem *target; - unsigned int phb_shift = ~0; /* silence gcc */ + unsigned long phb_shift = -1; u64 mask; switch (busno_to_phbid(busnum)) { @@ -856,6 +828,33 @@ static void __init calgary_disable_translation(struct pci_dev *dev) del_timer_sync(&tbl->watchdog_timer); } +static inline unsigned int __init locate_register_space(struct pci_dev *dev) +{ + int rionodeid; + u32 address; + + /* + * Each Calgary has four busses. The first four busses (first Calgary) + * have RIO node ID 2, then the next four (second Calgary) have RIO + * node ID 3, the next four (third Calgary) have node ID 2 again, etc. + * We use a gross hack - relying on the dev->bus->number ordering, + * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1, + * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the + * second (id 3), and then it repeats modulo 14. + */ + rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2; + /* + * register space address calculation as follows: + * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase) + * ChassisBase is always zero for x366/x260/x460 + * RioNodeId is 2 for first Calgary, 3 for second Calgary + */ + address = START_ADDRESS - + (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) + + (0x100000) * (rionodeid - CHASSIS_BASE); + return address; +} + static void __init calgary_init_one_nontraslated(struct pci_dev *dev) { pci_dev_get(dev); @@ -865,15 +864,23 @@ static void __init calgary_init_one_nontraslated(struct pci_dev *dev) static int __init calgary_init_one(struct pci_dev *dev) { + u32 address; void __iomem *bbar; int ret; BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); - bbar = busno_to_bbar(dev->bus->number); + address = locate_register_space(dev); + /* map entire 1MB of Calgary config space */ + bbar = ioremap_nocache(address, 1024 * 1024); + if (!bbar) { + ret = -ENODATA; + goto done; + } + ret = calgary_setup_tar(dev, bbar); if (ret) - goto done; + goto iounmap; pci_dev_get(dev); dev->bus->self = dev; @@ -881,66 +888,17 @@ static int __init calgary_init_one(struct pci_dev *dev) return 0; +iounmap: + iounmap(bbar); done: return ret; } -static int __init calgary_locate_bbars(void) -{ - int ret; - int rioidx, phb, bus; - void __iomem *bbar; - void __iomem *target; - unsigned long offset; - u8 start_bus, end_bus; - u32 val; - - ret = -ENODATA; - for (rioidx = 0; rioidx < rio_table_hdr->num_rio_dev; rioidx++) { - struct rio_detail *rio = rio_devs[rioidx]; - - if ((rio->type != COMPAT_CALGARY) && (rio->type != ALT_CALGARY)) - continue; - - /* map entire 1MB of Calgary config space */ - bbar = ioremap_nocache(rio->BBAR, 1024 * 1024); - if (!bbar) - goto error; - - for (phb = 0; phb < PHBS_PER_CALGARY; phb++) { - offset = phb_debug_offsets[phb] | PHB_DEBUG_STUFF_OFFSET; - target = calgary_reg(bbar, offset); - - val = be32_to_cpu(readl(target)); - start_bus = (u8)((val & 0x00FF0000) >> 16); - end_bus = (u8)((val & 0x0000FF00) >> 8); - for (bus = start_bus; bus <= end_bus; bus++) { - bus_info[bus].bbar = bbar; - bus_info[bus].phbid = phb; - } - } - } - - return 0; - -error: - /* scan bus_info and iounmap any bbars we previously ioremap'd */ - for (bus = 0; bus < ARRAY_SIZE(bus_info); bus++) - if (bus_info[bus].bbar) - iounmap(bus_info[bus].bbar); - - return ret; -} - static int __init calgary_init(void) { - int ret; + int ret = -ENODEV; struct pci_dev *dev = NULL; - ret = calgary_locate_bbars(); - if (ret) - return ret; - do { dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CALGARY, @@ -963,7 +921,7 @@ static int __init calgary_init(void) error: do { - dev = pci_get_device_reverse(PCI_VENDOR_ID_IBM, + dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CALGARY, dev); if (!dev) @@ -1004,56 +962,13 @@ static inline int __init determine_tce_table_size(u64 ram) return ret; } -static int __init build_detail_arrays(void) -{ - unsigned long ptr; - int i, scal_detail_size, rio_detail_size; - - if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ - printk(KERN_WARNING - "Calgary: MAX_NUMNODES too low! Defined as %d, " - "but system has %d nodes.\n", - MAX_NUMNODES, rio_table_hdr->num_scal_dev); - return -ENODEV; - } - - switch (rio_table_hdr->version){ - case 2: - scal_detail_size = 11; - rio_detail_size = 13; - break; - case 3: - scal_detail_size = 12; - rio_detail_size = 15; - break; - default: - printk(KERN_WARNING - "Calgary: Invalid Rio Grande Table Version: %d\n", - rio_table_hdr->version); - return -EPROTO; - } - - ptr = ((unsigned long)rio_table_hdr) + 3; - for (i = 0; i < rio_table_hdr->num_scal_dev; - i++, ptr += scal_detail_size) - scal_devs[i] = (struct scal_detail *)ptr; - - for (i = 0; i < rio_table_hdr->num_rio_dev; - i++, ptr += rio_detail_size) - rio_devs[i] = (struct rio_detail *)ptr; - - return 0; -} - void __init detect_calgary(void) { u32 val; int bus; void *tbl; int calgary_found = 0; - unsigned long ptr; - int offset; - int ret; + int phb = -1; /* * if the user specified iommu=off or iommu=soft or we found @@ -1062,47 +977,25 @@ void __init detect_calgary(void) if (swiotlb || no_iommu || iommu_detected) return; - if (!use_calgary) - return; - if (!early_pci_allowed()) return; - ptr = (unsigned long)phys_to_virt(get_bios_ebda()); - - rio_table_hdr = NULL; - offset = 0x180; - while (offset) { - /* The block id is stored in the 2nd word */ - if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){ - /* set the pointer past the offset & block id */ - rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4); - break; - } - /* The next offset is stored in the 1st word. 0 means no more */ - offset = *((unsigned short *)(ptr + offset)); - } - if (!rio_table_hdr) { - printk(KERN_ERR "Calgary: Unable to locate " - "Rio Grande Table in EBDA - bailing!\n"); - return; - } - - ret = build_detail_arrays(); - if (ret) { - printk(KERN_ERR "Calgary: build_detail_arrays ret %d\n", ret); - return; - } - specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { int dev; struct calgary_bus_info *info = &bus_info[bus]; + info->phbid = -1; if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) continue; + /* + * There are 4 PHBs per Calgary chip. Set phb to which phb (0-3) + * it is connected to releative to the clagary chip. + */ + phb = (phb + 1) % PHBS_PER_CALGARY; + if (info->translation_disabled) continue; @@ -1117,6 +1010,7 @@ void __init detect_calgary(void) if (!tbl) goto cleanup; info->tce_space = tbl; + info->phbid = phb; calgary_found = 1; break; } diff --git a/trunk/arch/x86_64/kernel/pci-dma.c b/trunk/arch/x86_64/kernel/pci-dma.c index 683b7a5c1ab3..f8d857453f8a 100644 --- a/trunk/arch/x86_64/kernel/pci-dma.c +++ b/trunk/arch/x86_64/kernel/pci-dma.c @@ -296,11 +296,6 @@ __init int iommu_setup(char *p) gart_parse_options(p); #endif -#ifdef CONFIG_CALGARY_IOMMU - if (!strncmp(p, "calgary", 7)) - use_calgary = 1; -#endif /* CONFIG_CALGARY_IOMMU */ - p += strcspn(p, ","); if (*p == ',') ++p; diff --git a/trunk/arch/x86_64/kernel/pci-gart.c b/trunk/arch/x86_64/kernel/pci-gart.c index fc1960f1f243..16261a8a3303 100644 --- a/trunk/arch/x86_64/kernel/pci-gart.c +++ b/trunk/arch/x86_64/kernel/pci-gart.c @@ -601,9 +601,10 @@ void __init gart_iommu_init(void) (!force_iommu && end_pfn <= MAX_DMA32_PFN) || !iommu_aperture || (no_agp && init_k8_gatt(&info) < 0)) { + printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); if (end_pfn > MAX_DMA32_PFN) { printk(KERN_ERR "WARNING more than 4GB of memory " - "but GART IOMMU not available.\n" + "but IOMMU not available.\n" KERN_ERR "WARNING 32bit PCI may malfunction.\n"); } return; diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index a418ee4c8c62..7451a4c43c16 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -108,15 +108,17 @@ void exit_idle(void) */ static void default_idle(void) { + local_irq_enable(); + current_thread_info()->status &= ~TS_POLLING; smp_mb__after_clear_bit(); - local_irq_disable(); - if (!need_resched()) { - /* Enables interrupts one instruction before HLT. - x86 special cases this so there is no race. */ - safe_halt(); - } else - local_irq_enable(); + while (!need_resched()) { + local_irq_disable(); + if (!need_resched()) + safe_halt(); + else + local_irq_enable(); + } current_thread_info()->status |= TS_POLLING; } @@ -128,7 +130,15 @@ static void default_idle(void) static void poll_idle (void) { local_irq_enable(); - cpu_relax(); + + asm volatile( + "2:" + "testl %0,%1;" + "rep; nop;" + "je 2b;" + : : + "i" (_TIF_NEED_RESCHED), + "m" (current_thread_info()->flags)); } void cpu_idle_wait(void) @@ -209,12 +219,6 @@ void cpu_idle (void) idle = default_idle; if (cpu_is_offline(smp_processor_id())) play_dead(); - /* - * Idle routines should keep interrupts disabled - * from here on, until they go to idle. - * Otherwise, idle callbacks can misfire. - */ - local_irq_disable(); enter_idle(); idle(); /* In many cases the interrupt that ended idle @@ -252,16 +256,9 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) /* Default MONITOR/MWAIT with no hints, used for default C1 state */ static void mwait_idle(void) { - if (!need_resched()) { - __monitor((void *)¤t_thread_info()->flags, 0, 0); - smp_mb(); - if (!need_resched()) - __sti_mwait(0, 0); - else - local_irq_enable(); - } else { - local_irq_enable(); - } + local_irq_enable(); + while (!need_resched()) + mwait_idle_with_hints(0,0); } void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index af425a8049fb..fc944b5e8f4a 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -471,7 +471,8 @@ void __init setup_arch(char **cmdline_p) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { reserve_bootmem_generic(INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET; + initrd_start = + INITRD_START ? INITRD_START + PAGE_OFFSET : 0; initrd_end = initrd_start+INITRD_SIZE; } else { @@ -731,8 +732,11 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) /* Fix cpuid4 emulation for more */ num_cache_leaves = 3; - /* RDTSC can be speculated around */ - clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + /* When there is only one core no need to synchronize RDTSC */ + if (num_possible_cpus() == 1) + set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + else + clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -831,15 +835,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability); } - if (cpu_has_ds) { - unsigned int l1, l2; - rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); - if (!(l1 & (1<<11))) - set_bit(X86_FEATURE_BTS, c->x86_capability); - if (!(l1 & (1<<12))) - set_bit(X86_FEATURE_PEBS, c->x86_capability); - } - n = c->extended_cpuid_level; if (n >= 0x80000008) { unsigned eax = cpuid_eax(0x80000008); @@ -859,10 +854,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); if (c->x86 == 6) set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); - if (c->x86 == 15) - set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); - else - clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); c->x86_max_cores = intel_num_cpu_cores(c); srat_detect_node(); diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index af1ec4d23cf8..9f74c883568c 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -379,17 +379,12 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info, put_cpu(); return 0; } - - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); - spin_lock_bh(&call_lock); __smp_call_function_single(cpu, func, info, nonatomic, wait); spin_unlock_bh(&call_lock); put_cpu(); return 0; } -EXPORT_SYMBOL(smp_call_function_single); /* * this function sends a 'generic call function' IPI to all other CPUs diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index daf19332f0dd..9800147c4c68 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -60,7 +60,6 @@ #include #include #include -#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -1170,13 +1169,6 @@ int __cpuinit __cpu_up(unsigned int cpu) while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); - - if (num_online_cpus() > 8 && genapic == &apic_flat) { - printk(KERN_WARNING - "flat APIC routing can't be used with > 8 cpus\n"); - BUG(); - } - err = 0; return err; diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index a1641ffdffcf..0d65b22f229c 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -30,9 +30,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -108,7 +108,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) preempt_enable_no_resched(); } -int kstack_depth_to_print = 12; +static int kstack_depth_to_print = 12; #ifdef CONFIG_STACK_UNWIND static int call_trace = 1; #else @@ -225,25 +225,16 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) { struct ops_and_data *oad = (struct ops_and_data *)context; int n = 0; - unsigned long sp = UNW_SP(info); - if (arch_unw_user_mode(info)) - return -1; while (unwind(info) == 0 && UNW_PC(info)) { n++; oad->ops->address(oad->data, UNW_PC(info)); if (arch_unw_user_mode(info)) break; - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) - && sp > UNW_SP(info)) - break; - sp = UNW_SP(info); } return n; } -#define MSG(txt) ops->warning(data, txt) - /* * x86-64 can have upto three kernel stacks: * process stack @@ -257,12 +248,11 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) return p > t && p < t + THREAD_SIZE - 3; } -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, - unsigned long *stack, +void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack, struct stacktrace_ops *ops, void *data) { - const unsigned cpu = get_cpu(); - unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; + const unsigned cpu = smp_processor_id(); + unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned used = 0; struct thread_info *tinfo; @@ -278,30 +268,28 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, if (unwind_init_frame_info(&info, tsk, regs) == 0) unw_ret = dump_trace_unwind(&info, &oad); } else if (tsk == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, - &oad); + unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); else { if (unwind_init_blocked(&info, tsk) == 0) unw_ret = dump_trace_unwind(&info, &oad); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s", + ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if ((long)UNW_SP(&info) < 0) { - MSG("Leftover inexact backtrace:"); + ops->warning(data, "Leftover inexact backtrace:\n"); stack = (unsigned long *)UNW_SP(&info); if (!stack) - goto out; + return; } else - MSG("Full inexact backtrace again:"); + ops->warning(data, "Full inexact backtrace again:\n"); } else if (call_trace >= 1) - goto out; + return; else - MSG("Full inexact backtrace again:"); + ops->warning(data, "Full inexact backtrace again:\n"); } else - MSG("Inexact backtrace:"); + ops->warning(data, "Inexact backtrace:\n"); } if (!stack) { unsigned long dummy; @@ -309,6 +297,12 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, if (tsk && tsk != current) stack = (unsigned long *)tsk->thread.rsp; } + /* + * Align the stack pointer on word boundary, later loops + * rely on that (and corruption / debug info bugs can cause + * unaligned values here): + */ + stack = (unsigned long *)((unsigned long)stack & ~(sizeof(long)-1)); /* * Print function call entries within a stack. 'cond' is the @@ -318,9 +312,9 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, #define HANDLE_STACK(cond) \ do while (cond) { \ unsigned long addr = *stack++; \ - /* Use unlocked access here because except for NMIs \ - we should be already protected against module unloads */ \ - if (__kernel_text_address(addr)) { \ + if (oops_in_progress ? \ + __kernel_text_address(addr) : \ + kernel_text_address(addr)) { \ /* \ * If the address is either in the text segment of the \ * kernel, or in the region which contains vmalloc'ed \ @@ -386,8 +380,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, tinfo = current_thread_info(); HANDLE_STACK (valid_stack_ptr(tinfo, stack)); #undef HANDLE_STACK -out: - put_cpu(); } EXPORT_SYMBOL(dump_trace); @@ -794,7 +786,8 @@ mem_parity_error(unsigned char reason, struct pt_regs * regs) { printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", reason); - printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n"); + printk(KERN_EMERG "You probably have a hardware problem with your " + "RAM chips\n"); if (panic_on_unrecovered_nmi) panic("NMI: Not continuing"); diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index 6a1f8f491e5d..d9534e750d4f 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -51,6 +51,15 @@ SECTIONS RODATA +#ifdef CONFIG_STACK_UNWIND + . = ALIGN(8); + .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { + __start_unwind = .; + *(.eh_frame) + __end_unwind = .; + } +#endif + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { diff --git a/trunk/arch/x86_64/kernel/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index 4a673f5397a0..92546c1526f1 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -42,7 +42,6 @@ #include #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) -#define __syscall_clobber "r11","rcx","memory" int __sysctl_vsyscall __section_sysctl_vsyscall = 1; seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; @@ -275,6 +274,7 @@ static void __cpuinit cpu_vsyscall_init(void *arg) vsyscall_set_cpu(raw_smp_processor_id()); } +#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) { @@ -283,13 +283,13 @@ cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); return NOTIFY_DONE; } +#endif static void __init map_vsyscall(void) { extern char __vsyscall_0; unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); - /* Note that VSYSCALL_MAPPED_PAGES must agree with the code below. */ __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); } diff --git a/trunk/arch/x86_64/lib/csum-partial.c b/trunk/arch/x86_64/lib/csum-partial.c index bc503f506903..06ae630de82b 100644 --- a/trunk/arch/x86_64/lib/csum-partial.c +++ b/trunk/arch/x86_64/lib/csum-partial.c @@ -9,6 +9,8 @@ #include #include +#define __force_inline inline __attribute__((always_inline)) + static inline unsigned short from32to16(unsigned a) { unsigned short b = a >> 16; @@ -31,7 +33,7 @@ static inline unsigned short from32to16(unsigned a) * Unrolling to an 128 bytes inner loop. * Using interleaving with more registers to break the carry chains. */ -static unsigned do_csum(const unsigned char *buff, unsigned len) +static __force_inline unsigned do_csum(const unsigned char *buff, unsigned len) { unsigned odd, count; unsigned long result = 0; diff --git a/trunk/arch/x86_64/lib/delay.c b/trunk/arch/x86_64/lib/delay.c index 2dbebd308347..50be90975d04 100644 --- a/trunk/arch/x86_64/lib/delay.c +++ b/trunk/arch/x86_64/lib/delay.c @@ -40,13 +40,13 @@ EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) { - __delay(((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) + 1); + __delay((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32); } EXPORT_SYMBOL(__const_udelay); void __udelay(unsigned long usecs) { - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ + __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } EXPORT_SYMBOL(__udelay); diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index a65fc6f1dcaf..3751b4788e28 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -23,9 +23,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -96,7 +96,7 @@ void bust_spinlocks(int yes) static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned long error_code) { - unsigned char *instr; + unsigned char __user *instr; int scan_more = 1; int prefetch = 0; unsigned char *max_instr; @@ -116,7 +116,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned char instr_hi; unsigned char instr_lo; - if (probe_kernel_address(instr, opcode)) + if (__get_user(opcode, (char __user *)instr)) break; instr_hi = opcode & 0xf0; @@ -154,7 +154,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, case 0x00: /* Prefetch instruction is 0x0F0D or 0x0F18 */ scan_more = 0; - if (probe_kernel_address(instr, opcode)) + if (__get_user(opcode, (char __user *)instr)) break; prefetch = (instr_lo == 0xF) && (opcode == 0x0D || opcode == 0x18); @@ -170,7 +170,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, static int bad_address(void *p) { unsigned long dummy; - return probe_kernel_address((unsigned long *)p, dummy); + return __get_user(dummy, (unsigned long __user *)p); } void dump_pagetable(unsigned long address) diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 2968b90ef8ad..4c0c00ef3ca7 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -730,15 +730,14 @@ static __init int x8664_sysctl_init(void) __initcall(x8664_sysctl_init); #endif -/* A pseudo VMA to allow ptrace access for the vsyscall page. This only +/* A pseudo VMAs to allow ptrace access for the vsyscall page. This only covers the 64bit vsyscall page now. 32bit has a real VMA now and does not need special handling anymore. */ static struct vm_area_struct gate_vma = { .vm_start = VSYSCALL_START, - .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES << PAGE_SHIFT), - .vm_page_prot = PAGE_READONLY_EXEC, - .vm_flags = VM_READ | VM_EXEC + .vm_end = VSYSCALL_END, + .vm_page_prot = PAGE_READONLY }; struct vm_area_struct *get_gate_vma(struct task_struct *tsk) diff --git a/trunk/arch/x86_64/mm/pageattr.c b/trunk/arch/x86_64/mm/pageattr.c index ccb91dd996a9..3e231d762aaa 100644 --- a/trunk/arch/x86_64/mm/pageattr.c +++ b/trunk/arch/x86_64/mm/pageattr.c @@ -61,40 +61,34 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, return base; } -static void cache_flush_page(void *adr) -{ - int i; - for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) - asm volatile("clflush (%0)" :: "r" (adr + i)); -} -static void flush_kernel_map(void *arg) +static void flush_kernel_map(void *address) { - struct list_head *l = (struct list_head *)arg; - struct page *pg; - - /* When clflush is available always use it because it is - much cheaper than WBINVD */ - if (!cpu_has_clflush) - asm volatile("wbinvd" ::: "memory"); - list_for_each_entry(pg, l, lru) { - void *adr = page_address(pg); - if (cpu_has_clflush) - cache_flush_page(adr); - __flush_tlb_one(adr); - } + if (0 && address && cpu_has_clflush) { + /* is this worth it? */ + int i; + for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) + asm volatile("clflush (%0)" :: "r" (address + i)); + } else + asm volatile("wbinvd":::"memory"); + if (address) + __flush_tlb_one(address); + else + __flush_tlb_all(); } -static inline void flush_map(struct list_head *l) + +static inline void flush_map(unsigned long address) { - on_each_cpu(flush_kernel_map, l, 1, 1); + on_each_cpu(flush_kernel_map, (void *)address, 1, 1); } -static LIST_HEAD(deferred_pages); /* protected by init_mm.mmap_sem */ +static struct page *deferred_pages; /* protected by init_mm.mmap_sem */ static inline void save_page(struct page *fpage) { - list_add(&fpage->lru, &deferred_pages); + fpage->lru.next = (struct list_head *)deferred_pages; + deferred_pages = fpage; } /* @@ -213,18 +207,18 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) void global_flush_tlb(void) { - struct page *pg, *next; - struct list_head l; + struct page *dpage; down_read(&init_mm.mmap_sem); - list_replace_init(&deferred_pages, &l); + dpage = xchg(&deferred_pages, NULL); up_read(&init_mm.mmap_sem); - flush_map(&l); - - list_for_each_entry_safe(pg, next, &l, lru) { - ClearPagePrivate(pg); - __free_page(pg); + flush_map((dpage && !dpage->lru.next) ? (unsigned long)page_address(dpage) : 0); + while (dpage) { + struct page *tmp = dpage; + dpage = (struct page *)dpage->lru.next; + ClearPagePrivate(tmp); + __free_page(tmp); } } diff --git a/trunk/block/blktrace.c b/trunk/block/blktrace.c index d3679dd1d220..74e02c04b2da 100644 --- a/trunk/block/blktrace.c +++ b/trunk/block/blktrace.c @@ -394,7 +394,8 @@ static int blk_trace_setup(request_queue_t *q, struct block_device *bdev, if (bt) { if (bt->dropped_file) debugfs_remove(bt->dropped_file); - free_percpu(bt->sequence); + if (bt->sequence) + free_percpu(bt->sequence); if (bt->rchan) relay_close(bt->rchan); kfree(bt); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 78c6b312bd30..84e9be073180 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -43,8 +43,8 @@ static int cfq_slice_idle = HZ / 125; #define RQ_CIC(rq) ((struct cfq_io_context*)(rq)->elevator_private) #define RQ_CFQQ(rq) ((rq)->elevator_private2) -static struct kmem_cache *cfq_pool; -static struct kmem_cache *cfq_ioc_pool; +static kmem_cache_t *cfq_pool; +static kmem_cache_t *cfq_ioc_pool; static DEFINE_PER_CPU(unsigned long, ioc_count); static struct completion *ioc_gone; diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 31512cd9f3ad..cc6e95f8e5d9 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -44,17 +44,17 @@ static struct io_context *current_io_context(gfp_t gfp_flags, int node); /* * For the allocated request tables */ -static struct kmem_cache *request_cachep; +static kmem_cache_t *request_cachep; /* * For queue allocation */ -static struct kmem_cache *requestq_cachep; +static kmem_cache_t *requestq_cachep; /* * For io context allocations */ -static struct kmem_cache *iocontext_cachep; +static kmem_cache_t *iocontext_cachep; /* * Controlling structure to kblockd @@ -3459,6 +3459,8 @@ static void blk_done_softirq(struct softirq_action *h) } } +#ifdef CONFIG_HOTPLUG_CPU + static int blk_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { @@ -3484,6 +3486,8 @@ static struct notifier_block __devinitdata blk_cpu_notifier = { .notifier_call = blk_cpu_notify, }; +#endif /* CONFIG_HOTPLUG_CPU */ + /** * blk_complete_request - end I/O on a request * @req: the request being processed diff --git a/trunk/drivers/atm/he.c b/trunk/drivers/atm/he.c index 7d9b4e52f0bf..c7314a79da0f 100644 --- a/trunk/drivers/atm/he.c +++ b/trunk/drivers/atm/he.c @@ -820,7 +820,7 @@ he_init_group(struct he_dev *he_dev, int group) void *cpuaddr; #ifdef USE_RBPS_POOL - cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle); + cpuaddr = pci_pool_alloc(he_dev->rbps_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle); if (cpuaddr == NULL) return -ENOMEM; #else @@ -884,7 +884,7 @@ he_init_group(struct he_dev *he_dev, int group) void *cpuaddr; #ifdef USE_RBPL_POOL - cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle); + cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle); if (cpuaddr == NULL) return -ENOMEM; #else @@ -1724,7 +1724,7 @@ __alloc_tpd(struct he_dev *he_dev) struct he_tpd *tpd; dma_addr_t dma_handle; - tpd = pci_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC|GFP_DMA, &dma_handle); + tpd = pci_pool_alloc(he_dev->tpd_pool, SLAB_ATOMIC|SLAB_DMA, &dma_handle); if (tpd == NULL) return NULL; diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 67b79a7592a9..e4b530ef757d 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -386,7 +386,6 @@ void device_initialize(struct device *dev) INIT_LIST_HEAD(&dev->node); init_MUTEX(&dev->sem); device_init_wakeup(dev, 0); - set_dev_node(dev, -1); } #ifdef CONFIG_SYSFS_DEPRECATED diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index 7fd095efaebd..1f745f12f94e 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -104,8 +104,8 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); /* * register_cpu - Setup a driverfs device for a CPU. - * @cpu - cpu->hotpluggable field set to 1 will generate a control file in - * sysfs for this CPU. + * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to + * generate a control file in sysfs for this CPU. * @num - CPU number to use when creating the device. * * Initialize and register the CPU device. @@ -119,7 +119,7 @@ int __devinit register_cpu(struct cpu *cpu, int num) error = sysdev_register(&cpu->sysdev); - if (!error && cpu->hotpluggable) + if (!error && !cpu->no_control) register_cpu_control(cpu); if (!error) cpu_sys_devices[num] = &cpu->sysdev; diff --git a/trunk/drivers/base/dmapool.c b/trunk/drivers/base/dmapool.c index dbe0735f8c9e..b2efbd4cf710 100644 --- a/trunk/drivers/base/dmapool.c +++ b/trunk/drivers/base/dmapool.c @@ -126,7 +126,7 @@ dma_pool_create (const char *name, struct device *dev, } else if (allocation < size) return NULL; - if (!(retval = kmalloc (sizeof *retval, GFP_KERNEL))) + if (!(retval = kmalloc (sizeof *retval, SLAB_KERNEL))) return retval; strlcpy (retval->name, name, sizeof retval->name); @@ -297,7 +297,7 @@ dma_pool_alloc (struct dma_pool *pool, gfp_t mem_flags, dma_addr_t *handle) } } } - if (!(page = pool_alloc_page (pool, GFP_ATOMIC))) { + if (!(page = pool_alloc_page (pool, SLAB_ATOMIC))) { if (mem_flags & __GFP_WAIT) { DECLARE_WAITQUEUE (wait, current); diff --git a/trunk/drivers/base/memory.c b/trunk/drivers/base/memory.c index 74b96795d2f5..c6b7d9c4b651 100644 --- a/trunk/drivers/base/memory.c +++ b/trunk/drivers/base/memory.c @@ -290,8 +290,9 @@ static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); static int block_size_init(void) { - return sysfs_create_file(&memory_sysdev_class.kset.kobj, - &class_attr_block_size_bytes.attr); + sysfs_create_file(&memory_sysdev_class.kset.kobj, + &class_attr_block_size_bytes.attr); + return 0; } /* @@ -322,14 +323,12 @@ static CLASS_ATTR(probe, 0700, NULL, memory_probe_store); static int memory_probe_init(void) { - return sysfs_create_file(&memory_sysdev_class.kset.kobj, - &class_attr_probe.attr); -} -#else -static inline int memory_probe_init(void) -{ + sysfs_create_file(&memory_sysdev_class.kset.kobj, + &class_attr_probe.attr); return 0; } +#else +#define memory_probe_init(...) do {} while (0) #endif /* @@ -432,12 +431,9 @@ int __init memory_dev_init(void) { unsigned int i; int ret; - int err; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); - if (ret) - goto out; /* * Create entries for memory sections that were found @@ -446,19 +442,11 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!valid_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0); - if (!ret) - ret = err; + add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0); } - err = memory_probe_init(); - if (!ret) - ret = err; - err = block_size_init(); - if (!ret) - ret = err; -out: - if (ret) - printk(KERN_ERR "%s() failed: %d\n", __FUNCTION__, ret); + memory_probe_init(); + block_size_init(); + return ret; } diff --git a/trunk/drivers/base/topology.c b/trunk/drivers/base/topology.c index 067a9e8bc377..3d12b85b0962 100644 --- a/trunk/drivers/base/topology.c +++ b/trunk/drivers/base/topology.c @@ -108,6 +108,7 @@ static int __cpuinit topology_add_dev(unsigned int cpu) return rc; } +#ifdef CONFIG_HOTPLUG_CPU static void __cpuinit topology_remove_dev(unsigned int cpu) { struct sys_device *sys_dev = get_cpu_sysdev(cpu); @@ -135,6 +136,7 @@ static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, } return rc ? NOTIFY_BAD : NOTIFY_OK; } +#endif static int __cpuinit topology_sysfs_init(void) { diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index 8d81a3a64c07..742d07403101 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -324,13 +324,13 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller) Command->Next = Controller->FreeCommands; Controller->FreeCommands = Command; Controller->Commands[CommandIdentifier-1] = Command; - ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, GFP_ATOMIC, + ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, SLAB_ATOMIC, &ScatterGatherDMA); if (ScatterGatherCPU == NULL) return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION"); if (RequestSensePool != NULL) { - RequestSenseCPU = pci_pool_alloc(RequestSensePool, GFP_ATOMIC, + RequestSenseCPU = pci_pool_alloc(RequestSensePool, SLAB_ATOMIC, &RequestSenseDMA); if (RequestSenseCPU == NULL) { pci_pool_free(ScatterGatherPool, ScatterGatherCPU, diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index 432c17e1e0e6..17dc22282e14 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -168,8 +168,7 @@ config BLK_CPQ_CISS_DA config CISS_SCSI_TAPE bool "SCSI tape drive support for Smart Array 5xxx" - depends on BLK_CPQ_CISS_DA && PROC_FS - depends on SCSI=y || SCSI=BLK_CPQ_CISS_DA + depends on BLK_CPQ_CISS_DA && SCSI && PROC_FS help When enabled (Y), this option allows SCSI tape drives and SCSI medium changers (tape robots) to be accessed via a Compaq 5xxx array diff --git a/trunk/drivers/block/aoe/aoeblk.c b/trunk/drivers/block/aoe/aoeblk.c index 478489c568a4..aa25f8b09fe3 100644 --- a/trunk/drivers/block/aoe/aoeblk.c +++ b/trunk/drivers/block/aoe/aoeblk.c @@ -12,7 +12,7 @@ #include #include "aoe.h" -static struct kmem_cache *buf_pool_cache; +static kmem_cache_t *buf_pool_cache; static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) { diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 892e092afe9a..4105c3bf3476 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -47,15 +47,14 @@ #include #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -#define DRIVER_NAME "HP CISS Driver (v 3.6.14)" -#define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,14) +#define DRIVER_NAME "HP CISS Driver (v 3.6.10)" +#define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,10) /* Embedded module documentation macros - see modules.h */ MODULE_AUTHOR("Hewlett-Packard Company"); -MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.14"); +MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.10"); MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" " SA6i P600 P800 P400 P400i E200 E200i E500"); -MODULE_VERSION("3.6.14"); MODULE_LICENSE("GPL"); #include "cciss_cmd.h" @@ -82,9 +81,7 @@ static const struct pci_device_id cciss_pci_device_id[] = { {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3213}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, - {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3233}, {0,} }; @@ -93,29 +90,27 @@ MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); /* board_id = Subsystem Device ID & Vendor ID * product = Marketing Name for the board * access = Address of the struct of function pointers - * nr_cmds = Number of commands supported by controller */ static struct board_type products[] = { - {0x40700E11, "Smart Array 5300", &SA5_access, 512}, - {0x40800E11, "Smart Array 5i", &SA5B_access, 512}, - {0x40820E11, "Smart Array 532", &SA5B_access, 512}, - {0x40830E11, "Smart Array 5312", &SA5B_access, 512}, - {0x409A0E11, "Smart Array 641", &SA5_access, 512}, - {0x409B0E11, "Smart Array 642", &SA5_access, 512}, - {0x409C0E11, "Smart Array 6400", &SA5_access, 512}, - {0x409D0E11, "Smart Array 6400 EM", &SA5_access, 512}, - {0x40910E11, "Smart Array 6i", &SA5_access, 512}, - {0x3225103C, "Smart Array P600", &SA5_access, 512}, - {0x3223103C, "Smart Array P800", &SA5_access, 512}, - {0x3234103C, "Smart Array P400", &SA5_access, 512}, - {0x3235103C, "Smart Array P400i", &SA5_access, 512}, - {0x3211103C, "Smart Array E200i", &SA5_access, 120}, - {0x3212103C, "Smart Array E200", &SA5_access, 120}, - {0x3213103C, "Smart Array E200i", &SA5_access, 120}, - {0x3214103C, "Smart Array E200i", &SA5_access, 120}, - {0x3215103C, "Smart Array E200i", &SA5_access, 120}, - {0x3237103C, "Smart Array E500", &SA5_access, 512}, - {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, + {0x40700E11, "Smart Array 5300", &SA5_access}, + {0x40800E11, "Smart Array 5i", &SA5B_access}, + {0x40820E11, "Smart Array 532", &SA5B_access}, + {0x40830E11, "Smart Array 5312", &SA5B_access}, + {0x409A0E11, "Smart Array 641", &SA5_access}, + {0x409B0E11, "Smart Array 642", &SA5_access}, + {0x409C0E11, "Smart Array 6400", &SA5_access}, + {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, + {0x40910E11, "Smart Array 6i", &SA5_access}, + {0x3225103C, "Smart Array P600", &SA5_access}, + {0x3223103C, "Smart Array P800", &SA5_access}, + {0x3234103C, "Smart Array P400", &SA5_access}, + {0x3235103C, "Smart Array P400i", &SA5_access}, + {0x3211103C, "Smart Array E200i", &SA5_access}, + {0x3212103C, "Smart Array E200", &SA5_access}, + {0x3213103C, "Smart Array E200i", &SA5_access}, + {0x3214103C, "Smart Array E200i", &SA5_access}, + {0x3215103C, "Smart Array E200i", &SA5_access}, + {0x3233103C, "Smart Array E500", &SA5_access}, }; /* How long to wait (in milliseconds) for board to go into simple mode */ @@ -126,6 +121,7 @@ static struct board_type products[] = { #define MAX_CMD_RETRIES 3 #define READ_AHEAD 1024 +#define NR_CMDS 384 /* #commands that can be outstanding */ #define MAX_CTLR 32 /* Originally cciss driver only supports 8 major numbers */ @@ -141,6 +137,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); +static int revalidate_allvol(ctlr_info_t *host); static int cciss_revalidate(struct gendisk *disk); static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, @@ -268,7 +265,6 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, "Firmware Version: %c%c%c%c\n" "IRQ: %d\n" "Logical drives: %d\n" - "Max sectors: %d\n" "Current Q depth: %d\n" "Current # commands on controller: %d\n" "Max Q depth since init: %d\n" @@ -279,9 +275,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, (unsigned long)h->board_id, h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT], - h->num_luns, - h->cciss_max_sectors, - h->Qdepth, h->commands_outstanding, + h->num_luns, h->Qdepth, h->commands_outstanding, h->maxQsinceinit, h->max_outstanding, h->maxSG); pos += size; @@ -406,8 +400,8 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) } else { /* get it out of the controllers pool */ do { - i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); - if (i == h->nr_cmds) + i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS); + if (i == NR_CMDS) return NULL; } while (test_and_set_bit (i & (BITS_PER_LONG - 1), @@ -493,7 +487,7 @@ static int cciss_open(struct inode *inode, struct file *filep) * but I'm already using way to many device nodes to claim another one * for "raw controller". */ - if (drv->heads == 0) { + if (drv->nr_blocks == 0) { if (iminor(inode) != 0) { /* not node 0? */ /* if not node 0 make sure it is a partition = 0 */ if (iminor(inode) & 0x0f) { @@ -856,7 +850,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, } case CCISS_REVALIDVOLS: - return rebuild_lun_table(host, NULL); + if (bdev != bdev->bd_contains || drv != host->drv) + return -ENXIO; + return revalidate_allvol(host); case CCISS_GETLUNINFO:{ LogvolInfo_struct luninfo; @@ -1156,6 +1152,75 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, } } +/* + * revalidate_allvol is for online array config utilities. After a + * utility reconfigures the drives in the array, it can use this function + * (through an ioctl) to make the driver zap any previous disk structs for + * that controller and get new ones. + * + * Right now I'm using the getgeometry() function to do this, but this + * function should probably be finer grained and allow you to revalidate one + * particular logical volume (instead of all of them on a particular + * controller). + */ +static int revalidate_allvol(ctlr_info_t *host) +{ + int ctlr = host->ctlr, i; + unsigned long flags; + + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + if (host->usage_count > 1) { + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + printk(KERN_WARNING "cciss: Device busy for volume" + " revalidation (usage=%d)\n", host->usage_count); + return -EBUSY; + } + host->usage_count++; + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + + for (i = 0; i < NWD; i++) { + struct gendisk *disk = host->gendisk[i]; + if (disk) { + request_queue_t *q = disk->queue; + + if (disk->flags & GENHD_FL_UP) + del_gendisk(disk); + if (q) + blk_cleanup_queue(q); + } + } + + /* + * Set the partition and block size structures for all volumes + * on this controller to zero. We will reread all of this data + */ + memset(host->drv, 0, sizeof(drive_info_struct) + * CISS_MAX_LUN); + /* + * Tell the array controller not to give us any interrupts while + * we check the new geometry. Then turn interrupts back on when + * we're done. + */ + host->access.set_intr_mask(host, CCISS_INTR_OFF); + cciss_getgeometry(ctlr); + host->access.set_intr_mask(host, CCISS_INTR_ON); + + /* Loop through each real device */ + for (i = 0; i < NWD; i++) { + struct gendisk *disk = host->gendisk[i]; + drive_info_struct *drv = &(host->drv[i]); + /* we must register the controller even if no disks exist */ + /* this is for the online array utilities */ + if (!drv->heads && i) + continue; + blk_queue_hardsect_size(drv->queue, drv->block_size); + set_capacity(disk, drv->nr_blocks); + add_disk(disk); + } + host->usage_count--; + return 0; +} + static inline void complete_buffers(struct bio *bio, int status) { while (bio) { @@ -1178,7 +1243,7 @@ static void cciss_check_queues(ctlr_info_t *h) * in case the interrupt we serviced was from an ioctl and did not * free any new commands. */ - if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds) + if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) return; /* We have room on the queue for more commands. Now we need to queue @@ -1197,7 +1262,7 @@ static void cciss_check_queues(ctlr_info_t *h) /* check to see if we have maxed out the number of commands * that can be placed on the queue. */ - if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds) { + if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { if (curr_queue == start_queue) { h->next_to_run = (start_queue + 1) % (h->highest_lun + 1); @@ -1315,11 +1380,6 @@ static void cciss_update_drive_info(int ctlr, int drv_index) /* if it's the controller it's already added */ if (drv_index) { disk->queue = blk_init_queue(do_cciss_request, &h->lock); - sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); - disk->major = h->major; - disk->first_minor = drv_index << NWD_SHIFT; - disk->fops = &cciss_fops; - disk->private_data = &h->drv[drv_index]; /* Set up queue information */ disk->queue->backing_dev_info.ra_pages = READ_AHEAD; @@ -1331,7 +1391,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index) /* This is a limit in the driver and could be eliminated. */ blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); - blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); + blk_queue_max_sectors(disk->queue, 512); blk_queue_softirq_done(disk->queue, cciss_softirq_done); @@ -1398,6 +1458,11 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) /* Set busy_configuring flag for this operation */ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + if (h->num_luns >= CISS_MAX_LUN) { + spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + return -EINVAL; + } + if (h->busy_configuring) { spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); return -EBUSY; @@ -1430,8 +1495,17 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) 0, 0, TYPE_CMD); if (return_code == IO_OK) { - listlength = - be32_to_cpu(*(__u32 *) ld_buff->LUNListLength); + listlength |= + (0xff & (unsigned int)(ld_buff->LUNListLength[0])) + << 24; + listlength |= + (0xff & (unsigned int)(ld_buff->LUNListLength[1])) + << 16; + listlength |= + (0xff & (unsigned int)(ld_buff->LUNListLength[2])) + << 8; + listlength |= + 0xff & (unsigned int)(ld_buff->LUNListLength[3]); } else { /* reading number of logical volumes failed */ printk(KERN_WARNING "cciss: report logical volume" " command failed\n"); @@ -1482,14 +1556,6 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) if (drv_index == -1) goto freeret; - /*Check if the gendisk needs to be allocated */ - if (!h->gendisk[drv_index]){ - h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT); - if (!h->gendisk[drv_index]){ - printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index); - goto mem_msg; - } - } } h->drv[drv_index].LunID = lunid; cciss_update_drive_info(ctlr, drv_index); @@ -1527,7 +1593,6 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all) { - int i; ctlr_info_t *h = get_host(disk); if (!capable(CAP_SYS_RAWIO)) @@ -1551,35 +1616,9 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, del_gendisk(disk); if (q) { blk_cleanup_queue(q); - /* Set drv->queue to NULL so that we do not try - * to call blk_start_queue on this queue in the - * interrupt handler - */ drv->queue = NULL; } - /* If clear_all is set then we are deleting the logical - * drive, not just refreshing its info. For drives - * other than disk 0 we will call put_disk. We do not - * do this for disk 0 as we need it to be able to - * configure the controller. - */ - if (clear_all){ - /* This isn't pretty, but we need to find the - * disk in our array and NULL our the pointer. - * This is so that we will call alloc_disk if - * this index is used again later. - */ - for (i=0; i < CISS_MAX_LUN; i++){ - if(h->gendisk[i] == disk){ - h->gendisk[i] = NULL; - break; - } - } - put_disk(disk); - } } - } else { - set_capacity(disk, 0); } --h->num_luns; @@ -2097,7 +2136,7 @@ static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete) /* We've sent down an abort or reset, but something else has completed */ - if (srl->ncompletions >= (hba[ctlr]->nr_cmds + 2)) { + if (srl->ncompletions >= (NR_CMDS + 2)) { /* Uh oh. No room to save it for later... */ printk(KERN_WARNING "cciss%d: Sendcmd: Invalid command addr, " "reject list overflow, command lost!\n", ctlr); @@ -2634,7 +2673,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) a1 = a; if ((a & 0x04)) { a2 = (a >> 3); - if (a2 >= h->nr_cmds) { + if (a2 >= NR_CMDS) { printk(KERN_WARNING "cciss: controller cciss%d failed, stopping.\n", h->ctlr); @@ -2788,21 +2827,23 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, if (err > 0) { printk(KERN_WARNING "cciss: only %d MSI-X vectors " "available\n", err); - goto default_int_mode; } else { printk(KERN_WARNING "cciss: MSI-X init failed %d\n", err); - goto default_int_mode; } } if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { if (!pci_enable_msi(pdev)) { + c->intr[SIMPLE_MODE_INT] = pdev->irq; c->msi_vector = 1; + return; } else { printk(KERN_WARNING "cciss: MSI init failed\n"); + c->intr[SIMPLE_MODE_INT] = pdev->irq; + return; } } -default_int_mode: + default_int_mode: #endif /* CONFIG_PCI_MSI */ /* if we get here we're going to use the default interrupt mode */ c->intr[SIMPLE_MODE_INT] = pdev->irq; @@ -2915,10 +2956,16 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) if (board_id == products[i].board_id) { c->product_name = products[i].product_name; c->access = *(products[i].access); - c->nr_cmds = products[i].nr_cmds; break; } } + if (i == ARRAY_SIZE(products)) { + printk(KERN_WARNING "cciss: Sorry, I don't know how" + " to access the Smart Array controller %08lx\n", + (unsigned long)board_id); + err = -ENODEV; + goto err_out_free_res; + } if ((readb(&c->cfgtable->Signature[0]) != 'C') || (readb(&c->cfgtable->Signature[1]) != 'I') || (readb(&c->cfgtable->Signature[2]) != 'S') || @@ -2927,27 +2974,6 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) err = -ENODEV; goto err_out_free_res; } - /* We didn't find the controller in our list. We know the - * signature is valid. If it's an HP device let's try to - * bind to the device and fire it up. Otherwise we bail. - */ - if (i == ARRAY_SIZE(products)) { - if (subsystem_vendor_id == PCI_VENDOR_ID_HP) { - c->product_name = products[i-1].product_name; - c->access = *(products[i-1].access); - c->nr_cmds = products[i-1].nr_cmds; - printk(KERN_WARNING "cciss: This is an unknown " - "Smart Array controller.\n" - "cciss: Please update to the latest driver " - "available from www.hp.com.\n"); - } else { - printk(KERN_WARNING "cciss: Sorry, I don't know how" - " to access the Smart Array controller %08lx\n" - , (unsigned long)board_id); - err = -ENODEV; - goto err_out_free_res; - } - } #ifdef CONFIG_X86 { /* Need to enable prefetch in the SCSI core for 6400 in x86 */ @@ -2958,17 +2984,6 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) } #endif - /* Disabling DMA prefetch for the P600 - * An ASIC bug may result in a prefetch beyond - * physical memory. - */ - if(board_id == 0x3225103C) { - __u32 dma_prefetch; - dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG); - dma_prefetch |= 0x8000; - writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG); - } - #ifdef CCISS_DEBUG printk("Trying to put board into Simple mode\n"); #endif /* CCISS_DEBUG */ @@ -3143,7 +3158,13 @@ static void cciss_getgeometry(int cntl_num) /* Returns -1 if no free entries are left. */ static int alloc_cciss_hba(void) { - int i; + struct gendisk *disk[NWD]; + int i, n; + for (n = 0; n < NWD; n++) { + disk[n] = alloc_disk(1 << NWD_SHIFT); + if (!disk[n]) + goto out; + } for (i = 0; i < MAX_CTLR; i++) { if (!hba[i]) { @@ -3151,18 +3172,20 @@ static int alloc_cciss_hba(void) p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); if (!p) goto Enomem; - p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); - if (!p->gendisk[0]) - goto Enomem; + for (n = 0; n < NWD; n++) + p->gendisk[n] = disk[n]; hba[i] = p; return i; } } printk(KERN_WARNING "cciss: This driver supports a maximum" " of %d controllers.\n", MAX_CTLR); - return -1; -Enomem: + goto out; + Enomem: printk(KERN_ERR "cciss: out of memory.\n"); + out: + while (n--) + put_disk(disk[n]); return -1; } @@ -3172,7 +3195,7 @@ static void free_hba(int i) int n; hba[i] = NULL; - for (n = 0; n < CISS_MAX_LUN; n++) + for (n = 0; n < NWD; n++) put_disk(p->gendisk[n]); kfree(p); } @@ -3185,8 +3208,9 @@ static void free_hba(int i) static int __devinit cciss_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { + request_queue_t *q; int i; - int j = 0; + int j; int rc; int dac; @@ -3245,15 +3269,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not"); hba[i]->cmd_pool_bits = - kmalloc(((hba[i]->nr_cmds + BITS_PER_LONG - + kmalloc(((NR_CMDS + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL); hba[i]->cmd_pool = (CommandList_struct *) pci_alloc_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(CommandList_struct), + NR_CMDS * sizeof(CommandList_struct), &(hba[i]->cmd_pool_dhandle)); hba[i]->errinfo_pool = (ErrorInfo_struct *) pci_alloc_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(ErrorInfo_struct), + NR_CMDS * sizeof(ErrorInfo_struct), &(hba[i]->errinfo_pool_dhandle)); if ((hba[i]->cmd_pool_bits == NULL) || (hba[i]->cmd_pool == NULL) @@ -3264,7 +3288,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, #ifdef CONFIG_CISS_SCSI_TAPE hba[i]->scsi_rejects.complete = kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) * - (hba[i]->nr_cmds + 5), GFP_KERNEL); + (NR_CMDS + 5), GFP_KERNEL); if (hba[i]->scsi_rejects.complete == NULL) { printk(KERN_ERR "cciss: out of memory"); goto clean4; @@ -3278,7 +3302,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, /* command and error info recs zeroed out before they are used */ memset(hba[i]->cmd_pool_bits, 0, - ((hba[i]->nr_cmds + BITS_PER_LONG - + ((NR_CMDS + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(unsigned long)); #ifdef CCISS_DEBUG @@ -3293,34 +3317,18 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); cciss_procinit(i); - - hba[i]->cciss_max_sectors = 2048; - hba[i]->busy_initializing = 0; - do { + for (j = 0; j < NWD; j++) { /* mfm */ drive_info_struct *drv = &(hba[i]->drv[j]); struct gendisk *disk = hba[i]->gendisk[j]; - request_queue_t *q; - - /* Check if the disk was allocated already */ - if (!disk){ - hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT); - disk = hba[i]->gendisk[j]; - } - - /* Check that the disk was able to be allocated */ - if (!disk) { - printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j); - goto clean4; - } q = blk_init_queue(do_cciss_request, &hba[i]->lock); if (!q) { printk(KERN_ERR "cciss: unable to allocate queue for disk %d\n", j); - goto clean4; + break; } drv->queue = q; @@ -3333,7 +3341,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, /* This is a limit in the driver and could be eliminated. */ blk_queue_max_phys_segments(q, MAXSGENTRIES); - blk_queue_max_sectors(q, hba[i]->cciss_max_sectors); + blk_queue_max_sectors(q, 512); blk_queue_softirq_done(q, cciss_softirq_done); @@ -3352,8 +3360,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, blk_queue_hardsect_size(q, drv->block_size); set_capacity(disk, drv->nr_blocks); add_disk(disk); - j++; - } while (j <= hba[i]->highest_lun); + } return 1; @@ -3364,11 +3371,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, kfree(hba[i]->cmd_pool_bits); if (hba[i]->cmd_pool) pci_free_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(CommandList_struct), + NR_CMDS * sizeof(CommandList_struct), hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); if (hba[i]->errinfo_pool) pci_free_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(ErrorInfo_struct), + NR_CMDS * sizeof(ErrorInfo_struct), hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); @@ -3376,15 +3383,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, unregister_blkdev(hba[i]->major, hba[i]->devname); clean1: hba[i]->busy_initializing = 0; - /* cleanup any queues that may have been initialized */ - for (j=0; j <= hba[i]->highest_lun; j++){ - drive_info_struct *drv = &(hba[i]->drv[j]); - if (drv->queue) - blk_cleanup_queue(drv->queue); - } - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); free_hba(i); return -1; } @@ -3432,7 +3430,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) remove_proc_entry(hba[i]->devname, proc_cciss); /* remove it from the disk list */ - for (j = 0; j < CISS_MAX_LUN; j++) { + for (j = 0; j < NWD; j++) { struct gendisk *disk = hba[i]->gendisk[j]; if (disk) { request_queue_t *q = disk->queue; @@ -3444,9 +3442,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) } } - pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct), + pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct), + pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(ErrorInfo_struct), hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); kfree(hba[i]->cmd_pool_bits); #ifdef CONFIG_CISS_SCSI_TAPE diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index b70988dd33ec..562235c1445a 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -6,6 +6,7 @@ #include "cciss_cmd.h" +#define NWD 16 #define NWD_SHIFT 4 #define MAX_PART (1 << NWD_SHIFT) @@ -59,7 +60,6 @@ struct ctlr_info __u32 board_id; void __iomem *vaddr; unsigned long paddr; - int nr_cmds; /* Number of commands allowed on this controller */ CfgTable_struct __iomem *cfgtable; int interrupts_enabled; int major; @@ -76,7 +76,6 @@ struct ctlr_info unsigned int intr[4]; unsigned int msix_vector; unsigned int msi_vector; - int cciss_max_sectors; BYTE cciss_read; BYTE cciss_write; BYTE cciss_read_capacity; @@ -111,7 +110,7 @@ struct ctlr_info int next_to_run; // Disk structures we need to pass back - struct gendisk *gendisk[CISS_MAX_LUN]; + struct gendisk *gendisk[NWD]; #ifdef CONFIG_CISS_SCSI_TAPE void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ /* list of block side commands the scsi error handling sucked up */ @@ -283,7 +282,6 @@ struct board_type { __u32 board_id; char *product_name; struct access_method *access; - int nr_cmds; /* Max cmds this kind of ctlr can handle. */ }; #define CCISS_LOCK(i) (&hba[i]->lock) diff --git a/trunk/drivers/block/cciss_cmd.h b/trunk/drivers/block/cciss_cmd.h index 43bf5593b59b..4af7c4c0c7af 100644 --- a/trunk/drivers/block/cciss_cmd.h +++ b/trunk/drivers/block/cciss_cmd.h @@ -55,7 +55,6 @@ #define I2O_INT_MASK 0x34 #define I2O_IBPOST_Q 0x40 #define I2O_OBPOST_Q 0x44 -#define I2O_DMA1_CFG 0x214 //Configuration Table #define CFGTBL_ChangeReq 0x00000001l @@ -89,7 +88,7 @@ typedef union _u64bit //########################################################################### //STRUCTURES //########################################################################### -#define CISS_MAX_LUN 1024 +#define CISS_MAX_LUN 16 #define CISS_MAX_PHYS_LUN 1024 // SCSI-3 Cmmands diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 7bf2cfbd6285..9d1035e8d9d8 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -355,30 +355,14 @@ static struct request *nbd_read_stat(struct nbd_device *lo) return NULL; } -static ssize_t pid_show(struct gendisk *disk, char *page) -{ - return sprintf(page, "%ld\n", - (long) ((struct nbd_device *)disk->private_data)->pid); -} - -static struct disk_attribute pid_attr = { - .attr = { .name = "pid", .mode = S_IRUGO }, - .show = pid_show, -}; - static void nbd_do_it(struct nbd_device *lo) { struct request *req; BUG_ON(lo->magic != LO_MAGIC); - lo->pid = current->pid; - sysfs_create_file(&lo->disk->kobj, &pid_attr.attr); - while ((req = nbd_read_stat(lo)) != NULL) nbd_end_request(req); - - sysfs_remove_file(&lo->disk->kobj, &pid_attr.attr); return; } diff --git a/trunk/drivers/block/paride/aten.c b/trunk/drivers/block/paride/aten.c index 2695465568ad..c4d696d43dc1 100644 --- a/trunk/drivers/block/paride/aten.c +++ b/trunk/drivers/block/paride/aten.c @@ -149,12 +149,12 @@ static struct pi_protocol aten = { static int __init aten_init(void) { - return paride_register(&aten); + return pi_register(&aten)-1; } static void __exit aten_exit(void) { - paride_unregister( &aten ); + pi_unregister( &aten ); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/bpck.c b/trunk/drivers/block/paride/bpck.c index 4f27e7392e38..d462ff6b139d 100644 --- a/trunk/drivers/block/paride/bpck.c +++ b/trunk/drivers/block/paride/bpck.c @@ -464,12 +464,12 @@ static struct pi_protocol bpck = { static int __init bpck_init(void) { - return paride_register(&bpck); + return pi_register(&bpck)-1; } static void __exit bpck_exit(void) { - paride_unregister(&bpck); + pi_unregister(&bpck); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/bpck6.c b/trunk/drivers/block/paride/bpck6.c index ad124525ac23..41a237c5957d 100644 --- a/trunk/drivers/block/paride/bpck6.c +++ b/trunk/drivers/block/paride/bpck6.c @@ -31,7 +31,10 @@ static int verbose; /* set this to 1 to see debugging messages and whatnot */ #include #include #include + +#if defined(CONFIG_PARPORT_MODULE)||defined(CONFIG_PARPORT) #include +#endif #include "ppc6lnx.c" #include "paride.h" @@ -136,6 +139,11 @@ static int bpck6_test_port ( PIA *pi ) /* check for 8-bit port */ PPCSTRUCT(pi)->ppc_id=pi->unit; PPCSTRUCT(pi)->lpt_addr=pi->port; +#ifdef CONFIG_PARPORT_PC_MODULE +#define CONFIG_PARPORT_PC +#endif + +#ifdef CONFIG_PARPORT_PC /* look at the parport device to see if what modes we can use */ if(((struct pardevice *)(pi->pardev))->port->modes & (PARPORT_MODE_EPP) @@ -153,6 +161,11 @@ static int bpck6_test_port ( PIA *pi ) /* check for 8-bit port */ { return 1; } +#else + /* there is no way of knowing what kind of port we have + default to the highest mode possible */ + return 5; +#endif } static int bpck6_probe_unit ( PIA *pi ) @@ -252,12 +265,12 @@ static int __init bpck6_init(void) printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n"); if(verbose) printk(KERN_DEBUG "bpck6: verbose debug enabled.\n"); - return paride_register(&bpck6); + return pi_register(&bpck6) - 1; } static void __exit bpck6_exit(void) { - paride_unregister(&bpck6); + pi_unregister(&bpck6); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/comm.c b/trunk/drivers/block/paride/comm.c index 9bcd35495323..43d61359d8ec 100644 --- a/trunk/drivers/block/paride/comm.c +++ b/trunk/drivers/block/paride/comm.c @@ -205,12 +205,12 @@ static struct pi_protocol comm = { static int __init comm_init(void) { - return paride_register(&comm); + return pi_register(&comm)-1; } static void __exit comm_exit(void) { - paride_unregister(&comm); + pi_unregister(&comm); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/dstr.c b/trunk/drivers/block/paride/dstr.c index accc5c777cbb..04d53bf58e8c 100644 --- a/trunk/drivers/block/paride/dstr.c +++ b/trunk/drivers/block/paride/dstr.c @@ -220,12 +220,12 @@ static struct pi_protocol dstr = { static int __init dstr_init(void) { - return paride_register(&dstr); + return pi_register(&dstr)-1; } static void __exit dstr_exit(void) { - paride_unregister(&dstr); + pi_unregister(&dstr); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/epat.c b/trunk/drivers/block/paride/epat.c index 1bcdff77322e..55d1c0a1fb90 100644 --- a/trunk/drivers/block/paride/epat.c +++ b/trunk/drivers/block/paride/epat.c @@ -327,12 +327,12 @@ static int __init epat_init(void) #ifdef CONFIG_PARIDE_EPATC8 epatc8 = 1; #endif - return paride_register(&epat); + return pi_register(&epat)-1; } static void __exit epat_exit(void) { - paride_unregister(&epat); + pi_unregister(&epat); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/epia.c b/trunk/drivers/block/paride/epia.c index fb0e782d055e..0f2e0c292d82 100644 --- a/trunk/drivers/block/paride/epia.c +++ b/trunk/drivers/block/paride/epia.c @@ -303,12 +303,12 @@ static struct pi_protocol epia = { static int __init epia_init(void) { - return paride_register(&epia); + return pi_register(&epia)-1; } static void __exit epia_exit(void) { - paride_unregister(&epia); + pi_unregister(&epia); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/fit2.c b/trunk/drivers/block/paride/fit2.c index 381283753ae4..e0f0691d8bc2 100644 --- a/trunk/drivers/block/paride/fit2.c +++ b/trunk/drivers/block/paride/fit2.c @@ -138,12 +138,12 @@ static struct pi_protocol fit2 = { static int __init fit2_init(void) { - return paride_register(&fit2); + return pi_register(&fit2)-1; } static void __exit fit2_exit(void) { - paride_unregister(&fit2); + pi_unregister(&fit2); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/fit3.c b/trunk/drivers/block/paride/fit3.c index 275d269458eb..15400e7bc666 100644 --- a/trunk/drivers/block/paride/fit3.c +++ b/trunk/drivers/block/paride/fit3.c @@ -198,12 +198,12 @@ static struct pi_protocol fit3 = { static int __init fit3_init(void) { - return paride_register(&fit3); + return pi_register(&fit3)-1; } static void __exit fit3_exit(void) { - paride_unregister(&fit3); + pi_unregister(&fit3); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/friq.c b/trunk/drivers/block/paride/friq.c index 4f2ba244689b..5ea2904d2815 100644 --- a/trunk/drivers/block/paride/friq.c +++ b/trunk/drivers/block/paride/friq.c @@ -263,12 +263,12 @@ static struct pi_protocol friq = { static int __init friq_init(void) { - return paride_register(&friq); + return pi_register(&friq)-1; } static void __exit friq_exit(void) { - paride_unregister(&friq); + pi_unregister(&friq); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/frpw.c b/trunk/drivers/block/paride/frpw.c index c3cde364603a..56b3824b1538 100644 --- a/trunk/drivers/block/paride/frpw.c +++ b/trunk/drivers/block/paride/frpw.c @@ -300,12 +300,12 @@ static struct pi_protocol frpw = { static int __init frpw_init(void) { - return paride_register(&frpw); + return pi_register(&frpw)-1; } static void __exit frpw_exit(void) { - paride_unregister(&frpw); + pi_unregister(&frpw); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/jumbo b/trunk/drivers/block/paride/jumbo new file mode 100644 index 000000000000..e793b9cb7e72 --- /dev/null +++ b/trunk/drivers/block/paride/jumbo @@ -0,0 +1,70 @@ +#!/bin/sh +# +# This script can be used to build "jumbo" modules that contain the +# base PARIDE support, one protocol module and one high-level driver. +# +echo -n "High level driver [pcd] : " +read X +HLD=${X:-pcd} +# +echo -n "Protocol module [bpck] : " +read X +PROTO=${X:-bpck} +# +echo -n "Use MODVERSIONS [y] ? " +read X +UMODV=${X:-y} +# +echo -n "For SMP kernel [n] ? " +read X +USMP=${X:-n} +# +echo -n "Support PARPORT [n] ? " +read X +UPARP=${X:-n} +# +echo +# +case $USMP in + y* | Y* ) FSMP="-DCONFIG_SMP" + ;; + *) FSMP="" + ;; +esac +# +MODI="-include ../../../include/linux/modversions.h" +# +case $UMODV in + y* | Y* ) FMODV="-DMODVERSIONS $MODI" + ;; + *) FMODV="" + ;; +esac +# +case $UPARP in + y* | Y* ) FPARP="-DCONFIG_PARPORT" + ;; + *) FPARP="" + ;; +esac +# +TARG=$HLD-$PROTO.o +FPROTO=-DCONFIG_PARIDE_`echo "$PROTO" | tr [a-z] [A-Z]` +FK="-D__KERNEL__ -I ../../../include" +FLCH=-D_LINUX_CONFIG_H +# +echo cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c +cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c +# +echo cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c +cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c +# +echo cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c +cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c +# +echo ld -r -o $TARG Jp.o Jb.o Jd.o +ld -r -o $TARG Jp.o Jb.o Jd.o +# +# +rm Jp.o Jb.o Jd.o +# diff --git a/trunk/drivers/block/paride/kbic.c b/trunk/drivers/block/paride/kbic.c index 35999c415ee3..d983bcea76fe 100644 --- a/trunk/drivers/block/paride/kbic.c +++ b/trunk/drivers/block/paride/kbic.c @@ -283,21 +283,13 @@ static struct pi_protocol k971 = { static int __init kbic_init(void) { - int rv; - - rv = paride_register(&k951); - if (rv < 0) - return rv; - rv = paride_register(&k971); - if (rv < 0) - paride_unregister(&k951); - return rv; + return (pi_register(&k951)||pi_register(&k971))-1; } static void __exit kbic_exit(void) { - paride_unregister(&k951); - paride_unregister(&k971); + pi_unregister(&k951); + pi_unregister(&k971); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/ktti.c b/trunk/drivers/block/paride/ktti.c index 117ab0e8ccf0..6c7edbfba9a0 100644 --- a/trunk/drivers/block/paride/ktti.c +++ b/trunk/drivers/block/paride/ktti.c @@ -115,12 +115,12 @@ static struct pi_protocol ktti = { static int __init ktti_init(void) { - return paride_register(&ktti); + return pi_register(&ktti)-1; } static void __exit ktti_exit(void) { - paride_unregister(&ktti); + pi_unregister(&ktti); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/on20.c b/trunk/drivers/block/paride/on20.c index 0173697a1a4d..9f8e01096809 100644 --- a/trunk/drivers/block/paride/on20.c +++ b/trunk/drivers/block/paride/on20.c @@ -140,12 +140,12 @@ static struct pi_protocol on20 = { static int __init on20_init(void) { - return paride_register(&on20); + return pi_register(&on20)-1; } static void __exit on20_exit(void) { - paride_unregister(&on20); + pi_unregister(&on20); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/on26.c b/trunk/drivers/block/paride/on26.c index 95ba256921f2..0f833caa2101 100644 --- a/trunk/drivers/block/paride/on26.c +++ b/trunk/drivers/block/paride/on26.c @@ -306,12 +306,12 @@ static struct pi_protocol on26 = { static int __init on26_init(void) { - return paride_register(&on26); + return pi_register(&on26)-1; } static void __exit on26_exit(void) { - paride_unregister(&on26); + pi_unregister(&on26); } MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/block/paride/paride.c b/trunk/drivers/block/paride/paride.c index 48c50f11f63b..4b258f7836f3 100644 --- a/trunk/drivers/block/paride/paride.c +++ b/trunk/drivers/block/paride/paride.c @@ -29,7 +29,14 @@ #include #include #include /* TASK_* */ + +#ifdef CONFIG_PARPORT_MODULE +#define CONFIG_PARPORT +#endif + +#ifdef CONFIG_PARPORT #include +#endif #include "paride.h" @@ -69,6 +76,8 @@ void pi_read_block(PIA * pi, char *buf, int count) EXPORT_SYMBOL(pi_read_block); +#ifdef CONFIG_PARPORT + static void pi_wake_up(void *p) { PIA *pi = (PIA *) p; @@ -91,8 +100,11 @@ static void pi_wake_up(void *p) cont(); } +#endif + int pi_schedule_claimed(PIA * pi, void (*cont) (void)) { +#ifdef CONFIG_PARPORT unsigned long flags; spin_lock_irqsave(&pi_spinlock, flags); @@ -103,6 +115,7 @@ int pi_schedule_claimed(PIA * pi, void (*cont) (void)) } pi->claimed = 1; spin_unlock_irqrestore(&pi_spinlock, flags); +#endif return 1; } EXPORT_SYMBOL(pi_schedule_claimed); @@ -120,16 +133,20 @@ static void pi_claim(PIA * pi) if (pi->claimed) return; pi->claimed = 1; +#ifdef CONFIG_PARPORT if (pi->pardev) wait_event(pi->parq, !parport_claim((struct pardevice *) pi->pardev)); +#endif } static void pi_unclaim(PIA * pi) { pi->claimed = 0; +#ifdef CONFIG_PARPORT if (pi->pardev) parport_release((struct pardevice *) (pi->pardev)); +#endif } void pi_connect(PIA * pi) @@ -150,15 +167,21 @@ EXPORT_SYMBOL(pi_disconnect); static void pi_unregister_parport(PIA * pi) { +#ifdef CONFIG_PARPORT if (pi->pardev) { parport_unregister_device((struct pardevice *) (pi->pardev)); pi->pardev = NULL; } +#endif } void pi_release(PIA * pi) { pi_unregister_parport(pi); +#ifndef CONFIG_PARPORT + if (pi->reserved) + release_region(pi->port, pi->reserved); +#endif /* !CONFIG_PARPORT */ if (pi->proto->release_proto) pi->proto->release_proto(pi); module_put(pi->proto->owner); @@ -206,7 +229,7 @@ static int pi_test_proto(PIA * pi, char *scratch, int verbose) return res; } -int paride_register(PIP * pr) +int pi_register(PIP * pr) { int k; @@ -214,24 +237,24 @@ int paride_register(PIP * pr) if (protocols[k] && !strcmp(pr->name, protocols[k]->name)) { printk("paride: %s protocol already registered\n", pr->name); - return -1; + return 0; } k = 0; while ((k < MAX_PROTOS) && (protocols[k])) k++; if (k == MAX_PROTOS) { printk("paride: protocol table full\n"); - return -1; + return 0; } protocols[k] = pr; pr->index = k; printk("paride: %s registered as protocol %d\n", pr->name, k); - return 0; + return 1; } -EXPORT_SYMBOL(paride_register); +EXPORT_SYMBOL(pi_register); -void paride_unregister(PIP * pr) +void pi_unregister(PIP * pr) { if (!pr) return; @@ -242,10 +265,12 @@ void paride_unregister(PIP * pr) protocols[pr->index] = NULL; } -EXPORT_SYMBOL(paride_unregister); +EXPORT_SYMBOL(pi_unregister); static int pi_register_parport(PIA * pi, int verbose) { +#ifdef CONFIG_PARPORT + struct parport *port; port = parport_find_base(pi->port); @@ -265,6 +290,7 @@ static int pi_register_parport(PIA * pi, int verbose) printk("%s: 0x%x is %s\n", pi->device, pi->port, port->name); pi->parname = (char *) port->name; +#endif return 1; } @@ -421,6 +447,13 @@ int pi_init(PIA * pi, int autoprobe, int port, int mode, printk("%s: Adapter not found\n", device); return 0; } +#ifndef CONFIG_PARPORT + if (!request_region(pi->port, pi->reserved, pi->device)) { + printk(KERN_WARNING "paride: Unable to request region 0x%x\n", + pi->port); + return 0; + } +#endif /* !CONFIG_PARPORT */ if (pi->parname) printk("%s: Sharing %s at 0x%x\n", pi->device, diff --git a/trunk/drivers/block/paride/paride.h b/trunk/drivers/block/paride/paride.h index 2bddbf45518b..c6d98ef09e48 100644 --- a/trunk/drivers/block/paride/paride.h +++ b/trunk/drivers/block/paride/paride.h @@ -163,8 +163,8 @@ struct pi_protocol { typedef struct pi_protocol PIP; -extern int paride_register( PIP * ); -extern void paride_unregister ( PIP * ); +extern int pi_register( PIP * ); +extern void pi_unregister ( PIP * ); #endif /* __DRIVERS_PARIDE_H__ */ /* end of paride.h */ diff --git a/trunk/drivers/block/paride/pcd.c b/trunk/drivers/block/paride/pcd.c index c852eed91e4b..ac5ba462710b 100644 --- a/trunk/drivers/block/paride/pcd.c +++ b/trunk/drivers/block/paride/pcd.c @@ -912,12 +912,12 @@ static int __init pcd_init(void) int unit; if (disable) - return -EINVAL; + return -1; pcd_init_units(); if (pcd_detect()) - return -ENODEV; + return -1; /* get the atapi capabilities page */ pcd_probe_capabilities(); @@ -925,7 +925,7 @@ static int __init pcd_init(void) if (register_blkdev(major, name)) { for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) put_disk(cd->disk); - return -EBUSY; + return -1; } pcd_queue = blk_init_queue(do_pcd_request, &pcd_lock); @@ -933,7 +933,7 @@ static int __init pcd_init(void) unregister_blkdev(major, name); for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) put_disk(cd->disk); - return -ENOMEM; + return -1; } for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { diff --git a/trunk/drivers/block/paride/pf.c b/trunk/drivers/block/paride/pf.c index 7cdaa1951260..1a9dee19efcf 100644 --- a/trunk/drivers/block/paride/pf.c +++ b/trunk/drivers/block/paride/pf.c @@ -933,25 +933,25 @@ static int __init pf_init(void) int unit; if (disable) - return -EINVAL; + return -1; pf_init_units(); if (pf_detect()) - return -ENODEV; + return -1; pf_busy = 0; if (register_blkdev(major, name)) { for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) put_disk(pf->disk); - return -EBUSY; + return -1; } pf_queue = blk_init_queue(do_pf_request, &pf_spin_lock); if (!pf_queue) { unregister_blkdev(major, name); for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) put_disk(pf->disk); - return -ENOMEM; + return -1; } blk_queue_max_phys_segments(pf_queue, cluster); diff --git a/trunk/drivers/block/paride/pg.c b/trunk/drivers/block/paride/pg.c index 9970aedbb5d9..13f998aa1cd3 100644 --- a/trunk/drivers/block/paride/pg.c +++ b/trunk/drivers/block/paride/pg.c @@ -646,14 +646,14 @@ static int __init pg_init(void) int err; if (disable){ - err = -EINVAL; + err = -1; goto out; } pg_init_units(); if (pg_detect()) { - err = -ENODEV; + err = -1; goto out; } diff --git a/trunk/drivers/block/paride/pt.c b/trunk/drivers/block/paride/pt.c index c902b25e4869..35fb26636721 100644 --- a/trunk/drivers/block/paride/pt.c +++ b/trunk/drivers/block/paride/pt.c @@ -946,12 +946,12 @@ static int __init pt_init(void) int err; if (disable) { - err = -EINVAL; + err = -1; goto out; } if (pt_detect()) { - err = -ENODEV; + err = -1; goto out; } diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index e45eaa264119..f2904f67af47 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/bluetooth/hci_bcsp.c b/trunk/drivers/bluetooth/hci_bcsp.c index 5e2c31882003..d0cface535fb 100644 --- a/trunk/drivers/bluetooth/hci_bcsp.c +++ b/trunk/drivers/bluetooth/hci_bcsp.c @@ -330,7 +330,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) reliable packet if the number of packets sent but not yet ack'ed is < than the winsize */ - spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING); + spin_lock_irqsave(&bcsp->unack.lock, flags); if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) { struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type); @@ -696,7 +696,7 @@ static void bcsp_timed_event(unsigned long arg) BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen); - spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING); + spin_lock_irqsave(&bcsp->unack.lock, flags); while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) { bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07; diff --git a/trunk/drivers/cdrom/optcd.c b/trunk/drivers/cdrom/optcd.c index 3541690a77d4..25032d7edc55 100644 --- a/trunk/drivers/cdrom/optcd.c +++ b/trunk/drivers/cdrom/optcd.c @@ -101,7 +101,7 @@ static void debug(int debug_this, const char* fmt, ...) return; va_start(args, fmt); - vsnprintf(s, sizeof(s), fmt, args); + vsprintf(s, fmt, args); printk(KERN_DEBUG "optcd: %s\n", s); va_end(args); } diff --git a/trunk/drivers/cdrom/sbpcd.c b/trunk/drivers/cdrom/sbpcd.c index a1283b1ef989..ba50e5a712f2 100644 --- a/trunk/drivers/cdrom/sbpcd.c +++ b/trunk/drivers/cdrom/sbpcd.c @@ -770,10 +770,11 @@ static void msg(int level, const char *fmt, ...) msgnum++; if (msgnum>99) msgnum=0; + sprintf(buf, MSG_LEVEL "%s-%d [%02d]: ", major_name, current_drive - D_S, msgnum); va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); + vsprintf(&buf[18], fmt, args); va_end(args); - printk(MSG_LEVEL "%s-%d [%02d]: %s", major_name, current_drive - D_S, msgnum, buf); + printk(buf); #if KLOGD_PAUSE sbp_sleep(KLOGD_PAUSE); /* else messages get lost */ #endif /* KLOGD_PAUSE */ diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c index 2f2c4efff8a3..00b17ae39736 100644 --- a/trunk/drivers/char/agp/amd64-agp.c +++ b/trunk/drivers/char/agp/amd64-agp.c @@ -459,7 +459,7 @@ static const struct aper_size_info_32 nforce3_sizes[5] = /* Handle shadow device of the Nvidia NForce3 */ /* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */ -static int nforce3_agp_init(struct pci_dev *pdev) +static int __devinit nforce3_agp_init(struct pci_dev *pdev) { u32 tmp, apbase, apbar, aplimit; struct pci_dev *dev1; diff --git a/trunk/drivers/char/decserial.c b/trunk/drivers/char/decserial.c index 8ea2bea2b183..85f404e25c73 100644 --- a/trunk/drivers/char/decserial.c +++ b/trunk/drivers/char/decserial.c @@ -23,12 +23,20 @@ extern int zs_init(void); #endif +#ifdef CONFIG_DZ +extern int dz_init(void); +#endif + #ifdef CONFIG_SERIAL_CONSOLE #ifdef CONFIG_ZS extern void zs_serial_console_init(void); #endif +#ifdef CONFIG_DZ +extern void dz_serial_console_init(void); +#endif + #endif /* rs_init - starts up the serial interface - @@ -38,11 +46,23 @@ extern void zs_serial_console_init(void); int __init rs_init(void) { -#ifdef CONFIG_ZS + +#if defined(CONFIG_ZS) && defined(CONFIG_DZ) if (IOASIC) return zs_init(); + else + return dz_init(); +#else + +#ifdef CONFIG_ZS + return zs_init(); +#endif + +#ifdef CONFIG_DZ + return dz_init(); +#endif + #endif - return -ENXIO; } __initcall(rs_init); @@ -56,9 +76,21 @@ __initcall(rs_init); */ static int __init decserial_console_init(void) { -#ifdef CONFIG_ZS +#if defined(CONFIG_ZS) && defined(CONFIG_DZ) if (IOASIC) zs_serial_console_init(); + else + dz_serial_console_init(); +#else + +#ifdef CONFIG_ZS + zs_serial_console_init(); +#endif + +#ifdef CONFIG_DZ + dz_serial_console_init(); +#endif + #endif return 0; } diff --git a/trunk/drivers/char/drm/drm_sman.c b/trunk/drivers/char/drm/drm_sman.c index 19c81d2e13d0..425c82336ee0 100644 --- a/trunk/drivers/char/drm/drm_sman.c +++ b/trunk/drivers/char/drm/drm_sman.c @@ -162,7 +162,6 @@ drm_sman_set_manager(drm_sman_t * sman, unsigned int manager, return 0; } -EXPORT_SYMBOL(drm_sman_set_manager); static drm_owner_item_t *drm_sman_get_owner_item(drm_sman_t * sman, unsigned long owner) diff --git a/trunk/drivers/char/drm/drm_vm.c b/trunk/drivers/char/drm/drm_vm.c index ae2691942ddb..b40ae438f531 100644 --- a/trunk/drivers/char/drm/drm_vm.c +++ b/trunk/drivers/char/drm/drm_vm.c @@ -147,14 +147,14 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!map) - return NOPAGE_SIGBUS; /* Nothing allocated */ + return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; i = (unsigned long)map->handle + offset; page = (map->type == _DRM_CONSISTENT) ? virt_to_page((void *)i) : vmalloc_to_page((void *)i); if (!page) - return NOPAGE_SIGBUS; + return NOPAGE_OOM; get_page(page); DRM_DEBUG("shm_nopage 0x%lx\n", address); @@ -272,7 +272,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!dma->pagelist) - return NOPAGE_SIGBUS; /* Nothing allocated */ + return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ page_nr = offset >> PAGE_SHIFT; @@ -310,7 +310,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!entry->pagelist) - return NOPAGE_SIGBUS; /* Nothing allocated */ + return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; map_offset = map->offset - (unsigned long)dev->sg->virtual; diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index cc2cd46bedc6..9902ffad3b12 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -38,7 +38,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c index d090622f1dea..8728255c9463 100644 --- a/trunk/drivers/char/hvcs.c +++ b/trunk/drivers/char/hvcs.c @@ -337,6 +337,11 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp); static void hvcs_close(struct tty_struct *tty, struct file *filp); static void hvcs_hangup(struct tty_struct * tty); +static void hvcs_create_device_attrs(struct hvcs_struct *hvcsd); +static void hvcs_remove_device_attrs(struct vio_dev *vdev); +static void hvcs_create_driver_attrs(void); +static void hvcs_remove_driver_attrs(void); + static int __devinit hvcs_probe(struct vio_dev *dev, const struct vio_device_id *id); static int __devexit hvcs_remove(struct vio_dev *dev); @@ -348,172 +353,6 @@ static void __exit hvcs_module_exit(void); #define HVCS_TRY_WRITE 0x00000004 #define HVCS_READ_MASK (HVCS_SCHED_READ | HVCS_QUICK_READ) -static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) -{ - return viod->dev.driver_data; -} -/* The sysfs interface for the driver and devices */ - -static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct vio_dev *viod = to_vio_dev(dev); - struct hvcs_struct *hvcsd = from_vio_dev(viod); - unsigned long flags; - int retval; - - spin_lock_irqsave(&hvcsd->lock, flags); - retval = sprintf(buf, "%X\n", hvcsd->p_unit_address); - spin_unlock_irqrestore(&hvcsd->lock, flags); - return retval; -} -static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL); - -static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct vio_dev *viod = to_vio_dev(dev); - struct hvcs_struct *hvcsd = from_vio_dev(viod); - unsigned long flags; - int retval; - - spin_lock_irqsave(&hvcsd->lock, flags); - retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); - spin_unlock_irqrestore(&hvcsd->lock, flags); - return retval; -} -static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL); - -static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf, - size_t count) -{ - /* - * Don't need this feature at the present time because firmware doesn't - * yet support multiple partners. - */ - printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n"); - return -EPERM; -} - -static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct vio_dev *viod = to_vio_dev(dev); - struct hvcs_struct *hvcsd = from_vio_dev(viod); - unsigned long flags; - int retval; - - spin_lock_irqsave(&hvcsd->lock, flags); - retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); - spin_unlock_irqrestore(&hvcsd->lock, flags); - return retval; -} - -static DEVICE_ATTR(current_vty, - S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store); - -static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) -{ - struct vio_dev *viod = to_vio_dev(dev); - struct hvcs_struct *hvcsd = from_vio_dev(viod); - unsigned long flags; - - /* writing a '0' to this sysfs entry will result in the disconnect. */ - if (simple_strtol(buf, NULL, 0) != 0) - return -EINVAL; - - spin_lock_irqsave(&hvcsd->lock, flags); - - if (hvcsd->open_count > 0) { - spin_unlock_irqrestore(&hvcsd->lock, flags); - printk(KERN_INFO "HVCS: vterm state unchanged. " - "The hvcs device node is still in use.\n"); - return -EPERM; - } - - if (hvcsd->connected == 0) { - spin_unlock_irqrestore(&hvcsd->lock, flags); - printk(KERN_INFO "HVCS: vterm state unchanged. The" - " vty-server is not connected to a vty.\n"); - return -EPERM; - } - - hvcs_partner_free(hvcsd); - printk(KERN_INFO "HVCS: Closed vty-server@%X and" - " partner vty@%X:%d connection.\n", - hvcsd->vdev->unit_address, - hvcsd->p_unit_address, - (uint32_t)hvcsd->p_partition_ID); - - spin_unlock_irqrestore(&hvcsd->lock, flags); - return count; -} - -static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct vio_dev *viod = to_vio_dev(dev); - struct hvcs_struct *hvcsd = from_vio_dev(viod); - unsigned long flags; - int retval; - - spin_lock_irqsave(&hvcsd->lock, flags); - retval = sprintf(buf, "%d\n", hvcsd->connected); - spin_unlock_irqrestore(&hvcsd->lock, flags); - return retval; -} -static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR, - hvcs_vterm_state_show, hvcs_vterm_state_store); - -static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct vio_dev *viod = to_vio_dev(dev); - struct hvcs_struct *hvcsd = from_vio_dev(viod); - unsigned long flags; - int retval; - - spin_lock_irqsave(&hvcsd->lock, flags); - retval = sprintf(buf, "%d\n", hvcsd->index); - spin_unlock_irqrestore(&hvcsd->lock, flags); - return retval; -} - -static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL); - -static struct attribute *hvcs_attrs[] = { - &dev_attr_partner_vtys.attr, - &dev_attr_partner_clcs.attr, - &dev_attr_current_vty.attr, - &dev_attr_vterm_state.attr, - &dev_attr_index.attr, - NULL, -}; - -static struct attribute_group hvcs_attr_group = { - .attrs = hvcs_attrs, -}; - -static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf) -{ - /* A 1 means it is updating, a 0 means it is done updating */ - return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status); -} - -static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf, - size_t count) -{ - if ((simple_strtol(buf, NULL, 0) != 1) - && (hvcs_rescan_status != 0)) - return -EINVAL; - - hvcs_rescan_status = 1; - printk(KERN_INFO "HVCS: rescanning partner info for all" - " vty-servers.\n"); - hvcs_rescan_devices_list(); - hvcs_rescan_status = 0; - return count; -} - -static DRIVER_ATTR(rescan, - S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store); - static void hvcs_kick(void) { hvcs_kicked = 1; @@ -736,7 +575,7 @@ static void destroy_hvcs_struct(struct kobject *kobj) spin_unlock_irqrestore(&hvcsd->lock, flags); spin_unlock(&hvcs_structs_lock); - sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group); + hvcs_remove_device_attrs(vdev); kfree(hvcsd); } @@ -769,7 +608,6 @@ static int __devinit hvcs_probe( { struct hvcs_struct *hvcsd; int index; - int retval; if (!dev || !id) { printk(KERN_ERR "HVCS: probed with invalid parameter.\n"); @@ -820,16 +658,14 @@ static int __devinit hvcs_probe( * the hvcs_struct has been added to the devices list then the user app * will get -ENODEV. */ + spin_lock(&hvcs_structs_lock); + list_add_tail(&(hvcsd->next), &hvcs_structs); + spin_unlock(&hvcs_structs_lock); - retval = sysfs_create_group(&dev->dev.kobj, &hvcs_attr_group); - if (retval) { - printk(KERN_ERR "HVCS: Can't create sysfs attrs for vty-server@%X\n", - hvcsd->vdev->unit_address); - return retval; - } + hvcs_create_device_attrs(hvcsd); printk(KERN_INFO "HVCS: vty-server@%X added to the vio bus.\n", dev->unit_address); @@ -1518,10 +1354,8 @@ static int __init hvcs_module_init(void) if (!hvcs_tty_driver) return -ENOMEM; - if (hvcs_alloc_index_list(num_ttys_to_alloc)) { - rc = -ENOMEM; - goto index_fail; - } + if (hvcs_alloc_index_list(num_ttys_to_alloc)) + return -ENOMEM; hvcs_tty_driver->owner = THIS_MODULE; @@ -1551,57 +1385,41 @@ static int __init hvcs_module_init(void) * dynamically assigned major and minor numbers for our devices. */ if (tty_register_driver(hvcs_tty_driver)) { - printk(KERN_ERR "HVCS: registration as a tty driver failed.\n"); - rc = -EIO; - goto register_fail; + printk(KERN_ERR "HVCS: registration " + " as a tty driver failed.\n"); + hvcs_free_index_list(); + put_tty_driver(hvcs_tty_driver); + return -EIO; } hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!hvcs_pi_buff) { - rc = -ENOMEM; - goto buff_alloc_fail; + tty_unregister_driver(hvcs_tty_driver); + hvcs_free_index_list(); + put_tty_driver(hvcs_tty_driver); + return -ENOMEM; } hvcs_task = kthread_run(khvcsd, NULL, "khvcsd"); if (IS_ERR(hvcs_task)) { printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n"); - rc = -EIO; - goto kthread_fail; + kfree(hvcs_pi_buff); + tty_unregister_driver(hvcs_tty_driver); + hvcs_free_index_list(); + put_tty_driver(hvcs_tty_driver); + return -EIO; } rc = vio_register_driver(&hvcs_vio_driver); - if (rc) { - printk(KERN_ERR "HVCS: can't register vio driver\n"); - goto vio_fail; - } /* * This needs to be done AFTER the vio_register_driver() call or else * the kobjects won't be initialized properly. */ - rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); - if (rc) { - printk(KERN_ERR "HVCS: sysfs attr create failed\n"); - goto attr_fail; - } + hvcs_create_driver_attrs(); printk(KERN_INFO "HVCS: driver module inserted.\n"); - return 0; - -attr_fail: - vio_unregister_driver(&hvcs_vio_driver); -vio_fail: - kthread_stop(hvcs_task); -kthread_fail: - kfree(hvcs_pi_buff); -buff_alloc_fail: - tty_unregister_driver(hvcs_tty_driver); -register_fail: - hvcs_free_index_list(); -index_fail: - put_tty_driver(hvcs_tty_driver); - hvcs_tty_driver = NULL; return rc; } @@ -1623,7 +1441,7 @@ static void __exit hvcs_module_exit(void) hvcs_pi_buff = NULL; spin_unlock(&hvcs_pi_lock); - driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan); + hvcs_remove_driver_attrs(); vio_unregister_driver(&hvcs_vio_driver); @@ -1638,3 +1456,191 @@ static void __exit hvcs_module_exit(void) module_init(hvcs_module_init); module_exit(hvcs_module_exit); + +static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) +{ + return viod->dev.driver_data; +} +/* The sysfs interface for the driver and devices */ + +static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct vio_dev *viod = to_vio_dev(dev); + struct hvcs_struct *hvcsd = from_vio_dev(viod); + unsigned long flags; + int retval; + + spin_lock_irqsave(&hvcsd->lock, flags); + retval = sprintf(buf, "%X\n", hvcsd->p_unit_address); + spin_unlock_irqrestore(&hvcsd->lock, flags); + return retval; +} +static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL); + +static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct vio_dev *viod = to_vio_dev(dev); + struct hvcs_struct *hvcsd = from_vio_dev(viod); + unsigned long flags; + int retval; + + spin_lock_irqsave(&hvcsd->lock, flags); + retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); + spin_unlock_irqrestore(&hvcsd->lock, flags); + return retval; +} +static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL); + +static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf, + size_t count) +{ + /* + * Don't need this feature at the present time because firmware doesn't + * yet support multiple partners. + */ + printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n"); + return -EPERM; +} + +static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct vio_dev *viod = to_vio_dev(dev); + struct hvcs_struct *hvcsd = from_vio_dev(viod); + unsigned long flags; + int retval; + + spin_lock_irqsave(&hvcsd->lock, flags); + retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); + spin_unlock_irqrestore(&hvcsd->lock, flags); + return retval; +} + +static DEVICE_ATTR(current_vty, + S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store); + +static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + struct vio_dev *viod = to_vio_dev(dev); + struct hvcs_struct *hvcsd = from_vio_dev(viod); + unsigned long flags; + + /* writing a '0' to this sysfs entry will result in the disconnect. */ + if (simple_strtol(buf, NULL, 0) != 0) + return -EINVAL; + + spin_lock_irqsave(&hvcsd->lock, flags); + + if (hvcsd->open_count > 0) { + spin_unlock_irqrestore(&hvcsd->lock, flags); + printk(KERN_INFO "HVCS: vterm state unchanged. " + "The hvcs device node is still in use.\n"); + return -EPERM; + } + + if (hvcsd->connected == 0) { + spin_unlock_irqrestore(&hvcsd->lock, flags); + printk(KERN_INFO "HVCS: vterm state unchanged. The" + " vty-server is not connected to a vty.\n"); + return -EPERM; + } + + hvcs_partner_free(hvcsd); + printk(KERN_INFO "HVCS: Closed vty-server@%X and" + " partner vty@%X:%d connection.\n", + hvcsd->vdev->unit_address, + hvcsd->p_unit_address, + (uint32_t)hvcsd->p_partition_ID); + + spin_unlock_irqrestore(&hvcsd->lock, flags); + return count; +} + +static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct vio_dev *viod = to_vio_dev(dev); + struct hvcs_struct *hvcsd = from_vio_dev(viod); + unsigned long flags; + int retval; + + spin_lock_irqsave(&hvcsd->lock, flags); + retval = sprintf(buf, "%d\n", hvcsd->connected); + spin_unlock_irqrestore(&hvcsd->lock, flags); + return retval; +} +static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR, + hvcs_vterm_state_show, hvcs_vterm_state_store); + +static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct vio_dev *viod = to_vio_dev(dev); + struct hvcs_struct *hvcsd = from_vio_dev(viod); + unsigned long flags; + int retval; + + spin_lock_irqsave(&hvcsd->lock, flags); + retval = sprintf(buf, "%d\n", hvcsd->index); + spin_unlock_irqrestore(&hvcsd->lock, flags); + return retval; +} + +static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL); + +static struct attribute *hvcs_attrs[] = { + &dev_attr_partner_vtys.attr, + &dev_attr_partner_clcs.attr, + &dev_attr_current_vty.attr, + &dev_attr_vterm_state.attr, + &dev_attr_index.attr, + NULL, +}; + +static struct attribute_group hvcs_attr_group = { + .attrs = hvcs_attrs, +}; + +static void hvcs_create_device_attrs(struct hvcs_struct *hvcsd) +{ + struct vio_dev *vdev = hvcsd->vdev; + sysfs_create_group(&vdev->dev.kobj, &hvcs_attr_group); +} + +static void hvcs_remove_device_attrs(struct vio_dev *vdev) +{ + sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group); +} + +static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf) +{ + /* A 1 means it is updating, a 0 means it is done updating */ + return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status); +} + +static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf, + size_t count) +{ + if ((simple_strtol(buf, NULL, 0) != 1) + && (hvcs_rescan_status != 0)) + return -EINVAL; + + hvcs_rescan_status = 1; + printk(KERN_INFO "HVCS: rescanning partner info for all" + " vty-servers.\n"); + hvcs_rescan_devices_list(); + hvcs_rescan_status = 0; + return count; +} +static DRIVER_ATTR(rescan, + S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store); + +static void hvcs_create_driver_attrs(void) +{ + struct device_driver *driverfs = &(hvcs_vio_driver.driver); + driver_create_file(driverfs, &driver_attr_rescan); +} + +static void hvcs_remove_driver_attrs(void) +{ + struct device_driver *driverfs = &(hvcs_vio_driver.driver); + driver_remove_file(driverfs, &driver_attr_rescan); +} diff --git a/trunk/drivers/char/hw_random/Kconfig b/trunk/drivers/char/hw_random/Kconfig index 5f3acd8e64b8..9f7635f75178 100644 --- a/trunk/drivers/char/hw_random/Kconfig +++ b/trunk/drivers/char/hw_random/Kconfig @@ -3,20 +3,17 @@ # config HW_RANDOM - tristate "Hardware Random Number Generator Core support" - default m + bool "Hardware Random Number Generator Core support" + default y ---help--- Hardware Random Number Generator Core infrastructure. - To compile this driver as a module, choose M here: the - module will be called rng-core. - If unsure, say Y. config HW_RANDOM_INTEL tristate "Intel HW Random Number Generator support" depends on HW_RANDOM && (X86 || IA64) && PCI - default HW_RANDOM + default y ---help--- This driver provides kernel-side support for the Random Number Generator hardware found on Intel i8xx-based motherboards. @@ -29,7 +26,7 @@ config HW_RANDOM_INTEL config HW_RANDOM_AMD tristate "AMD HW Random Number Generator support" depends on HW_RANDOM && X86 && PCI - default HW_RANDOM + default y ---help--- This driver provides kernel-side support for the Random Number Generator hardware found on AMD 76x-based motherboards. @@ -42,7 +39,7 @@ config HW_RANDOM_AMD config HW_RANDOM_GEODE tristate "AMD Geode HW Random Number Generator support" depends on HW_RANDOM && X86 && PCI - default HW_RANDOM + default y ---help--- This driver provides kernel-side support for the Random Number Generator hardware found on the AMD Geode LX. @@ -55,7 +52,7 @@ config HW_RANDOM_GEODE config HW_RANDOM_VIA tristate "VIA HW Random Number Generator support" depends on HW_RANDOM && X86_32 - default HW_RANDOM + default y ---help--- This driver provides kernel-side support for the Random Number Generator hardware found on VIA based motherboards. @@ -68,7 +65,7 @@ config HW_RANDOM_VIA config HW_RANDOM_IXP4XX tristate "Intel IXP4xx NPU HW Random Number Generator support" depends on HW_RANDOM && ARCH_IXP4XX - default HW_RANDOM + default y ---help--- This driver provides kernel-side support for the Random Number Generator hardware found on the Intel IXP4xx NPU. @@ -81,7 +78,7 @@ config HW_RANDOM_IXP4XX config HW_RANDOM_OMAP tristate "OMAP Random Number Generator support" depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX) - default HW_RANDOM + default y ---help--- This driver provides kernel-side support for the Random Number Generator hardware found on OMAP16xx and OMAP24xx multimedia diff --git a/trunk/drivers/char/hw_random/Makefile b/trunk/drivers/char/hw_random/Makefile index c41fa19454e3..e263ae96f940 100644 --- a/trunk/drivers/char/hw_random/Makefile +++ b/trunk/drivers/char/hw_random/Makefile @@ -2,8 +2,7 @@ # Makefile for HW Random Number Generator (RNG) device drivers. # -obj-$(CONFIG_HW_RANDOM) += rng-core.o -rng-core-y := core.o +obj-$(CONFIG_HW_RANDOM) += core.o obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o diff --git a/trunk/drivers/char/ip2/i2cmd.h b/trunk/drivers/char/ip2/i2cmd.h index 29277ec6b8ed..baa4e721b758 100644 --- a/trunk/drivers/char/ip2/i2cmd.h +++ b/trunk/drivers/char/ip2/i2cmd.h @@ -367,6 +367,11 @@ static UCHAR cc02[]; #define CSE_NULL 3 // Replace with a null #define CSE_MARK 4 // Replace with a 3-character sequence (as Unix) +#define CMD_SET_REPLACEMENT(arg,ch) \ + (((cmdSyntaxPtr)(ct36a))->cmd[1] = (arg), \ + (((cmdSyntaxPtr)(ct36a))->cmd[2] = (ch), \ + (cmdSyntaxPtr)(ct36a)) + #define CSE_REPLACE 0x8 // Replace the errored character with the // replacement character defined here diff --git a/trunk/drivers/char/ip2/i2lib.c b/trunk/drivers/char/ip2/i2lib.c index 78045767ec33..c213fdbdb2b0 100644 --- a/trunk/drivers/char/ip2/i2lib.c +++ b/trunk/drivers/char/ip2/i2lib.c @@ -1016,6 +1016,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count) unsigned short channel; unsigned short stuffIndex; unsigned long flags; + int rc = 0; int bailout = 10; diff --git a/trunk/drivers/char/ipmi/ipmi_bt_sm.c b/trunk/drivers/char/ipmi/ipmi_bt_sm.c index 6c59baa887a8..0030cd8e2e95 100644 --- a/trunk/drivers/char/ipmi/ipmi_bt_sm.c +++ b/trunk/drivers/char/ipmi/ipmi_bt_sm.c @@ -33,13 +33,11 @@ #include /* for completion codes */ #include "ipmi_si_sm.h" -#define BT_DEBUG_OFF 0 /* Used in production */ -#define BT_DEBUG_ENABLE 1 /* Generic messages */ -#define BT_DEBUG_MSG 2 /* Prints all request/response buffers */ -#define BT_DEBUG_STATES 4 /* Verbose look at state changes */ - -static int bt_debug = BT_DEBUG_OFF; +static int bt_debug = 0x00; /* Production value 0, see following flags */ +#define BT_DEBUG_ENABLE 1 +#define BT_DEBUG_MSG 2 +#define BT_DEBUG_STATES 4 module_param(bt_debug, int, 0644); MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); @@ -49,54 +47,38 @@ MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); Since the Open IPMI architecture is single-message oriented at this stage, the queue depth of BT is of no concern. */ -#define BT_NORMAL_TIMEOUT 5 /* seconds */ -#define BT_NORMAL_RETRY_LIMIT 2 -#define BT_RESET_DELAY 6 /* seconds after warm reset */ - -/* States are written in chronological order and usually cover - multiple rows of the state table discussion in the IPMI spec. */ +#define BT_NORMAL_TIMEOUT 5000000 /* seconds in microseconds */ +#define BT_RETRY_LIMIT 2 +#define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */ enum bt_states { - BT_STATE_IDLE = 0, /* Order is critical in this list */ + BT_STATE_IDLE, BT_STATE_XACTION_START, BT_STATE_WRITE_BYTES, + BT_STATE_WRITE_END, BT_STATE_WRITE_CONSUME, - BT_STATE_READ_WAIT, - BT_STATE_CLEAR_B2H, - BT_STATE_READ_BYTES, - BT_STATE_RESET1, /* These must come last */ + BT_STATE_B2H_WAIT, + BT_STATE_READ_END, + BT_STATE_RESET1, /* These must come last */ BT_STATE_RESET2, BT_STATE_RESET3, BT_STATE_RESTART, - BT_STATE_PRINTME, - BT_STATE_CAPABILITIES_BEGIN, - BT_STATE_CAPABILITIES_END, - BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */ + BT_STATE_HOSED }; -/* Macros seen at the end of state "case" blocks. They help with legibility - and debugging. */ - -#define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; } - -#define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; } - struct si_sm_data { enum bt_states state; + enum bt_states last_state; /* assist printing and resets */ unsigned char seq; /* BT sequence number */ struct si_sm_io *io; - unsigned char write_data[IPMI_MAX_MSG_LENGTH]; - int write_count; - unsigned char read_data[IPMI_MAX_MSG_LENGTH]; - int read_count; - int truncated; - long timeout; /* microseconds countdown */ - int error_retries; /* end of "common" fields */ + unsigned char write_data[IPMI_MAX_MSG_LENGTH]; + int write_count; + unsigned char read_data[IPMI_MAX_MSG_LENGTH]; + int read_count; + int truncated; + long timeout; + unsigned int error_retries; /* end of "common" fields */ int nonzero_status; /* hung BMCs stay all 0 */ - enum bt_states complete; /* to divert the state machine */ - int BT_CAP_outreqs; - long BT_CAP_req2rsp; - int BT_CAP_retries; /* Recommended retries */ }; #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */ @@ -129,118 +111,86 @@ struct si_sm_data { static char *state2txt(unsigned char state) { switch (state) { - case BT_STATE_IDLE: return("IDLE"); - case BT_STATE_XACTION_START: return("XACTION"); - case BT_STATE_WRITE_BYTES: return("WR_BYTES"); - case BT_STATE_WRITE_CONSUME: return("WR_CONSUME"); - case BT_STATE_READ_WAIT: return("RD_WAIT"); - case BT_STATE_CLEAR_B2H: return("CLEAR_B2H"); - case BT_STATE_READ_BYTES: return("RD_BYTES"); - case BT_STATE_RESET1: return("RESET1"); - case BT_STATE_RESET2: return("RESET2"); - case BT_STATE_RESET3: return("RESET3"); - case BT_STATE_RESTART: return("RESTART"); - case BT_STATE_LONG_BUSY: return("LONG_BUSY"); - case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN"); - case BT_STATE_CAPABILITIES_END: return("CAP_END"); + case BT_STATE_IDLE: return("IDLE"); + case BT_STATE_XACTION_START: return("XACTION"); + case BT_STATE_WRITE_BYTES: return("WR_BYTES"); + case BT_STATE_WRITE_END: return("WR_END"); + case BT_STATE_WRITE_CONSUME: return("WR_CONSUME"); + case BT_STATE_B2H_WAIT: return("B2H_WAIT"); + case BT_STATE_READ_END: return("RD_END"); + case BT_STATE_RESET1: return("RESET1"); + case BT_STATE_RESET2: return("RESET2"); + case BT_STATE_RESET3: return("RESET3"); + case BT_STATE_RESTART: return("RESTART"); + case BT_STATE_HOSED: return("HOSED"); } return("BAD STATE"); } #define STATE2TXT state2txt(bt->state) -static char *status2txt(unsigned char status) +static char *status2txt(unsigned char status, char *buf) { - /* - * This cannot be called by two threads at the same time and - * the buffer is always consumed immediately, so the static is - * safe to use. - */ - static char buf[40]; - strcpy(buf, "[ "); - if (status & BT_B_BUSY) - strcat(buf, "B_BUSY "); - if (status & BT_H_BUSY) - strcat(buf, "H_BUSY "); - if (status & BT_OEM0) - strcat(buf, "OEM0 "); - if (status & BT_SMS_ATN) - strcat(buf, "SMS "); - if (status & BT_B2H_ATN) - strcat(buf, "B2H "); - if (status & BT_H2B_ATN) - strcat(buf, "H2B "); + if (status & BT_B_BUSY) strcat(buf, "B_BUSY "); + if (status & BT_H_BUSY) strcat(buf, "H_BUSY "); + if (status & BT_OEM0) strcat(buf, "OEM0 "); + if (status & BT_SMS_ATN) strcat(buf, "SMS "); + if (status & BT_B2H_ATN) strcat(buf, "B2H "); + if (status & BT_H2B_ATN) strcat(buf, "H2B "); strcat(buf, "]"); return buf; } -#define STATUS2TXT status2txt(status) - -/* called externally at insmod time, and internally on cleanup */ +#define STATUS2TXT(buf) status2txt(status, buf) +/* This will be called from within this module on a hosed condition */ +#define FIRST_SEQ 0 static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io) { - memset(bt, 0, sizeof(struct si_sm_data)); - if (bt->io != io) { /* external: one-time only things */ - bt->io = io; - bt->seq = 0; - } - bt->state = BT_STATE_IDLE; /* start here */ - bt->complete = BT_STATE_IDLE; /* end here */ - bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * 1000000; - bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT; - /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */ + bt->state = BT_STATE_IDLE; + bt->last_state = BT_STATE_IDLE; + bt->seq = FIRST_SEQ; + bt->io = io; + bt->write_count = 0; + bt->read_count = 0; + bt->error_retries = 0; + bt->nonzero_status = 0; + bt->truncated = 0; + bt->timeout = BT_NORMAL_TIMEOUT; return 3; /* We claim 3 bytes of space; ought to check SPMI table */ } -/* Jam a completion code (probably an error) into a response */ - -static void force_result(struct si_sm_data *bt, unsigned char completion_code) -{ - bt->read_data[0] = 4; /* # following bytes */ - bt->read_data[1] = bt->write_data[1] | 4; /* Odd NetFn/LUN */ - bt->read_data[2] = bt->write_data[2]; /* seq (ignored) */ - bt->read_data[3] = bt->write_data[3]; /* Command */ - bt->read_data[4] = completion_code; - bt->read_count = 5; -} - -/* The upper state machine starts here */ - static int bt_start_transaction(struct si_sm_data *bt, unsigned char *data, unsigned int size) { unsigned int i; - if (size < 2) - return IPMI_REQ_LEN_INVALID_ERR; - if (size > IPMI_MAX_MSG_LENGTH) - return IPMI_REQ_LEN_EXCEEDED_ERR; + if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2))) + return -1; - if (bt->state == BT_STATE_LONG_BUSY) - return IPMI_NODE_BUSY_ERR; - - if (bt->state != BT_STATE_IDLE) - return IPMI_NOT_IN_MY_STATE_ERR; + if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) + return -2; if (bt_debug & BT_DEBUG_MSG) { - printk(KERN_WARNING "BT: +++++++++++++++++ New command\n"); - printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2); + printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n"); + printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq); for (i = 0; i < size; i ++) - printk (" %02x", data[i]); + printk (" %02x", data[i]); printk("\n"); } bt->write_data[0] = size + 1; /* all data plus seq byte */ bt->write_data[1] = *data; /* NetFn/LUN */ - bt->write_data[2] = bt->seq++; + bt->write_data[2] = bt->seq; memcpy(bt->write_data + 3, data + 1, size - 1); bt->write_count = size + 2; + bt->error_retries = 0; bt->nonzero_status = 0; + bt->read_count = 0; bt->truncated = 0; bt->state = BT_STATE_XACTION_START; - bt->timeout = bt->BT_CAP_req2rsp; - force_result(bt, IPMI_ERR_UNSPECIFIED); + bt->last_state = BT_STATE_IDLE; + bt->timeout = BT_NORMAL_TIMEOUT; return 0; } @@ -248,30 +198,38 @@ static int bt_start_transaction(struct si_sm_data *bt, it calls this. Strip out the length and seq bytes. */ static int bt_get_result(struct si_sm_data *bt, - unsigned char *data, - unsigned int length) + unsigned char *data, + unsigned int length) { int i, msg_len; msg_len = bt->read_count - 2; /* account for length & seq */ + /* Always NetFn, Cmd, cCode */ if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) { - force_result(bt, IPMI_ERR_UNSPECIFIED); + printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len); + data[0] = bt->write_data[1] | 0x4; /* Kludge a response */ + data[1] = bt->write_data[3]; + data[2] = IPMI_ERR_UNSPECIFIED; msg_len = 3; - } - data[0] = bt->read_data[1]; - data[1] = bt->read_data[3]; - if (length < msg_len || bt->truncated) { - data[2] = IPMI_ERR_MSG_TRUNCATED; - msg_len = 3; - } else - memcpy(data + 2, bt->read_data + 4, msg_len - 2); + } else { + data[0] = bt->read_data[1]; + data[1] = bt->read_data[3]; + if (length < msg_len) + bt->truncated = 1; + if (bt->truncated) { /* can be set in read_all_bytes() */ + data[2] = IPMI_ERR_MSG_TRUNCATED; + msg_len = 3; + } else + memcpy(data + 2, bt->read_data + 4, msg_len - 2); - if (bt_debug & BT_DEBUG_MSG) { - printk (KERN_WARNING "BT: result %d bytes:", msg_len); - for (i = 0; i < msg_len; i++) - printk(" %02x", data[i]); - printk ("\n"); + if (bt_debug & BT_DEBUG_MSG) { + printk (KERN_WARNING "BT: res (raw)"); + for (i = 0; i < msg_len; i++) + printk(" %02x", data[i]); + printk ("\n"); + } } + bt->read_count = 0; /* paranoia */ return msg_len; } @@ -280,40 +238,22 @@ static int bt_get_result(struct si_sm_data *bt, static void reset_flags(struct si_sm_data *bt) { - if (bt_debug) - printk(KERN_WARNING "IPMI BT: flag reset %s\n", - status2txt(BT_STATUS)); if (BT_STATUS & BT_H_BUSY) - BT_CONTROL(BT_H_BUSY); /* force clear */ - BT_CONTROL(BT_CLR_WR_PTR); /* always reset */ - BT_CONTROL(BT_SMS_ATN); /* always clear */ - BT_INTMASK_W(BT_BMC_HWRST); -} - -/* Get rid of an unwanted/stale response. This should only be needed for - BMCs that support multiple outstanding requests. */ - -static void drain_BMC2HOST(struct si_sm_data *bt) -{ - int i, size; - - if (!(BT_STATUS & BT_B2H_ATN)) /* Not signalling a response */ - return; - - BT_CONTROL(BT_H_BUSY); /* now set */ - BT_CONTROL(BT_B2H_ATN); /* always clear */ - BT_STATUS; /* pause */ - BT_CONTROL(BT_B2H_ATN); /* some BMCs are stubborn */ - BT_CONTROL(BT_CLR_RD_PTR); /* always reset */ - if (bt_debug) - printk(KERN_WARNING "IPMI BT: stale response %s; ", - status2txt(BT_STATUS)); - size = BMC2HOST; - for (i = 0; i < size ; i++) - BMC2HOST; - BT_CONTROL(BT_H_BUSY); /* now clear */ - if (bt_debug) - printk("drained %d bytes\n", size + 1); + BT_CONTROL(BT_H_BUSY); + if (BT_STATUS & BT_B_BUSY) + BT_CONTROL(BT_B_BUSY); + BT_CONTROL(BT_CLR_WR_PTR); + BT_CONTROL(BT_SMS_ATN); + + if (BT_STATUS & BT_B2H_ATN) { + int i; + BT_CONTROL(BT_H_BUSY); + BT_CONTROL(BT_B2H_ATN); + BT_CONTROL(BT_CLR_RD_PTR); + for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++) + BMC2HOST; + BT_CONTROL(BT_H_BUSY); + } } static inline void write_all_bytes(struct si_sm_data *bt) @@ -321,256 +261,201 @@ static inline void write_all_bytes(struct si_sm_data *bt) int i; if (bt_debug & BT_DEBUG_MSG) { - printk(KERN_WARNING "BT: write %d bytes seq=0x%02X", + printk(KERN_WARNING "BT: write %d bytes seq=0x%02X", bt->write_count, bt->seq); for (i = 0; i < bt->write_count; i++) printk (" %02x", bt->write_data[i]); printk ("\n"); } for (i = 0; i < bt->write_count; i++) - HOST2BMC(bt->write_data[i]); + HOST2BMC(bt->write_data[i]); } static inline int read_all_bytes(struct si_sm_data *bt) { unsigned char i; - /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode. - Keep layout of first four bytes aligned with write_data[] */ - bt->read_data[0] = BMC2HOST; bt->read_count = bt->read_data[0]; + if (bt_debug & BT_DEBUG_MSG) + printk(KERN_WARNING "BT: read %d bytes:", bt->read_count); + /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more + following the length byte. */ if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) { if (bt_debug & BT_DEBUG_MSG) - printk(KERN_WARNING "BT: bad raw rsp len=%d\n", - bt->read_count); + printk("bad length %d\n", bt->read_count); bt->truncated = 1; return 1; /* let next XACTION START clean it up */ } for (i = 1; i <= bt->read_count; i++) - bt->read_data[i] = BMC2HOST; - bt->read_count++; /* Account internally for length byte */ + bt->read_data[i] = BMC2HOST; + bt->read_count++; /* account for the length byte */ if (bt_debug & BT_DEBUG_MSG) { - int max = bt->read_count; - - printk(KERN_WARNING "BT: got %d bytes seq=0x%02X", - max, bt->read_data[2]); - if (max > 16) - max = 16; - for (i = 0; i < max; i++) + for (i = 0; i < bt->read_count; i++) printk (" %02x", bt->read_data[i]); - printk ("%s\n", bt->read_count == max ? "" : " ..."); + printk ("\n"); } + if (bt->seq != bt->write_data[2]) /* idiot check */ + printk(KERN_DEBUG "BT: internal error: sequence mismatch\n"); - /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */ - if ((bt->read_data[3] == bt->write_data[3]) && - (bt->read_data[2] == bt->write_data[2]) && - ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8))) + /* per the spec, the (NetFn, Seq, Cmd) tuples should match */ + if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */ + (bt->read_data[2] == bt->write_data[2]) && /* Sequence */ + ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8))) return 1; if (bt_debug & BT_DEBUG_MSG) - printk(KERN_WARNING "IPMI BT: bad packet: " + printk(KERN_WARNING "BT: bad packet: " "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n", - bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3], + bt->write_data[1], bt->write_data[2], bt->write_data[3], bt->read_data[1], bt->read_data[2], bt->read_data[3]); return 0; } -/* Restart if retries are left, or return an error completion code */ +/* Modifies bt->state appropriately, need to get into the bt_event() switch */ -static enum si_sm_result error_recovery(struct si_sm_data *bt, - unsigned char status, - unsigned char cCode) +static void error_recovery(struct si_sm_data *bt, char *reason) { - char *reason; + unsigned char status; + char buf[40]; /* For getting status */ - bt->timeout = bt->BT_CAP_req2rsp; - - switch (cCode) { - case IPMI_TIMEOUT_ERR: - reason = "timeout"; - break; - default: - reason = "internal error"; - break; - } + bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */ - printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */ - reason, STATE2TXT, STATUS2TXT); + status = BT_STATUS; + printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT, + STATUS2TXT(buf)); - /* Per the IPMI spec, retries are based on the sequence number - known only to this module, so manage a restart here. */ (bt->error_retries)++; - if (bt->error_retries < bt->BT_CAP_retries) { - printk("%d retries left\n", - bt->BT_CAP_retries - bt->error_retries); - bt->state = BT_STATE_RESTART; - return SI_SM_CALL_WITHOUT_DELAY; + if (bt->error_retries > BT_RETRY_LIMIT) { + printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT); + bt->state = BT_STATE_HOSED; + if (!bt->nonzero_status) + printk(KERN_ERR "IPMI: BT stuck, try power cycle\n"); + else if (bt->error_retries <= BT_RETRY_LIMIT + 1) { + printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n"); + bt->state = BT_STATE_RESET1; + } + return; } - printk("failed %d retries, sending error response\n", - bt->BT_CAP_retries); - if (!bt->nonzero_status) - printk(KERN_ERR "IPMI BT: stuck, try power cycle\n"); - - /* this is most likely during insmod */ - else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) { - printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n"); - bt->state = BT_STATE_RESET1; - return SI_SM_CALL_WITHOUT_DELAY; + /* Sometimes the BMC queues get in an "off-by-one" state...*/ + if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) { + printk(KERN_DEBUG "retry B2H_WAIT\n"); + return; } - /* Concoct a useful error message, set up the next state, and - be done with this sequence. */ - - bt->state = BT_STATE_IDLE; - switch (cCode) { - case IPMI_TIMEOUT_ERR: - if (status & BT_B_BUSY) { - cCode = IPMI_NODE_BUSY_ERR; - bt->state = BT_STATE_LONG_BUSY; - } - break; - default: - break; - } - force_result(bt, cCode); - return SI_SM_TRANSACTION_COMPLETE; + printk(KERN_DEBUG "restart command\n"); + bt->state = BT_STATE_RESTART; } -/* Check status and (usually) take action and change this state machine. */ +/* Check the status and (possibly) advance the BT state machine. The + default return is SI_SM_CALL_WITH_DELAY. */ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) { - unsigned char status, BT_CAP[8]; - static enum bt_states last_printed = BT_STATE_PRINTME; + unsigned char status; + char buf[40]; /* For getting status */ int i; status = BT_STATUS; bt->nonzero_status |= status; - if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) { + + if ((bt_debug & BT_DEBUG_STATES) && (bt->state != bt->last_state)) printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n", STATE2TXT, - STATUS2TXT, + STATUS2TXT(buf), bt->timeout, time); - last_printed = bt->state; - } + bt->last_state = bt->state; - /* Commands that time out may still (eventually) provide a response. - This stale response will get in the way of a new response so remove - it if possible (hopefully during IDLE). Even if it comes up later - it will be rejected by its (now-forgotten) seq number. */ - - if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) { - drain_BMC2HOST(bt); - BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); - } + if (bt->state == BT_STATE_HOSED) + return SI_SM_HOSED; - if ((bt->state != BT_STATE_IDLE) && - (bt->state < BT_STATE_PRINTME)) { /* check timeout */ + if (bt->state != BT_STATE_IDLE) { /* do timeout test */ bt->timeout -= time; - if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) - return error_recovery(bt, - status, - IPMI_TIMEOUT_ERR); + if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) { + error_recovery(bt, "timed out"); + return SI_SM_CALL_WITHOUT_DELAY; + } } switch (bt->state) { - /* Idle state first checks for asynchronous messages from another - channel, then does some opportunistic housekeeping. */ - - case BT_STATE_IDLE: + case BT_STATE_IDLE: /* check for asynchronous messages */ if (status & BT_SMS_ATN) { BT_CONTROL(BT_SMS_ATN); /* clear it */ return SI_SM_ATTN; } - - if (status & BT_H_BUSY) /* clear a leftover H_BUSY */ - BT_CONTROL(BT_H_BUSY); - - /* Read BT capabilities if it hasn't been done yet */ - if (!bt->BT_CAP_outreqs) - BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN, - SI_SM_CALL_WITHOUT_DELAY); - bt->timeout = bt->BT_CAP_req2rsp; - BT_SI_SM_RETURN(SI_SM_IDLE); + return SI_SM_IDLE; case BT_STATE_XACTION_START: - if (status & (BT_B_BUSY | BT_H2B_ATN)) - BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); - if (BT_STATUS & BT_H_BUSY) - BT_CONTROL(BT_H_BUSY); /* force clear */ - BT_STATE_CHANGE(BT_STATE_WRITE_BYTES, - SI_SM_CALL_WITHOUT_DELAY); + if (status & BT_H_BUSY) { + BT_CONTROL(BT_H_BUSY); + break; + } + if (status & BT_B2H_ATN) + break; + bt->state = BT_STATE_WRITE_BYTES; + return SI_SM_CALL_WITHOUT_DELAY; /* for logging */ case BT_STATE_WRITE_BYTES: - if (status & BT_H_BUSY) - BT_CONTROL(BT_H_BUSY); /* clear */ + if (status & (BT_B_BUSY | BT_H2B_ATN)) + break; BT_CONTROL(BT_CLR_WR_PTR); write_all_bytes(bt); - BT_CONTROL(BT_H2B_ATN); /* can clear too fast to catch */ - BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME, - SI_SM_CALL_WITHOUT_DELAY); + BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */ + bt->state = BT_STATE_WRITE_CONSUME; + return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */ + + case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */ + if (status & (BT_H2B_ATN | BT_B_BUSY)) + break; + bt->state = BT_STATE_B2H_WAIT; + /* fall through with status */ + + /* Stay in BT_STATE_B2H_WAIT until a packet matches. However, spinning + hard here, constantly reading status, seems to hold off the + generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */ + + case BT_STATE_B2H_WAIT: + if (!(status & BT_B2H_ATN)) + break; + + /* Assume ordered, uncached writes: no need to wait */ + if (!(status & BT_H_BUSY)) + BT_CONTROL(BT_H_BUSY); /* set */ + BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */ + BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */ + i = read_all_bytes(bt); + BT_CONTROL(BT_H_BUSY); /* clear */ + if (!i) /* Try this state again */ + break; + bt->state = BT_STATE_READ_END; + return SI_SM_CALL_WITHOUT_DELAY; /* for logging */ + + case BT_STATE_READ_END: + + /* I could wait on BT_H_BUSY to go clear for a truly clean + exit. However, this is already done in XACTION_START + and the (possible) extra loop/status/possible wait affects + performance. So, as long as it works, just ignore H_BUSY */ + +#ifdef MAKE_THIS_TRUE_IF_NECESSARY - case BT_STATE_WRITE_CONSUME: - if (status & (BT_B_BUSY | BT_H2B_ATN)) - BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); - BT_STATE_CHANGE(BT_STATE_READ_WAIT, - SI_SM_CALL_WITHOUT_DELAY); - - /* Spinning hard can suppress B2H_ATN and force a timeout */ - - case BT_STATE_READ_WAIT: - if (!(status & BT_B2H_ATN)) - BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); - BT_CONTROL(BT_H_BUSY); /* set */ - - /* Uncached, ordered writes should just proceeed serially but - some BMCs don't clear B2H_ATN with one hit. Fast-path a - workaround without too much penalty to the general case. */ - - BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */ - BT_STATE_CHANGE(BT_STATE_CLEAR_B2H, - SI_SM_CALL_WITHOUT_DELAY); - - case BT_STATE_CLEAR_B2H: - if (status & BT_B2H_ATN) { /* keep hitting it */ - BT_CONTROL(BT_B2H_ATN); - BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); - } - BT_STATE_CHANGE(BT_STATE_READ_BYTES, - SI_SM_CALL_WITHOUT_DELAY); - - case BT_STATE_READ_BYTES: - if (!(status & BT_H_BUSY)) /* check in case of retry */ - BT_CONTROL(BT_H_BUSY); - BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */ - i = read_all_bytes(bt); /* true == packet seq match */ - BT_CONTROL(BT_H_BUSY); /* NOW clear */ - if (!i) /* Not my message */ - BT_STATE_CHANGE(BT_STATE_READ_WAIT, - SI_SM_CALL_WITHOUT_DELAY); - bt->state = bt->complete; - return bt->state == BT_STATE_IDLE ? /* where to next? */ - SI_SM_TRANSACTION_COMPLETE : /* normal */ - SI_SM_CALL_WITHOUT_DELAY; /* Startup magic */ - - case BT_STATE_LONG_BUSY: /* For example: after FW update */ - if (!(status & BT_B_BUSY)) { - reset_flags(bt); /* next state is now IDLE */ - bt_init_data(bt, bt->io); - } - return SI_SM_CALL_WITH_DELAY; /* No repeat printing */ + if (status & BT_H_BUSY) + break; +#endif + bt->seq++; + bt->state = BT_STATE_IDLE; + return SI_SM_TRANSACTION_COMPLETE; case BT_STATE_RESET1: - reset_flags(bt); - drain_BMC2HOST(bt); - BT_STATE_CHANGE(BT_STATE_RESET2, - SI_SM_CALL_WITH_DELAY); + reset_flags(bt); + bt->timeout = BT_RESET_DELAY; + bt->state = BT_STATE_RESET2; + break; case BT_STATE_RESET2: /* Send a soft reset */ BT_CONTROL(BT_CLR_WR_PTR); @@ -579,59 +464,29 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) HOST2BMC(42); /* Sequence number */ HOST2BMC(3); /* Cmd == Soft reset */ BT_CONTROL(BT_H2B_ATN); - bt->timeout = BT_RESET_DELAY * 1000000; - BT_STATE_CHANGE(BT_STATE_RESET3, - SI_SM_CALL_WITH_DELAY); + bt->state = BT_STATE_RESET3; + break; - case BT_STATE_RESET3: /* Hold off everything for a bit */ + case BT_STATE_RESET3: if (bt->timeout > 0) - return SI_SM_CALL_WITH_DELAY; - drain_BMC2HOST(bt); - BT_STATE_CHANGE(BT_STATE_RESTART, - SI_SM_CALL_WITH_DELAY); + return SI_SM_CALL_WITH_DELAY; + bt->state = BT_STATE_RESTART; /* printk in debug modes */ + break; - case BT_STATE_RESTART: /* don't reset retries or seq! */ + case BT_STATE_RESTART: /* don't reset retries! */ + reset_flags(bt); + bt->write_data[2] = ++bt->seq; bt->read_count = 0; bt->nonzero_status = 0; - bt->timeout = bt->BT_CAP_req2rsp; - BT_STATE_CHANGE(BT_STATE_XACTION_START, - SI_SM_CALL_WITH_DELAY); - - /* Get BT Capabilities, using timing of upper level state machine. - Set outreqs to prevent infinite loop on timeout. */ - case BT_STATE_CAPABILITIES_BEGIN: - bt->BT_CAP_outreqs = 1; - { - unsigned char GetBT_CAP[] = { 0x18, 0x36 }; - bt->state = BT_STATE_IDLE; - bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP)); - } - bt->complete = BT_STATE_CAPABILITIES_END; - BT_STATE_CHANGE(BT_STATE_XACTION_START, - SI_SM_CALL_WITH_DELAY); - - case BT_STATE_CAPABILITIES_END: - i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP)); - bt_init_data(bt, bt->io); - if ((i == 8) && !BT_CAP[2]) { - bt->BT_CAP_outreqs = BT_CAP[3]; - bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000; - bt->BT_CAP_retries = BT_CAP[7]; - } else - printk(KERN_WARNING "IPMI BT: using default values\n"); - if (!bt->BT_CAP_outreqs) - bt->BT_CAP_outreqs = 1; - printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n", - bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries); - bt->timeout = bt->BT_CAP_req2rsp; - return SI_SM_CALL_WITHOUT_DELAY; - - default: /* should never occur */ - return error_recovery(bt, - status, - IPMI_ERR_UNSPECIFIED); - } - return SI_SM_CALL_WITH_DELAY; + bt->timeout = BT_NORMAL_TIMEOUT; + bt->state = BT_STATE_XACTION_START; + break; + + default: /* HOSED is supposed to be caught much earlier */ + error_recovery(bt, "internal logic error"); + break; + } + return SI_SM_CALL_WITH_DELAY; } static int bt_detect(struct si_sm_data *bt) @@ -642,7 +497,7 @@ static int bt_detect(struct si_sm_data *bt) test that first. The calling routine uses negative logic. */ if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) - return 1; + return 1; reset_flags(bt); return 0; } @@ -658,11 +513,11 @@ static int bt_size(void) struct si_sm_handlers bt_smi_handlers = { - .init_data = bt_init_data, - .start_transaction = bt_start_transaction, - .get_result = bt_get_result, - .event = bt_event, - .detect = bt_detect, - .cleanup = bt_cleanup, - .size = bt_size, + .init_data = bt_init_data, + .start_transaction = bt_start_transaction, + .get_result = bt_get_result, + .event = bt_event, + .detect = bt_detect, + .cleanup = bt_cleanup, + .size = bt_size, }; diff --git a/trunk/drivers/char/ipmi/ipmi_devintf.c b/trunk/drivers/char/ipmi/ipmi_devintf.c index 375d3378eecd..81fcf0ce21d1 100644 --- a/trunk/drivers/char/ipmi/ipmi_devintf.c +++ b/trunk/drivers/char/ipmi/ipmi_devintf.c @@ -596,31 +596,6 @@ static int ipmi_ioctl(struct inode *inode, rv = 0; break; } - - case IPMICTL_GET_MAINTENANCE_MODE_CMD: - { - int mode; - - mode = ipmi_get_maintenance_mode(priv->user); - if (copy_to_user(arg, &mode, sizeof(mode))) { - rv = -EFAULT; - break; - } - rv = 0; - break; - } - - case IPMICTL_SET_MAINTENANCE_MODE_CMD: - { - int mode; - - if (copy_from_user(&mode, arg, sizeof(mode))) { - rv = -EFAULT; - break; - } - rv = ipmi_set_maintenance_mode(priv->user, mode); - break; - } } return rv; diff --git a/trunk/drivers/char/ipmi/ipmi_kcs_sm.c b/trunk/drivers/char/ipmi/ipmi_kcs_sm.c index c1b8228cb7b6..2062675f9e99 100644 --- a/trunk/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/trunk/drivers/char/ipmi/ipmi_kcs_sm.c @@ -93,8 +93,8 @@ enum kcs_states { state machine. */ }; -#define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH -#define MAX_KCS_WRITE_SIZE IPMI_MAX_MSG_LENGTH +#define MAX_KCS_READ_SIZE 80 +#define MAX_KCS_WRITE_SIZE 80 /* Timeouts in microseconds. */ #define IBF_RETRY_TIMEOUT 1000000 @@ -261,14 +261,12 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data, { unsigned int i; - if (size < 2) - return IPMI_REQ_LEN_INVALID_ERR; - if (size > MAX_KCS_WRITE_SIZE) - return IPMI_REQ_LEN_EXCEEDED_ERR; - - if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) - return IPMI_NOT_IN_MY_STATE_ERR; - + if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) { + return -1; + } + if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) { + return -2; + } if (kcs_debug & KCS_DEBUG_MSG) { printk(KERN_DEBUG "start_kcs_transaction -"); for (i = 0; i < size; i ++) { diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index 5703ee28e1cc..c47add8e47df 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -48,7 +48,7 @@ #define PFX "IPMI message handler: " -#define IPMI_DRIVER_VERSION "39.1" +#define IPMI_DRIVER_VERSION "39.0" static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); static int ipmi_init_msghandler(void); @@ -59,9 +59,6 @@ static int initialized = 0; static struct proc_dir_entry *proc_ipmi_root = NULL; #endif /* CONFIG_PROC_FS */ -/* Remain in auto-maintenance mode for this amount of time (in ms). */ -#define IPMI_MAINTENANCE_MODE_TIMEOUT 30000 - #define MAX_EVENTS_IN_QUEUE 25 /* Don't let a message sit in a queue forever, always time it with at lest @@ -196,28 +193,17 @@ struct ipmi_smi struct kref refcount; - /* Used for a list of interfaces. */ - struct list_head link; - /* The list of upper layers that are using me. seq_lock * protects this. */ struct list_head users; - /* Information to supply to users. */ - unsigned char ipmi_version_major; - unsigned char ipmi_version_minor; - /* Used for wake ups at startup. */ wait_queue_head_t waitq; struct bmc_device *bmc; char *my_dev_name; - char *sysfs_name; - /* This is the lower-layer's sender routine. Note that you - * must either be holding the ipmi_interfaces_mutex or be in - * an umpreemptible region to use this. You must fetch the - * value into a local variable and make sure it is not NULL. */ + /* This is the lower-layer's sender routine. */ struct ipmi_smi_handlers *handlers; void *send_info; @@ -256,7 +242,6 @@ struct ipmi_smi spinlock_t events_lock; /* For dealing with event stuff. */ struct list_head waiting_events; unsigned int waiting_events_count; /* How many events in queue? */ - int delivering_events; /* The event receiver for my BMC, only really used at panic shutdown as a place to store this. */ @@ -265,12 +250,6 @@ struct ipmi_smi unsigned char local_sel_device; unsigned char local_event_generator; - /* For handling of maintenance mode. */ - int maintenance_mode; - int maintenance_mode_enable; - int auto_maintenance_timeout; - spinlock_t maintenance_mode_lock; /* Used in a timer... */ - /* A cheap hack, if this is non-null and a message to an interface comes in with a NULL user, call this routine with it. Note that the message will still be freed by the @@ -359,6 +338,13 @@ struct ipmi_smi }; #define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev) +/* Used to mark an interface entry that cannot be used but is not a + * free entry, either, primarily used at creation and deletion time so + * a slot doesn't get reused too quickly. */ +#define IPMI_INVALID_INTERFACE_ENTRY ((ipmi_smi_t) ((long) 1)) +#define IPMI_INVALID_INTERFACE(i) (((i) == NULL) \ + || (i == IPMI_INVALID_INTERFACE_ENTRY)) + /** * The driver model view of the IPMI messaging driver. */ @@ -368,13 +354,16 @@ static struct device_driver ipmidriver = { }; static DEFINE_MUTEX(ipmidriver_mutex); -static struct list_head ipmi_interfaces = LIST_HEAD_INIT(ipmi_interfaces); -static DEFINE_MUTEX(ipmi_interfaces_mutex); +#define MAX_IPMI_INTERFACES 4 +static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES]; + +/* Directly protects the ipmi_interfaces data structure. */ +static DEFINE_SPINLOCK(interfaces_lock); /* List of watchers that want to know when smi's are added and deleted. */ static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers); -static DEFINE_MUTEX(smi_watchers_mutex); +static DECLARE_RWSEM(smi_watchers_sem); static void free_recv_msg_list(struct list_head *q) @@ -434,84 +423,48 @@ static void intf_free(struct kref *ref) kfree(intf); } -struct watcher_entry { - int intf_num; - ipmi_smi_t intf; - struct list_head link; -}; - int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) { - ipmi_smi_t intf; - struct list_head to_deliver = LIST_HEAD_INIT(to_deliver); - struct watcher_entry *e, *e2; - - mutex_lock(&smi_watchers_mutex); - - mutex_lock(&ipmi_interfaces_mutex); + int i; + unsigned long flags; - /* Build a list of things to deliver. */ - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - if (intf->intf_num == -1) + down_write(&smi_watchers_sem); + list_add(&(watcher->link), &smi_watchers); + up_write(&smi_watchers_sem); + spin_lock_irqsave(&interfaces_lock, flags); + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { + ipmi_smi_t intf = ipmi_interfaces[i]; + if (IPMI_INVALID_INTERFACE(intf)) continue; - e = kmalloc(sizeof(*e), GFP_KERNEL); - if (!e) - goto out_err; - kref_get(&intf->refcount); - e->intf = intf; - e->intf_num = intf->intf_num; - list_add_tail(&e->link, &to_deliver); + spin_unlock_irqrestore(&interfaces_lock, flags); + watcher->new_smi(i, intf->si_dev); + spin_lock_irqsave(&interfaces_lock, flags); } - - /* We will succeed, so add it to the list. */ - list_add(&watcher->link, &smi_watchers); - - mutex_unlock(&ipmi_interfaces_mutex); - - list_for_each_entry_safe(e, e2, &to_deliver, link) { - list_del(&e->link); - watcher->new_smi(e->intf_num, e->intf->si_dev); - kref_put(&e->intf->refcount, intf_free); - kfree(e); - } - - mutex_unlock(&smi_watchers_mutex); - + spin_unlock_irqrestore(&interfaces_lock, flags); return 0; - - out_err: - mutex_unlock(&ipmi_interfaces_mutex); - mutex_unlock(&smi_watchers_mutex); - list_for_each_entry_safe(e, e2, &to_deliver, link) { - list_del(&e->link); - kref_put(&e->intf->refcount, intf_free); - kfree(e); - } - return -ENOMEM; } int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher) { - mutex_lock(&smi_watchers_mutex); + down_write(&smi_watchers_sem); list_del(&(watcher->link)); - mutex_unlock(&smi_watchers_mutex); + up_write(&smi_watchers_sem); return 0; } -/* - * Must be called with smi_watchers_mutex held. - */ static void call_smi_watchers(int i, struct device *dev) { struct ipmi_smi_watcher *w; + down_read(&smi_watchers_sem); list_for_each_entry(w, &smi_watchers, link) { if (try_module_get(w->owner)) { w->new_smi(i, dev); module_put(w->owner); } } + up_read(&smi_watchers_sem); } static int @@ -637,17 +590,6 @@ static void deliver_response(struct ipmi_recv_msg *msg) } } -static void -deliver_err_response(struct ipmi_recv_msg *msg, int err) -{ - msg->recv_type = IPMI_RESPONSE_RECV_TYPE; - msg->msg_data[0] = err; - msg->msg.netfn |= 1; /* Convert to a response. */ - msg->msg.data_len = 1; - msg->msg.data = msg->msg_data; - deliver_response(msg); -} - /* Find the next sequence number not being used and add the given message with the given timeout to the sequence table. This must be called with the interface's seq_lock held. */ @@ -785,8 +727,14 @@ static int intf_err_seq(ipmi_smi_t intf, } spin_unlock_irqrestore(&(intf->seq_lock), flags); - if (msg) - deliver_err_response(msg, err); + if (msg) { + msg->recv_type = IPMI_RESPONSE_RECV_TYPE; + msg->msg_data[0] = err; + msg->msg.netfn |= 1; /* Convert to a response. */ + msg->msg.data_len = 1; + msg->msg.data = msg->msg_data; + deliver_response(msg); + } return rv; } @@ -828,18 +776,17 @@ int ipmi_create_user(unsigned int if_num, if (!new_user) return -ENOMEM; - mutex_lock(&ipmi_interfaces_mutex); - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - if (intf->intf_num == if_num) - goto found; + spin_lock_irqsave(&interfaces_lock, flags); + intf = ipmi_interfaces[if_num]; + if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) { + spin_unlock_irqrestore(&interfaces_lock, flags); + rv = -EINVAL; + goto out_kfree; } - /* Not found, return an error */ - rv = -EINVAL; - goto out_kfree; - found: /* Note that each existing user holds a refcount to the interface. */ kref_get(&intf->refcount); + spin_unlock_irqrestore(&interfaces_lock, flags); kref_init(&new_user->refcount); new_user->handler = handler; @@ -860,10 +807,6 @@ int ipmi_create_user(unsigned int if_num, } } - /* Hold the lock so intf->handlers is guaranteed to be good - * until now */ - mutex_unlock(&ipmi_interfaces_mutex); - new_user->valid = 1; spin_lock_irqsave(&intf->seq_lock, flags); list_add_rcu(&new_user->link, &intf->users); @@ -874,7 +817,6 @@ int ipmi_create_user(unsigned int if_num, out_kref: kref_put(&intf->refcount, intf_free); out_kfree: - mutex_unlock(&ipmi_interfaces_mutex); kfree(new_user); return rv; } @@ -904,7 +846,6 @@ int ipmi_destroy_user(ipmi_user_t user) && (intf->seq_table[i].recv_msg->user == user)) { intf->seq_table[i].inuse = 0; - ipmi_free_recv_msg(intf->seq_table[i].recv_msg); } } spin_unlock_irqrestore(&intf->seq_lock, flags); @@ -931,13 +872,9 @@ int ipmi_destroy_user(ipmi_user_t user) kfree(rcvr); } - mutex_lock(&ipmi_interfaces_mutex); - if (intf->handlers) { - module_put(intf->handlers->owner); - if (intf->handlers->dec_usecount) - intf->handlers->dec_usecount(intf->send_info); - } - mutex_unlock(&ipmi_interfaces_mutex); + module_put(intf->handlers->owner); + if (intf->handlers->dec_usecount) + intf->handlers->dec_usecount(intf->send_info); kref_put(&intf->refcount, intf_free); @@ -950,8 +887,8 @@ void ipmi_get_version(ipmi_user_t user, unsigned char *major, unsigned char *minor) { - *major = user->intf->ipmi_version_major; - *minor = user->intf->ipmi_version_minor; + *major = ipmi_version_major(&user->intf->bmc->id); + *minor = ipmi_version_minor(&user->intf->bmc->id); } int ipmi_set_my_address(ipmi_user_t user, @@ -994,65 +931,6 @@ int ipmi_get_my_LUN(ipmi_user_t user, return 0; } -int ipmi_get_maintenance_mode(ipmi_user_t user) -{ - int mode; - unsigned long flags; - - spin_lock_irqsave(&user->intf->maintenance_mode_lock, flags); - mode = user->intf->maintenance_mode; - spin_unlock_irqrestore(&user->intf->maintenance_mode_lock, flags); - - return mode; -} -EXPORT_SYMBOL(ipmi_get_maintenance_mode); - -static void maintenance_mode_update(ipmi_smi_t intf) -{ - if (intf->handlers->set_maintenance_mode) - intf->handlers->set_maintenance_mode( - intf->send_info, intf->maintenance_mode_enable); -} - -int ipmi_set_maintenance_mode(ipmi_user_t user, int mode) -{ - int rv = 0; - unsigned long flags; - ipmi_smi_t intf = user->intf; - - spin_lock_irqsave(&intf->maintenance_mode_lock, flags); - if (intf->maintenance_mode != mode) { - switch (mode) { - case IPMI_MAINTENANCE_MODE_AUTO: - intf->maintenance_mode = mode; - intf->maintenance_mode_enable - = (intf->auto_maintenance_timeout > 0); - break; - - case IPMI_MAINTENANCE_MODE_OFF: - intf->maintenance_mode = mode; - intf->maintenance_mode_enable = 0; - break; - - case IPMI_MAINTENANCE_MODE_ON: - intf->maintenance_mode = mode; - intf->maintenance_mode_enable = 1; - break; - - default: - rv = -EINVAL; - goto out_unlock; - } - - maintenance_mode_update(intf); - } - out_unlock: - spin_unlock_irqrestore(&intf->maintenance_mode_lock, flags); - - return rv; -} -EXPORT_SYMBOL(ipmi_set_maintenance_mode); - int ipmi_set_gets_events(ipmi_user_t user, int val) { unsigned long flags; @@ -1065,33 +943,20 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) spin_lock_irqsave(&intf->events_lock, flags); user->gets_events = val; - if (intf->delivering_events) - /* - * Another thread is delivering events for this, so - * let it handle any new events. - */ - goto out; - - /* Deliver any queued events. */ - while (user->gets_events && !list_empty(&intf->waiting_events)) { + if (val) { + /* Deliver any queued events. */ list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) list_move_tail(&msg->link, &msgs); intf->waiting_events_count = 0; + } - intf->delivering_events = 1; - spin_unlock_irqrestore(&intf->events_lock, flags); - - list_for_each_entry_safe(msg, msg2, &msgs, link) { - msg->user = user; - kref_get(&user->refcount); - deliver_response(msg); - } - - spin_lock_irqsave(&intf->events_lock, flags); - intf->delivering_events = 0; + /* Hold the events lock while doing this to preserve order. */ + list_for_each_entry_safe(msg, msg2, &msgs, link) { + msg->user = user; + kref_get(&user->refcount); + deliver_response(msg); } - out: spin_unlock_irqrestore(&intf->events_lock, flags); return 0; @@ -1202,8 +1067,7 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, void ipmi_user_set_run_to_completion(ipmi_user_t user, int val) { ipmi_smi_t intf = user->intf; - if (intf->handlers) - intf->handlers->set_run_to_completion(intf->send_info, val); + intf->handlers->set_run_to_completion(intf->send_info, val); } static unsigned char @@ -1314,11 +1178,10 @@ static int i_ipmi_request(ipmi_user_t user, int retries, unsigned int retry_time_ms) { - int rv = 0; - struct ipmi_smi_msg *smi_msg; - struct ipmi_recv_msg *recv_msg; - unsigned long flags; - struct ipmi_smi_handlers *handlers; + int rv = 0; + struct ipmi_smi_msg *smi_msg; + struct ipmi_recv_msg *recv_msg; + unsigned long flags; if (supplied_recv) { @@ -1341,13 +1204,6 @@ static int i_ipmi_request(ipmi_user_t user, } } - rcu_read_lock(); - handlers = intf->handlers; - if (!handlers) { - rv = -ENODEV; - goto out_err; - } - recv_msg->user = user; if (user) kref_get(&user->refcount); @@ -1390,24 +1246,6 @@ static int i_ipmi_request(ipmi_user_t user, goto out_err; } - if (((msg->netfn == IPMI_NETFN_APP_REQUEST) - && ((msg->cmd == IPMI_COLD_RESET_CMD) - || (msg->cmd == IPMI_WARM_RESET_CMD))) - || (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST)) - { - spin_lock_irqsave(&intf->maintenance_mode_lock, flags); - intf->auto_maintenance_timeout - = IPMI_MAINTENANCE_MODE_TIMEOUT; - if (!intf->maintenance_mode - && !intf->maintenance_mode_enable) - { - intf->maintenance_mode_enable = 1; - maintenance_mode_update(intf); - } - spin_unlock_irqrestore(&intf->maintenance_mode_lock, - flags); - } - if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) { spin_lock_irqsave(&intf->counter_lock, flags); intf->sent_invalid_commands++; @@ -1682,14 +1520,11 @@ static int i_ipmi_request(ipmi_user_t user, printk("\n"); } #endif - - handlers->sender(intf->send_info, smi_msg, priority); - rcu_read_unlock(); + intf->handlers->sender(intf->send_info, smi_msg, priority); return 0; out_err: - rcu_read_unlock(); ipmi_free_smi_msg(smi_msg); ipmi_free_recv_msg(recv_msg); return rv; @@ -1769,7 +1604,6 @@ int ipmi_request_supply_msgs(ipmi_user_t user, -1, 0); } -#ifdef CONFIG_PROC_FS static int ipmb_file_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -1858,7 +1692,6 @@ static int stat_file_read_proc(char *page, char **start, off_t off, return (out - ((char *) page)); } -#endif /* CONFIG_PROC_FS */ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, read_proc_t *read_proc, write_proc_t *write_proc, @@ -1984,12 +1817,13 @@ static int __find_bmc_prod_dev_id(struct device *dev, void *data) struct bmc_device *bmc = dev_get_drvdata(dev); return (bmc->id.product_id == id->product_id + && bmc->id.product_id == id->product_id && bmc->id.device_id == id->device_id); } static struct bmc_device *ipmi_find_bmc_prod_dev_id( struct device_driver *drv, - unsigned int product_id, unsigned char device_id) + unsigned char product_id, unsigned char device_id) { struct prod_dev_id id = { .product_id = product_id, @@ -2106,9 +1940,6 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, static void remove_files(struct bmc_device *bmc) { - if (!bmc->dev) - return; - device_remove_file(&bmc->dev->dev, &bmc->device_id_attr); device_remove_file(&bmc->dev->dev, @@ -2142,8 +1973,7 @@ cleanup_bmc_device(struct kref *ref) bmc = container_of(ref, struct bmc_device, refcount); remove_files(bmc); - if (bmc->dev) - platform_device_unregister(bmc->dev); + platform_device_unregister(bmc->dev); kfree(bmc); } @@ -2151,11 +1981,7 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) { struct bmc_device *bmc = intf->bmc; - if (intf->sysfs_name) { - sysfs_remove_link(&intf->si_dev->kobj, intf->sysfs_name); - kfree(intf->sysfs_name); - intf->sysfs_name = NULL; - } + sysfs_remove_link(&intf->si_dev->kobj, "bmc"); if (intf->my_dev_name) { sysfs_remove_link(&bmc->dev->dev.kobj, intf->my_dev_name); kfree(intf->my_dev_name); @@ -2164,7 +1990,6 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) mutex_lock(&ipmidriver_mutex); kref_put(&bmc->refcount, cleanup_bmc_device); - intf->bmc = NULL; mutex_unlock(&ipmidriver_mutex); } @@ -2172,56 +1997,6 @@ static int create_files(struct bmc_device *bmc) { int err; - bmc->device_id_attr.attr.name = "device_id"; - bmc->device_id_attr.attr.owner = THIS_MODULE; - bmc->device_id_attr.attr.mode = S_IRUGO; - bmc->device_id_attr.show = device_id_show; - - bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; - bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE; - bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; - bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; - - bmc->revision_attr.attr.name = "revision"; - bmc->revision_attr.attr.owner = THIS_MODULE; - bmc->revision_attr.attr.mode = S_IRUGO; - bmc->revision_attr.show = revision_show; - - bmc->firmware_rev_attr.attr.name = "firmware_revision"; - bmc->firmware_rev_attr.attr.owner = THIS_MODULE; - bmc->firmware_rev_attr.attr.mode = S_IRUGO; - bmc->firmware_rev_attr.show = firmware_rev_show; - - bmc->version_attr.attr.name = "ipmi_version"; - bmc->version_attr.attr.owner = THIS_MODULE; - bmc->version_attr.attr.mode = S_IRUGO; - bmc->version_attr.show = ipmi_version_show; - - bmc->add_dev_support_attr.attr.name = "additional_device_support"; - bmc->add_dev_support_attr.attr.owner = THIS_MODULE; - bmc->add_dev_support_attr.attr.mode = S_IRUGO; - bmc->add_dev_support_attr.show = add_dev_support_show; - - bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; - bmc->manufacturer_id_attr.attr.owner = THIS_MODULE; - bmc->manufacturer_id_attr.attr.mode = S_IRUGO; - bmc->manufacturer_id_attr.show = manufacturer_id_show; - - bmc->product_id_attr.attr.name = "product_id"; - bmc->product_id_attr.attr.owner = THIS_MODULE; - bmc->product_id_attr.attr.mode = S_IRUGO; - bmc->product_id_attr.show = product_id_show; - - bmc->guid_attr.attr.name = "guid"; - bmc->guid_attr.attr.owner = THIS_MODULE; - bmc->guid_attr.attr.mode = S_IRUGO; - bmc->guid_attr.show = guid_show; - - bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; - bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE; - bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; - bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; - err = device_create_file(&bmc->dev->dev, &bmc->device_id_attr); if (err) goto out; @@ -2291,8 +2066,7 @@ static int create_files(struct bmc_device *bmc) return err; } -static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, - const char *sysfs_name) +static int ipmi_bmc_register(ipmi_smi_t intf) { int rv; struct bmc_device *bmc = intf->bmc; @@ -2332,39 +2106,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, bmc->id.product_id, bmc->id.device_id); } else { - char name[14]; - unsigned char orig_dev_id = bmc->id.device_id; - int warn_printed = 0; - - snprintf(name, sizeof(name), - "ipmi_bmc.%4.4x", bmc->id.product_id); - - while (ipmi_find_bmc_prod_dev_id(&ipmidriver, - bmc->id.product_id, - bmc->id.device_id)) - { - if (!warn_printed) { - printk(KERN_WARNING PFX - "This machine has two different BMCs" - " with the same product id and device" - " id. This is an error in the" - " firmware, but incrementing the" - " device id to work around the problem." - " Prod ID = 0x%x, Dev ID = 0x%x\n", - bmc->id.product_id, bmc->id.device_id); - warn_printed = 1; - } - bmc->id.device_id++; /* Wraps at 255 */ - if (bmc->id.device_id == orig_dev_id) { - printk(KERN_ERR PFX - "Out of device ids!\n"); - break; - } - } - - bmc->dev = platform_device_alloc(name, bmc->id.device_id); + bmc->dev = platform_device_alloc("ipmi_bmc", + bmc->id.device_id); if (!bmc->dev) { - mutex_unlock(&ipmidriver_mutex); printk(KERN_ERR "ipmi_msghandler:" " Unable to allocate platform device\n"); @@ -2377,8 +2121,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, rv = platform_device_add(bmc->dev); mutex_unlock(&ipmidriver_mutex); if (rv) { - platform_device_put(bmc->dev); - bmc->dev = NULL; printk(KERN_ERR "ipmi_msghandler:" " Unable to register bmc device: %d\n", @@ -2388,6 +2130,57 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, return rv; } + bmc->device_id_attr.attr.name = "device_id"; + bmc->device_id_attr.attr.owner = THIS_MODULE; + bmc->device_id_attr.attr.mode = S_IRUGO; + bmc->device_id_attr.show = device_id_show; + + bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; + bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE; + bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; + bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; + + bmc->revision_attr.attr.name = "revision"; + bmc->revision_attr.attr.owner = THIS_MODULE; + bmc->revision_attr.attr.mode = S_IRUGO; + bmc->revision_attr.show = revision_show; + + bmc->firmware_rev_attr.attr.name = "firmware_revision"; + bmc->firmware_rev_attr.attr.owner = THIS_MODULE; + bmc->firmware_rev_attr.attr.mode = S_IRUGO; + bmc->firmware_rev_attr.show = firmware_rev_show; + + bmc->version_attr.attr.name = "ipmi_version"; + bmc->version_attr.attr.owner = THIS_MODULE; + bmc->version_attr.attr.mode = S_IRUGO; + bmc->version_attr.show = ipmi_version_show; + + bmc->add_dev_support_attr.attr.name + = "additional_device_support"; + bmc->add_dev_support_attr.attr.owner = THIS_MODULE; + bmc->add_dev_support_attr.attr.mode = S_IRUGO; + bmc->add_dev_support_attr.show = add_dev_support_show; + + bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; + bmc->manufacturer_id_attr.attr.owner = THIS_MODULE; + bmc->manufacturer_id_attr.attr.mode = S_IRUGO; + bmc->manufacturer_id_attr.show = manufacturer_id_show; + + bmc->product_id_attr.attr.name = "product_id"; + bmc->product_id_attr.attr.owner = THIS_MODULE; + bmc->product_id_attr.attr.mode = S_IRUGO; + bmc->product_id_attr.show = product_id_show; + + bmc->guid_attr.attr.name = "guid"; + bmc->guid_attr.attr.owner = THIS_MODULE; + bmc->guid_attr.attr.mode = S_IRUGO; + bmc->guid_attr.show = guid_show; + + bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; + bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE; + bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; + bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; + rv = create_files(bmc); if (rv) { mutex_lock(&ipmidriver_mutex); @@ -2409,44 +2202,29 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, * create symlink from system interface device to bmc device * and back. */ - intf->sysfs_name = kstrdup(sysfs_name, GFP_KERNEL); - if (!intf->sysfs_name) { - rv = -ENOMEM; - printk(KERN_ERR - "ipmi_msghandler: allocate link to BMC: %d\n", - rv); - goto out_err; - } - rv = sysfs_create_link(&intf->si_dev->kobj, - &bmc->dev->dev.kobj, intf->sysfs_name); + &bmc->dev->dev.kobj, "bmc"); if (rv) { - kfree(intf->sysfs_name); - intf->sysfs_name = NULL; printk(KERN_ERR "ipmi_msghandler: Unable to create bmc symlink: %d\n", rv); goto out_err; } - size = snprintf(dummy, 0, "ipmi%d", ifnum); + size = snprintf(dummy, 0, "ipmi%d", intf->intf_num); intf->my_dev_name = kmalloc(size+1, GFP_KERNEL); if (!intf->my_dev_name) { - kfree(intf->sysfs_name); - intf->sysfs_name = NULL; rv = -ENOMEM; printk(KERN_ERR "ipmi_msghandler: allocate link from BMC: %d\n", rv); goto out_err; } - snprintf(intf->my_dev_name, size+1, "ipmi%d", ifnum); + snprintf(intf->my_dev_name, size+1, "ipmi%d", intf->intf_num); rv = sysfs_create_link(&bmc->dev->dev.kobj, &intf->si_dev->kobj, intf->my_dev_name); if (rv) { - kfree(intf->sysfs_name); - intf->sysfs_name = NULL; kfree(intf->my_dev_name); intf->my_dev_name = NULL; printk(KERN_ERR @@ -2631,14 +2409,17 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, void *send_info, struct ipmi_device_id *device_id, struct device *si_dev, - const char *sysfs_name, unsigned char slave_addr) { int i, j; int rv; ipmi_smi_t intf; - ipmi_smi_t tintf; - struct list_head *link; + unsigned long flags; + int version_major; + int version_minor; + + version_major = ipmi_version_major(device_id); + version_minor = ipmi_version_minor(device_id); /* Make sure the driver is actually initialized, this handles problems with initialization order. */ @@ -2656,16 +2437,12 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, if (!intf) return -ENOMEM; memset(intf, 0, sizeof(*intf)); - - intf->ipmi_version_major = ipmi_version_major(device_id); - intf->ipmi_version_minor = ipmi_version_minor(device_id); - intf->bmc = kzalloc(sizeof(*intf->bmc), GFP_KERNEL); if (!intf->bmc) { kfree(intf); return -ENOMEM; } - intf->intf_num = -1; /* Mark it invalid for now. */ + intf->intf_num = -1; kref_init(&intf->refcount); intf->bmc->id = *device_id; intf->si_dev = si_dev; @@ -2693,30 +2470,26 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, INIT_LIST_HEAD(&intf->waiting_events); intf->waiting_events_count = 0; mutex_init(&intf->cmd_rcvrs_mutex); - spin_lock_init(&intf->maintenance_mode_lock); INIT_LIST_HEAD(&intf->cmd_rcvrs); init_waitqueue_head(&intf->waitq); spin_lock_init(&intf->counter_lock); intf->proc_dir = NULL; - mutex_lock(&smi_watchers_mutex); - mutex_lock(&ipmi_interfaces_mutex); - /* Look for a hole in the numbers. */ - i = 0; - link = &ipmi_interfaces; - list_for_each_entry_rcu(tintf, &ipmi_interfaces, link) { - if (tintf->intf_num != i) { - link = &tintf->link; + rv = -ENOMEM; + spin_lock_irqsave(&interfaces_lock, flags); + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { + if (ipmi_interfaces[i] == NULL) { + intf->intf_num = i; + /* Reserve the entry till we are done. */ + ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY; + rv = 0; break; } - i++; } - /* Add the new interface in numeric order. */ - if (i == 0) - list_add_rcu(&intf->link, &ipmi_interfaces); - else - list_add_tail_rcu(&intf->link, link); + spin_unlock_irqrestore(&interfaces_lock, flags); + if (rv) + goto out; rv = handlers->start_processing(send_info, intf); if (rv) @@ -2724,9 +2497,8 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, get_guid(intf); - if ((intf->ipmi_version_major > 1) - || ((intf->ipmi_version_major == 1) - && (intf->ipmi_version_minor >= 5))) + if ((version_major > 1) + || ((version_major == 1) && (version_minor >= 5))) { /* Start scanning the channels to see what is available. */ @@ -2749,67 +2521,64 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, if (rv == 0) rv = add_proc_entries(intf, i); - rv = ipmi_bmc_register(intf, i, sysfs_name); + rv = ipmi_bmc_register(intf); out: if (rv) { if (intf->proc_dir) remove_proc_entries(intf); - intf->handlers = NULL; - list_del_rcu(&intf->link); - mutex_unlock(&ipmi_interfaces_mutex); - mutex_unlock(&smi_watchers_mutex); - synchronize_rcu(); kref_put(&intf->refcount, intf_free); + if (i < MAX_IPMI_INTERFACES) { + spin_lock_irqsave(&interfaces_lock, flags); + ipmi_interfaces[i] = NULL; + spin_unlock_irqrestore(&interfaces_lock, flags); + } } else { - /* After this point the interface is legal to use. */ - intf->intf_num = i; - mutex_unlock(&ipmi_interfaces_mutex); + spin_lock_irqsave(&interfaces_lock, flags); + ipmi_interfaces[i] = intf; + spin_unlock_irqrestore(&interfaces_lock, flags); call_smi_watchers(i, intf->si_dev); - mutex_unlock(&smi_watchers_mutex); } return rv; } -static void cleanup_smi_msgs(ipmi_smi_t intf) -{ - int i; - struct seq_table *ent; - - /* No need for locks, the interface is down. */ - for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) { - ent = &(intf->seq_table[i]); - if (!ent->inuse) - continue; - deliver_err_response(ent->recv_msg, IPMI_ERR_UNSPECIFIED); - } -} - int ipmi_unregister_smi(ipmi_smi_t intf) { + int i; struct ipmi_smi_watcher *w; - int intf_num = intf->intf_num; + unsigned long flags; ipmi_bmc_unregister(intf); - mutex_lock(&smi_watchers_mutex); - mutex_lock(&ipmi_interfaces_mutex); - intf->intf_num = -1; - intf->handlers = NULL; - list_del_rcu(&intf->link); - mutex_unlock(&ipmi_interfaces_mutex); - synchronize_rcu(); + spin_lock_irqsave(&interfaces_lock, flags); + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { + if (ipmi_interfaces[i] == intf) { + /* Set the interface number reserved until we + * are done. */ + ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY; + intf->intf_num = -1; + break; + } + } + spin_unlock_irqrestore(&interfaces_lock,flags); - cleanup_smi_msgs(intf); + if (i == MAX_IPMI_INTERFACES) + return -ENODEV; remove_proc_entries(intf); /* Call all the watcher interfaces to tell them that an interface is gone. */ + down_read(&smi_watchers_sem); list_for_each_entry(w, &smi_watchers, link) - w->smi_gone(intf_num); - mutex_unlock(&smi_watchers_mutex); + w->smi_gone(i); + up_read(&smi_watchers_sem); + + /* Allow the entry to be reused now. */ + spin_lock_irqsave(&interfaces_lock, flags); + ipmi_interfaces[i] = NULL; + spin_unlock_irqrestore(&interfaces_lock,flags); kref_put(&intf->refcount, intf_free); return 0; @@ -2891,7 +2660,6 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, struct ipmi_ipmb_addr *ipmb_addr; struct ipmi_recv_msg *recv_msg; unsigned long flags; - struct ipmi_smi_handlers *handlers; if (msg->rsp_size < 10) { /* Message not big enough, just ignore it. */ @@ -2948,16 +2716,10 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, printk("\n"); } #endif - rcu_read_lock(); - handlers = intf->handlers; - if (handlers) { - handlers->sender(intf->send_info, msg, 0); - /* We used the message, so return the value - that causes it to not be freed or - queued. */ - rv = -1; - } - rcu_read_unlock(); + intf->handlers->sender(intf->send_info, msg, 0); + + rv = -1; /* We used the message, so return the value that + causes it to not be freed or queued. */ } else { /* Deliver the message to the user. */ spin_lock_irqsave(&intf->counter_lock, flags); @@ -3547,6 +3309,16 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) rcu_read_unlock(); } +static void +handle_msg_timeout(struct ipmi_recv_msg *msg) +{ + msg->recv_type = IPMI_RESPONSE_RECV_TYPE; + msg->msg_data[0] = IPMI_TIMEOUT_COMPLETION_CODE; + msg->msg.netfn |= 1; /* Convert to a response. */ + msg->msg.data_len = 1; + msg->msg.data = msg->msg_data; + deliver_response(msg); +} static struct ipmi_smi_msg * smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, @@ -3578,11 +3350,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, struct list_head *timeouts, long timeout_period, int slot, unsigned long *flags) { - struct ipmi_recv_msg *msg; - struct ipmi_smi_handlers *handlers; - - if (intf->intf_num == -1) - return; + struct ipmi_recv_msg *msg; if (!ent->inuse) return; @@ -3625,19 +3393,13 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, return; spin_unlock_irqrestore(&intf->seq_lock, *flags); - /* Send the new message. We send with a zero * priority. It timed out, I doubt time is * that critical now, and high priority * messages are really only for messages to the * local MC, which don't get resent. */ - handlers = intf->handlers; - if (handlers) - intf->handlers->sender(intf->send_info, - smi_msg, 0); - else - ipmi_free_smi_msg(smi_msg); - + intf->handlers->sender(intf->send_info, + smi_msg, 0); spin_lock_irqsave(&intf->seq_lock, *flags); } } @@ -3649,12 +3411,18 @@ static void ipmi_timeout_handler(long timeout_period) struct ipmi_recv_msg *msg, *msg2; struct ipmi_smi_msg *smi_msg, *smi_msg2; unsigned long flags; - int i; + int i, j; INIT_LIST_HEAD(&timeouts); - rcu_read_lock(); - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { + spin_lock(&interfaces_lock); + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { + intf = ipmi_interfaces[i]; + if (IPMI_INVALID_INTERFACE(intf)) + continue; + kref_get(&intf->refcount); + spin_unlock(&interfaces_lock); + /* See if any waiting messages need to be processed. */ spin_lock_irqsave(&intf->waiting_msgs_lock, flags); list_for_each_entry_safe(smi_msg, smi_msg2, @@ -3674,60 +3442,35 @@ static void ipmi_timeout_handler(long timeout_period) have timed out, putting them in the timeouts list. */ spin_lock_irqsave(&intf->seq_lock, flags); - for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) - check_msg_timeout(intf, &(intf->seq_table[i]), - &timeouts, timeout_period, i, + for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) + check_msg_timeout(intf, &(intf->seq_table[j]), + &timeouts, timeout_period, j, &flags); spin_unlock_irqrestore(&intf->seq_lock, flags); list_for_each_entry_safe(msg, msg2, &timeouts, link) - deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE); - - /* - * Maintenance mode handling. Check the timeout - * optimistically before we claim the lock. It may - * mean a timeout gets missed occasionally, but that - * only means the timeout gets extended by one period - * in that case. No big deal, and it avoids the lock - * most of the time. - */ - if (intf->auto_maintenance_timeout > 0) { - spin_lock_irqsave(&intf->maintenance_mode_lock, flags); - if (intf->auto_maintenance_timeout > 0) { - intf->auto_maintenance_timeout - -= timeout_period; - if (!intf->maintenance_mode - && (intf->auto_maintenance_timeout <= 0)) - { - intf->maintenance_mode_enable = 0; - maintenance_mode_update(intf); - } - } - spin_unlock_irqrestore(&intf->maintenance_mode_lock, - flags); - } + handle_msg_timeout(msg); + + kref_put(&intf->refcount, intf_free); + spin_lock(&interfaces_lock); } - rcu_read_unlock(); + spin_unlock(&interfaces_lock); } static void ipmi_request_event(void) { - ipmi_smi_t intf; - struct ipmi_smi_handlers *handlers; + ipmi_smi_t intf; + int i; - rcu_read_lock(); - /* Called from the timer, no need to check if handlers is - * valid. */ - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - /* No event requests when in maintenance mode. */ - if (intf->maintenance_mode_enable) + spin_lock(&interfaces_lock); + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { + intf = ipmi_interfaces[i]; + if (IPMI_INVALID_INTERFACE(intf)) continue; - handlers = intf->handlers; - if (handlers) - handlers->request_events(intf->send_info); + intf->handlers->request_events(intf->send_info); } - rcu_read_unlock(); + spin_unlock(&interfaces_lock); } static struct timer_list ipmi_timer; @@ -3856,6 +3599,7 @@ static void send_panic_events(char *str) struct kernel_ipmi_msg msg; ipmi_smi_t intf; unsigned char data[16]; + int i; struct ipmi_system_interface_addr *si; struct ipmi_addr addr; struct ipmi_smi_msg smi_msg; @@ -3889,9 +3633,9 @@ static void send_panic_events(char *str) recv_msg.done = dummy_recv_done_handler; /* For every registered interface, send the event. */ - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - if (!intf->handlers) - /* Interface is not ready. */ + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { + intf = ipmi_interfaces[i]; + if (IPMI_INVALID_INTERFACE(intf)) continue; /* Send the event announcing the panic. */ @@ -3916,14 +3660,13 @@ static void send_panic_events(char *str) if (!str) return; - /* For every registered interface, send the event. */ - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { char *p = str; struct ipmi_ipmb_addr *ipmb; int j; - if (intf->intf_num == -1) - /* Interface was not ready yet. */ + intf = ipmi_interfaces[i]; + if (IPMI_INVALID_INTERFACE(intf)) continue; /* First job here is to figure out where to send the @@ -4049,6 +3792,7 @@ static int panic_event(struct notifier_block *this, unsigned long event, void *ptr) { + int i; ipmi_smi_t intf; if (has_panicked) @@ -4056,9 +3800,9 @@ static int panic_event(struct notifier_block *this, has_panicked = 1; /* For every registered interface, set it to run to completion. */ - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - if (!intf->handlers) - /* Interface is not ready. */ + for (i = 0; i < MAX_IPMI_INTERFACES; i++) { + intf = ipmi_interfaces[i]; + if (IPMI_INVALID_INTERFACE(intf)) continue; intf->handlers->set_run_to_completion(intf->send_info, 1); @@ -4079,6 +3823,7 @@ static struct notifier_block panic_block = { static int ipmi_init_msghandler(void) { + int i; int rv; if (initialized) @@ -4093,6 +3838,9 @@ static int ipmi_init_msghandler(void) printk(KERN_INFO "ipmi message handler version " IPMI_DRIVER_VERSION "\n"); + for (i = 0; i < MAX_IPMI_INTERFACES; i++) + ipmi_interfaces[i] = NULL; + #ifdef CONFIG_PROC_FS proc_ipmi_root = proc_mkdir("ipmi", NULL); if (!proc_ipmi_root) { diff --git a/trunk/drivers/char/ipmi/ipmi_poweroff.c b/trunk/drivers/char/ipmi/ipmi_poweroff.c index 597eb4f88b84..8d941db83457 100644 --- a/trunk/drivers/char/ipmi/ipmi_poweroff.c +++ b/trunk/drivers/char/ipmi/ipmi_poweroff.c @@ -43,9 +43,6 @@ #define PFX "IPMI poweroff: " -static void ipmi_po_smi_gone(int if_num); -static void ipmi_po_new_smi(int if_num, struct device *device); - /* Definitions for controlling power off (if the system supports it). It * conveniently matches the IPMI chassis control values. */ #define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */ @@ -54,37 +51,6 @@ static void ipmi_po_new_smi(int if_num, struct device *device); /* the IPMI data command */ static int poweroff_powercycle; -/* Which interface to use, -1 means the first we see. */ -static int ifnum_to_use = -1; - -/* Our local state. */ -static int ready = 0; -static ipmi_user_t ipmi_user; -static int ipmi_ifnum; -static void (*specific_poweroff_func)(ipmi_user_t user) = NULL; - -/* Holds the old poweroff function so we can restore it on removal. */ -static void (*old_poweroff_func)(void); - -static int set_param_ifnum(const char *val, struct kernel_param *kp) -{ - int rv = param_set_int(val, kp); - if (rv) - return rv; - if ((ifnum_to_use < 0) || (ifnum_to_use == ipmi_ifnum)) - return 0; - - ipmi_po_smi_gone(ipmi_ifnum); - ipmi_po_new_smi(ifnum_to_use, NULL); - return 0; -} - -module_param_call(ifnum_to_use, set_param_ifnum, param_get_int, - &ifnum_to_use, 0644); -MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " - "timer. Setting to -1 defaults to the first registered " - "interface"); - /* parameter definition to allow user to flag power cycle */ module_param(poweroff_powercycle, int, 0644); MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); @@ -176,42 +142,6 @@ static int ipmi_request_in_rc_mode(ipmi_user_t user, #define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01 #define IPMI_PICMG_ID 0 -#define IPMI_NETFN_OEM 0x2e -#define IPMI_ATCA_PPS_GRACEFUL_RESTART 0x11 -#define IPMI_ATCA_PPS_IANA "\x00\x40\x0A" -#define IPMI_MOTOROLA_MANUFACTURER_ID 0x0000A1 -#define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID 0x0051 - -static void (*atca_oem_poweroff_hook)(ipmi_user_t user) = NULL; - -static void pps_poweroff_atca (ipmi_user_t user) -{ - struct ipmi_system_interface_addr smi_addr; - struct kernel_ipmi_msg send_msg; - int rv; - /* - * Configure IPMI address for local access - */ - smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - smi_addr.channel = IPMI_BMC_CHANNEL; - smi_addr.lun = 0; - - printk(KERN_INFO PFX "PPS powerdown hook used"); - - send_msg.netfn = IPMI_NETFN_OEM; - send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART; - send_msg.data = IPMI_ATCA_PPS_IANA; - send_msg.data_len = 3; - rv = ipmi_request_in_rc_mode(user, - (struct ipmi_addr *) &smi_addr, - &send_msg); - if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { - printk(KERN_ERR PFX "Unable to send ATCA ," - " IPMI error 0x%x\n", rv); - } - return; -} - static int ipmi_atca_detect (ipmi_user_t user) { struct ipmi_system_interface_addr smi_addr; @@ -237,13 +167,6 @@ static int ipmi_atca_detect (ipmi_user_t user) rv = ipmi_request_wait_for_response(user, (struct ipmi_addr *) &smi_addr, &send_msg); - - printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id); - if((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID) - && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) { - printk(KERN_INFO PFX "Installing Pigeon Point Systems Poweroff Hook\n"); - atca_oem_poweroff_hook = pps_poweroff_atca; - } return !rv; } @@ -277,19 +200,12 @@ static void ipmi_poweroff_atca (ipmi_user_t user) rv = ipmi_request_in_rc_mode(user, (struct ipmi_addr *) &smi_addr, &send_msg); - /** At this point, the system may be shutting down, and most - ** serial drivers (if used) will have interrupts turned off - ** it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE - ** return code - **/ - if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { + if (rv) { printk(KERN_ERR PFX "Unable to send ATCA powerdown message," " IPMI error 0x%x\n", rv); goto out; } - if(atca_oem_poweroff_hook) - return atca_oem_poweroff_hook(user); out: return; } @@ -524,6 +440,15 @@ static struct poweroff_function poweroff_functions[] = { / sizeof(struct poweroff_function)) +/* Our local state. */ +static int ready = 0; +static ipmi_user_t ipmi_user; +static void (*specific_poweroff_func)(ipmi_user_t user) = NULL; + +/* Holds the old poweroff function so we can restore it on removal. */ +static void (*old_poweroff_func)(void); + + /* Called on a powerdown request. */ static void ipmi_poweroff_function (void) { @@ -548,9 +473,6 @@ static void ipmi_po_new_smi(int if_num, struct device *device) if (ready) return; - if ((ifnum_to_use >= 0) && (ifnum_to_use != if_num)) - return; - rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL, &ipmi_user); if (rv) { @@ -559,8 +481,6 @@ static void ipmi_po_new_smi(int if_num, struct device *device) return; } - ipmi_ifnum = if_num; - /* * Do a get device ide and store some results, since this is * used by several functions. @@ -621,15 +541,9 @@ static void ipmi_po_new_smi(int if_num, struct device *device) static void ipmi_po_smi_gone(int if_num) { - if (!ready) - return; - - if (ipmi_ifnum != if_num) - return; - - ready = 0; - ipmi_destroy_user(ipmi_user); - pm_power_off = old_poweroff_func; + /* This can never be called, because once poweroff driver is + registered, the interface can't go away until the power + driver is unregistered. */ } static struct ipmi_smi_watcher smi_watcher = @@ -702,9 +616,9 @@ static int ipmi_poweroff_init (void) printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); goto out_err; } +#endif out_err: -#endif return rv; } diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 81a0c89598e7..bb1fac104fda 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -61,10 +61,6 @@ #include "ipmi_si_sm.h" #include #include -#include -#include - -#define PFX "ipmi_si: " /* Measure times between events in the driver. */ #undef DEBUG_TIMING @@ -96,7 +92,7 @@ enum si_intf_state { enum si_type { SI_KCS, SI_SMIC, SI_BT }; -static char *si_to_str[] = { "kcs", "smic", "bt" }; +static char *si_to_str[] = { "KCS", "SMIC", "BT" }; #define DEVICE_NAME "ipmi_si" @@ -226,10 +222,7 @@ struct smi_info static int force_kipmid[SI_MAX_PARMS]; static int num_force_kipmid; -static int unload_when_empty = 1; - static int try_smi_init(struct smi_info *smi); -static void cleanup_one_si(struct smi_info *to_clean); static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); static int register_xaction_notifier(struct notifier_block * nb) @@ -247,18 +240,14 @@ static void deliver_recv_msg(struct smi_info *smi_info, spin_lock(&(smi_info->si_lock)); } -static void return_hosed_msg(struct smi_info *smi_info, int cCode) +static void return_hosed_msg(struct smi_info *smi_info) { struct ipmi_smi_msg *msg = smi_info->curr_msg; - if (cCode < 0 || cCode > IPMI_ERR_UNSPECIFIED) - cCode = IPMI_ERR_UNSPECIFIED; - /* else use it as is */ - /* Make it a reponse */ msg->rsp[0] = msg->data[0] | 4; msg->rsp[1] = msg->data[1]; - msg->rsp[2] = cCode; + msg->rsp[2] = 0xFF; /* Unknown error. */ msg->rsp_size = 3; smi_info->curr_msg = NULL; @@ -309,7 +298,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) smi_info->curr_msg->data, smi_info->curr_msg->data_size); if (err) { - return_hosed_msg(smi_info, err); + return_hosed_msg(smi_info); } rv = SI_SM_CALL_WITHOUT_DELAY; @@ -651,7 +640,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, /* If we were handling a user message, format a response to send to the upper layer to tell it about the error. */ - return_hosed_msg(smi_info, IPMI_ERR_UNSPECIFIED); + return_hosed_msg(smi_info); } si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); } @@ -695,24 +684,22 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, { /* We are idle and the upper layer requested that I fetch events, so do so. */ - atomic_set(&smi_info->req_events, 0); + unsigned char msg[2]; - smi_info->curr_msg = ipmi_alloc_smi_msg(); - if (!smi_info->curr_msg) - goto out; + spin_lock(&smi_info->count_lock); + smi_info->flag_fetches++; + spin_unlock(&smi_info->count_lock); - smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); - smi_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD; - smi_info->curr_msg->data_size = 2; + atomic_set(&smi_info->req_events, 0); + msg[0] = (IPMI_NETFN_APP_REQUEST << 2); + msg[1] = IPMI_GET_MSG_FLAGS_CMD; smi_info->handlers->start_transaction( - smi_info->si_sm, - smi_info->curr_msg->data, - smi_info->curr_msg->data_size); - smi_info->si_state = SI_GETTING_EVENTS; + smi_info->si_sm, msg, 2); + smi_info->si_state = SI_GETTING_FLAGS; goto restart; } - out: + return si_sm_result; } @@ -727,15 +714,6 @@ static void sender(void *send_info, struct timeval t; #endif - if (atomic_read(&smi_info->stop_operation)) { - msg->rsp[0] = msg->data[0] | 4; - msg->rsp[1] = msg->data[1]; - msg->rsp[2] = IPMI_ERR_UNSPECIFIED; - msg->rsp_size = 3; - deliver_recv_msg(smi_info, msg); - return; - } - spin_lock_irqsave(&(smi_info->msg_lock), flags); #ifdef DEBUG_TIMING do_gettimeofday(&t); @@ -827,21 +805,13 @@ static void poll(void *send_info) { struct smi_info *smi_info = send_info; - /* - * Make sure there is some delay in the poll loop so we can - * drive time forward and timeout things. - */ - udelay(10); - smi_event_handler(smi_info, 10); + smi_event_handler(smi_info, 0); } static void request_events(void *send_info) { struct smi_info *smi_info = send_info; - if (atomic_read(&smi_info->stop_operation)) - return; - atomic_set(&smi_info->req_events, 1); } @@ -979,21 +949,12 @@ static int smi_start_processing(void *send_info, return 0; } -static void set_maintenance_mode(void *send_info, int enable) -{ - struct smi_info *smi_info = send_info; - - if (!enable) - atomic_set(&smi_info->req_events, 0); -} - static struct ipmi_smi_handlers handlers = { .owner = THIS_MODULE, .start_processing = smi_start_processing, .sender = sender, .request_events = request_events, - .set_maintenance_mode = set_maintenance_mode, .set_run_to_completion = set_run_to_completion, .poll = poll, }; @@ -1026,16 +987,6 @@ static int num_regshifts = 0; static int slave_addrs[SI_MAX_PARMS]; static int num_slave_addrs = 0; -#define IPMI_IO_ADDR_SPACE 0 -#define IPMI_MEM_ADDR_SPACE 1 -static char *addr_space_to_str[] = { "I/O", "mem" }; - -static int hotmod_handler(const char *val, struct kernel_param *kp); - -module_param_call(hotmod, hotmod_handler, NULL, NULL, 0200); -MODULE_PARM_DESC(hotmod, "Add and remove interfaces. See" - " Documentation/IPMI.txt in the kernel sources for the" - " gory details."); module_param_named(trydefaults, si_trydefaults, bool, 0); MODULE_PARM_DESC(trydefaults, "Setting this to 'false' will disable the" @@ -1087,12 +1038,12 @@ module_param_array(force_kipmid, int, &num_force_kipmid, 0); MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or" " disabled(0). Normally the IPMI driver auto-detects" " this, but the value may be overridden by this parm."); -module_param(unload_when_empty, int, 0); -MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are" - " specified or found, default is 1. Setting to 0" - " is useful for hot add of devices using hotmod."); +#define IPMI_IO_ADDR_SPACE 0 +#define IPMI_MEM_ADDR_SPACE 1 +static char *addr_space_to_str[] = { "I/O", "memory" }; + static void std_irq_cleanup(struct smi_info *info) { if (info->si_type == SI_BT) @@ -1366,234 +1317,6 @@ static int mem_setup(struct smi_info *info) return 0; } -/* - * Parms come in as [:op2[:op3...]]. ops are: - * add|remove,kcs|bt|smic,mem|i/o,
[,[,[,...]]] - * Options are: - * rsp= - * rsi= - * rsh= - * irq= - * ipmb= - */ -enum hotmod_op { HM_ADD, HM_REMOVE }; -struct hotmod_vals { - char *name; - int val; -}; -static struct hotmod_vals hotmod_ops[] = { - { "add", HM_ADD }, - { "remove", HM_REMOVE }, - { NULL } -}; -static struct hotmod_vals hotmod_si[] = { - { "kcs", SI_KCS }, - { "smic", SI_SMIC }, - { "bt", SI_BT }, - { NULL } -}; -static struct hotmod_vals hotmod_as[] = { - { "mem", IPMI_MEM_ADDR_SPACE }, - { "i/o", IPMI_IO_ADDR_SPACE }, - { NULL } -}; -static int ipmi_strcasecmp(const char *s1, const char *s2) -{ - while (*s1 || *s2) { - if (!*s1) - return -1; - if (!*s2) - return 1; - if (*s1 != *s2) - return *s1 - *s2; - s1++; - s2++; - } - return 0; -} -static int parse_str(struct hotmod_vals *v, int *val, char *name, char **curr) -{ - char *s; - int i; - - s = strchr(*curr, ','); - if (!s) { - printk(KERN_WARNING PFX "No hotmod %s given.\n", name); - return -EINVAL; - } - *s = '\0'; - s++; - for (i = 0; hotmod_ops[i].name; i++) { - if (ipmi_strcasecmp(*curr, v[i].name) == 0) { - *val = v[i].val; - *curr = s; - return 0; - } - } - - printk(KERN_WARNING PFX "Invalid hotmod %s '%s'\n", name, *curr); - return -EINVAL; -} - -static int hotmod_handler(const char *val, struct kernel_param *kp) -{ - char *str = kstrdup(val, GFP_KERNEL); - int rv = -EINVAL; - char *next, *curr, *s, *n, *o; - enum hotmod_op op; - enum si_type si_type; - int addr_space; - unsigned long addr; - int regspacing; - int regsize; - int regshift; - int irq; - int ipmb; - int ival; - struct smi_info *info; - - if (!str) - return -ENOMEM; - - /* Kill any trailing spaces, as we can get a "\n" from echo. */ - ival = strlen(str) - 1; - while ((ival >= 0) && isspace(str[ival])) { - str[ival] = '\0'; - ival--; - } - - for (curr = str; curr; curr = next) { - regspacing = 1; - regsize = 1; - regshift = 0; - irq = 0; - ipmb = 0x20; - - next = strchr(curr, ':'); - if (next) { - *next = '\0'; - next++; - } - - rv = parse_str(hotmod_ops, &ival, "operation", &curr); - if (rv) - break; - op = ival; - - rv = parse_str(hotmod_si, &ival, "interface type", &curr); - if (rv) - break; - si_type = ival; - - rv = parse_str(hotmod_as, &addr_space, "address space", &curr); - if (rv) - break; - - s = strchr(curr, ','); - if (s) { - *s = '\0'; - s++; - } - addr = simple_strtoul(curr, &n, 0); - if ((*n != '\0') || (*curr == '\0')) { - printk(KERN_WARNING PFX "Invalid hotmod address" - " '%s'\n", curr); - break; - } - - while (s) { - curr = s; - s = strchr(curr, ','); - if (s) { - *s = '\0'; - s++; - } - o = strchr(curr, '='); - if (o) { - *o = '\0'; - o++; - } -#define HOTMOD_INT_OPT(name, val) \ - if (ipmi_strcasecmp(curr, name) == 0) { \ - if (!o) { \ - printk(KERN_WARNING PFX \ - "No option given for '%s'\n", \ - curr); \ - goto out; \ - } \ - val = simple_strtoul(o, &n, 0); \ - if ((*n != '\0') || (*o == '\0')) { \ - printk(KERN_WARNING PFX \ - "Bad option given for '%s'\n", \ - curr); \ - goto out; \ - } \ - } - - HOTMOD_INT_OPT("rsp", regspacing) - else HOTMOD_INT_OPT("rsi", regsize) - else HOTMOD_INT_OPT("rsh", regshift) - else HOTMOD_INT_OPT("irq", irq) - else HOTMOD_INT_OPT("ipmb", ipmb) - else { - printk(KERN_WARNING PFX - "Invalid hotmod option '%s'\n", - curr); - goto out; - } -#undef HOTMOD_INT_OPT - } - - if (op == HM_ADD) { - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - rv = -ENOMEM; - goto out; - } - - info->addr_source = "hotmod"; - info->si_type = si_type; - info->io.addr_data = addr; - info->io.addr_type = addr_space; - if (addr_space == IPMI_MEM_ADDR_SPACE) - info->io_setup = mem_setup; - else - info->io_setup = port_setup; - - info->io.addr = NULL; - info->io.regspacing = regspacing; - if (!info->io.regspacing) - info->io.regspacing = DEFAULT_REGSPACING; - info->io.regsize = regsize; - if (!info->io.regsize) - info->io.regsize = DEFAULT_REGSPACING; - info->io.regshift = regshift; - info->irq = irq; - if (info->irq) - info->irq_setup = std_irq_setup; - info->slave_addr = ipmb; - - try_smi_init(info); - } else { - /* remove */ - struct smi_info *e, *tmp_e; - - mutex_lock(&smi_infos_lock); - list_for_each_entry_safe(e, tmp_e, &smi_infos, link) { - if (e->io.addr_type != addr_space) - continue; - if (e->si_type != si_type) - continue; - if (e->io.addr_data == addr) - cleanup_one_si(e); - } - mutex_unlock(&smi_infos_lock); - } - } - out: - kfree(str); - return rv; -} static __devinit void hardcode_find_bmc(void) { @@ -1610,11 +1333,11 @@ static __devinit void hardcode_find_bmc(void) info->addr_source = "hardcoded"; - if (!si_type[i] || ipmi_strcasecmp(si_type[i], "kcs") == 0) { + if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) { info->si_type = SI_KCS; - } else if (ipmi_strcasecmp(si_type[i], "smic") == 0) { + } else if (strcmp(si_type[i], "smic") == 0) { info->si_type = SI_SMIC; - } else if (ipmi_strcasecmp(si_type[i], "bt") == 0) { + } else if (strcmp(si_type[i], "bt") == 0) { info->si_type = SI_BT; } else { printk(KERN_WARNING @@ -2229,9 +1952,19 @@ static int try_get_dev_id(struct smi_info *smi_info) static int type_file_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { + char *out = (char *) page; struct smi_info *smi = data; - return sprintf(page, "%s\n", si_to_str[smi->si_type]); + switch (smi->si_type) { + case SI_KCS: + return sprintf(out, "kcs\n"); + case SI_SMIC: + return sprintf(out, "smic\n"); + case SI_BT: + return sprintf(out, "bt\n"); + default: + return 0; + } } static int stat_file_read_proc(char *page, char **start, off_t off, @@ -2267,24 +2000,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off, out += sprintf(out, "incoming_messages: %ld\n", smi->incoming_messages); - return out - page; -} - -static int param_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct smi_info *smi = data; - - return sprintf(page, - "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n", - si_to_str[smi->si_type], - addr_space_to_str[smi->io.addr_type], - smi->io.addr_data, - smi->io.regspacing, - smi->io.regsize, - smi->io.regshift, - smi->irq, - smi->slave_addr); + return (out - ((char *) page)); } /* @@ -2646,7 +2362,6 @@ static int try_smi_init(struct smi_info *new_smi) new_smi, &new_smi->device_id, new_smi->dev, - "bmc", new_smi->slave_addr); if (rv) { printk(KERN_ERR @@ -2675,16 +2390,6 @@ static int try_smi_init(struct smi_info *new_smi) goto out_err_stop_timer; } - rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", - param_read_proc, NULL, - new_smi, THIS_MODULE); - if (rv) { - printk(KERN_ERR - "ipmi_si: Unable to create proc entry: %d\n", - rv); - goto out_err_stop_timer; - } - list_add_tail(&new_smi->link, &smi_infos); mutex_unlock(&smi_infos_lock); @@ -2778,12 +2483,7 @@ static __devinit int init_ipmi_si(void) #endif #ifdef CONFIG_PCI - rv = pci_register_driver(&ipmi_pci_driver); - if (rv){ - printk(KERN_ERR - "init_ipmi_si: Unable to register PCI driver: %d\n", - rv); - } + pci_module_init(&ipmi_pci_driver); #endif if (si_trydefaults) { @@ -2798,7 +2498,7 @@ static __devinit int init_ipmi_si(void) } mutex_lock(&smi_infos_lock); - if (unload_when_empty && list_empty(&smi_infos)) { + if (list_empty(&smi_infos)) { mutex_unlock(&smi_infos_lock); #ifdef CONFIG_PCI pci_unregister_driver(&ipmi_pci_driver); @@ -2813,7 +2513,7 @@ static __devinit int init_ipmi_si(void) } module_init(init_ipmi_si); -static void cleanup_one_si(struct smi_info *to_clean) +static void __devexit cleanup_one_si(struct smi_info *to_clean) { int rv; unsigned long flags; diff --git a/trunk/drivers/char/ipmi/ipmi_smic_sm.c b/trunk/drivers/char/ipmi/ipmi_smic_sm.c index e64ea7d25d24..39d7e5ef1a2b 100644 --- a/trunk/drivers/char/ipmi/ipmi_smic_sm.c +++ b/trunk/drivers/char/ipmi/ipmi_smic_sm.c @@ -141,14 +141,12 @@ static int start_smic_transaction(struct si_sm_data *smic, { unsigned int i; - if (size < 2) - return IPMI_REQ_LEN_INVALID_ERR; - if (size > MAX_SMIC_WRITE_SIZE) - return IPMI_REQ_LEN_EXCEEDED_ERR; - - if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) - return IPMI_NOT_IN_MY_STATE_ERR; - + if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) { + return -1; + } + if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) { + return -2; + } if (smic_debug & SMIC_DEBUG_MSG) { printk(KERN_INFO "start_smic_transaction -"); for (i = 0; i < size; i ++) { diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 90fb2a541916..73f759eaa5a6 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -135,7 +135,6 @@ static int nowayout = WATCHDOG_NOWAYOUT; static ipmi_user_t watchdog_user = NULL; -static int watchdog_ifnum; /* Default the timeout to 10 seconds. */ static int timeout = 10; @@ -162,8 +161,6 @@ static struct fasync_struct *fasync_q = NULL; static char pretimeout_since_last_heartbeat = 0; static char expect_close; -static int ifnum_to_use = -1; - static DECLARE_RWSEM(register_sem); /* Parameters to ipmi_set_timeout */ @@ -172,8 +169,6 @@ static DECLARE_RWSEM(register_sem); #define IPMI_SET_TIMEOUT_FORCE_HB 2 static int ipmi_set_timeout(int do_heartbeat); -static void ipmi_register_watchdog(int ipmi_intf); -static void ipmi_unregister_watchdog(int ipmi_intf); /* If true, the driver will start running as soon as it is configured and ready. */ @@ -250,26 +245,6 @@ static int get_param_str(char *buffer, struct kernel_param *kp) return strlen(buffer); } - -static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp) -{ - int rv = param_set_int(val, kp); - if (rv) - return rv; - if ((ifnum_to_use < 0) || (ifnum_to_use == watchdog_ifnum)) - return 0; - - ipmi_unregister_watchdog(watchdog_ifnum); - ipmi_register_watchdog(ifnum_to_use); - return 0; -} - -module_param_call(ifnum_to_use, set_param_wdog_ifnum, get_param_int, - &ifnum_to_use, 0644); -MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " - "timer. Setting to -1 defaults to the first registered " - "interface"); - module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644); MODULE_PARM_DESC(timeout, "Timeout value in seconds."); @@ -288,13 +263,12 @@ module_param_call(preop, set_param_str, get_param_str, preop_op, 0644); MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " "preop_none, preop_panic, preop_give_data."); -module_param(start_now, int, 0444); +module_param(start_now, int, 0); MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as" "soon as the driver is loaded."); module_param(nowayout, int, 0644); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=CONFIG_WATCHDOG_NOWAYOUT)"); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); /* Default state of the timer. */ static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE; @@ -898,11 +872,6 @@ static void ipmi_register_watchdog(int ipmi_intf) if (watchdog_user) goto out; - if ((ifnum_to_use >= 0) && (ifnum_to_use != ipmi_intf)) - goto out; - - watchdog_ifnum = ipmi_intf; - rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &watchdog_user); if (rv < 0) { printk(KERN_CRIT PFX "Unable to register with ipmi\n"); @@ -932,39 +901,6 @@ static void ipmi_register_watchdog(int ipmi_intf) } } -static void ipmi_unregister_watchdog(int ipmi_intf) -{ - int rv; - - down_write(®ister_sem); - - if (!watchdog_user) - goto out; - - if (watchdog_ifnum != ipmi_intf) - goto out; - - /* Make sure no one can call us any more. */ - misc_deregister(&ipmi_wdog_miscdev); - - /* Wait to make sure the message makes it out. The lower layer has - pointers to our buffers, we want to make sure they are done before - we release our memory. */ - while (atomic_read(&set_timeout_tofree)) - schedule_timeout_uninterruptible(1); - - /* Disconnect from IPMI. */ - rv = ipmi_destroy_user(watchdog_user); - if (rv) { - printk(KERN_WARNING PFX "error unlinking from IPMI: %d\n", - rv); - } - watchdog_user = NULL; - - out: - up_write(®ister_sem); -} - #ifdef HAVE_NMI_HANDLER static int ipmi_nmi(void *dev_id, int cpu, int handled) @@ -1068,7 +1004,9 @@ static void ipmi_new_smi(int if_num, struct device *device) static void ipmi_smi_gone(int if_num) { - ipmi_unregister_watchdog(if_num); + /* This can never be called, because once the watchdog is + registered, the interface can't go away until the watchdog + is unregistered. */ } static struct ipmi_smi_watcher smi_watcher = @@ -1210,32 +1148,30 @@ static int __init ipmi_wdog_init(void) check_parms(); - register_reboot_notifier(&wdog_reboot_notifier); - atomic_notifier_chain_register(&panic_notifier_list, - &wdog_panic_notifier); - rv = ipmi_smi_watcher_register(&smi_watcher); if (rv) { #ifdef HAVE_NMI_HANDLER if (preaction_val == WDOG_PRETIMEOUT_NMI) release_nmi(&ipmi_nmi_handler); #endif - atomic_notifier_chain_unregister(&panic_notifier_list, - &wdog_panic_notifier); - unregister_reboot_notifier(&wdog_reboot_notifier); printk(KERN_WARNING PFX "can't register smi watcher\n"); return rv; } + register_reboot_notifier(&wdog_reboot_notifier); + atomic_notifier_chain_register(&panic_notifier_list, + &wdog_panic_notifier); + printk(KERN_INFO PFX "driver initialized\n"); return 0; } -static void __exit ipmi_wdog_exit(void) +static __exit void ipmi_unregister_watchdog(void) { - ipmi_smi_watcher_unregister(&smi_watcher); - ipmi_unregister_watchdog(watchdog_ifnum); + int rv; + + down_write(®ister_sem); #ifdef HAVE_NMI_HANDLER if (nmi_handler_registered) @@ -1243,8 +1179,37 @@ static void __exit ipmi_wdog_exit(void) #endif atomic_notifier_chain_unregister(&panic_notifier_list, - &wdog_panic_notifier); + &wdog_panic_notifier); unregister_reboot_notifier(&wdog_reboot_notifier); + + if (! watchdog_user) + goto out; + + /* Make sure no one can call us any more. */ + misc_deregister(&ipmi_wdog_miscdev); + + /* Wait to make sure the message makes it out. The lower layer has + pointers to our buffers, we want to make sure they are done before + we release our memory. */ + while (atomic_read(&set_timeout_tofree)) + schedule_timeout_uninterruptible(1); + + /* Disconnect from IPMI. */ + rv = ipmi_destroy_user(watchdog_user); + if (rv) { + printk(KERN_WARNING PFX "error unlinking from IPMI: %d\n", + rv); + } + watchdog_user = NULL; + + out: + up_write(®ister_sem); +} + +static void __exit ipmi_wdog_exit(void) +{ + ipmi_smi_watcher_unregister(&smi_watcher); + ipmi_unregister_watchdog(); } module_exit(ipmi_wdog_exit); module_init(ipmi_wdog_init); diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index 8f591945ebd9..bd9195e17956 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -3476,8 +3476,6 @@ static int stli_initecp(stlibrd_t *brdp) if (sig.magic != cpu_to_le32(ECP_MAGIC)) { release_region(brdp->iobase, brdp->iosize); - iounmap(brdp->membase); - brdp->membase = NULL; return -ENODEV; } @@ -3634,8 +3632,6 @@ static int stli_initonb(stlibrd_t *brdp) sig.magic3 != cpu_to_le16(ONB_MAGIC3)) { release_region(brdp->iobase, brdp->iosize); - iounmap(brdp->membase); - brdp->membase = NULL; return -ENODEV; } diff --git a/trunk/drivers/char/misc.c b/trunk/drivers/char/misc.c index 7e975f606924..7a484fc7cb9e 100644 --- a/trunk/drivers/char/misc.c +++ b/trunk/drivers/char/misc.c @@ -199,8 +199,6 @@ int misc_register(struct miscdevice * misc) dev_t dev; int err = 0; - INIT_LIST_HEAD(&misc->list); - down(&misc_sem); list_for_each_entry(c, &misc_list, list) { if (c->minor == misc->minor) { diff --git a/trunk/drivers/char/mmtimer.c b/trunk/drivers/char/mmtimer.c index c09160383a53..22b9905c1e52 100644 --- a/trunk/drivers/char/mmtimer.c +++ b/trunk/drivers/char/mmtimer.c @@ -680,7 +680,7 @@ static int __init mmtimer_init(void) if (sn_rtc_cycles_per_second < 100000) { printk(KERN_ERR "%s: unable to determine clock frequency\n", MMTIMER_NAME); - goto out1; + return -1; } mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second / @@ -689,13 +689,13 @@ static int __init mmtimer_init(void) if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, IRQF_PERCPU, MMTIMER_NAME, NULL)) { printk(KERN_WARNING "%s: unable to allocate interrupt.", MMTIMER_NAME); - goto out1; + return -1; } if (misc_register(&mmtimer_miscdev)) { printk(KERN_ERR "%s: failed to register device\n", MMTIMER_NAME); - goto out2; + return -1; } /* Get max numbered node, calculate slots needed */ @@ -709,18 +709,16 @@ static int __init mmtimer_init(void) if (timers == NULL) { printk(KERN_ERR "%s: failed to allocate memory for device\n", MMTIMER_NAME); - goto out3; + return -1; } - memset(timers,0,(sizeof(mmtimer_t *)*maxn)); - /* Allocate mmtimer_t's for each online node */ for_each_online_node(node) { timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node); if (timers[node] == NULL) { printk(KERN_ERR "%s: failed to allocate memory for device\n", MMTIMER_NAME); - goto out4; + return -1; } for (i=0; i< NUM_COMPARATORS; i++) { mmtimer_t * base = timers[node] + i; @@ -741,17 +739,6 @@ static int __init mmtimer_init(void) sn_rtc_cycles_per_second/(unsigned long)1E6); return 0; - -out4: - for_each_online_node(node) { - kfree(timers[node]); - } -out3: - misc_deregister(&mmtimer_miscdev); -out2: - free_irq(SGI_MMTIMER_VECTOR, NULL); -out1: - return -1; } module_init(mmtimer_init); diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index 8b316953173d..2d025a9fd14d 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -498,12 +498,9 @@ static void __exit moxa_exit(void) printk("Couldn't unregister MOXA Intellio family serial driver\n"); put_tty_driver(moxaDriver); - for (i = 0; i < MAX_BOARDS; i++) { - if (moxaBaseAddr[i]) - iounmap(moxaBaseAddr[i]); + for (i = 0; i < MAX_BOARDS; i++) if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI) pci_dev_put(moxa_boards[i].pciInfo.pdev); - } if (verbose) printk("Done\n"); diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 74d21c1c104f..1bd12296dca5 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -75,10 +75,8 @@ #include #include -#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_CS_MODULE)) -#define SYNCLINK_GENERIC_HDLC 1 -#else -#define SYNCLINK_GENERIC_HDLC 0 +#ifdef CONFIG_HDLC_MODULE +#define CONFIG_HDLC 1 #endif #define GET_USER(error,value,addr) error = get_user(value,addr) @@ -237,7 +235,7 @@ typedef struct _mgslpc_info { int dosyncppp; spinlock_t netlock; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC struct net_device *netdev; #endif @@ -394,7 +392,7 @@ static void tx_timeout(unsigned long context); static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC #define dev_to_port(D) (dev_to_hdlc(D)->priv) static void hdlcdev_tx_done(MGSLPC_INFO *info); static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size); @@ -1055,7 +1053,7 @@ static void tx_done(MGSLPC_INFO *info) info->drop_rts_on_tx_done = 0; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else @@ -1166,7 +1164,7 @@ static void dcd_change(MGSLPC_INFO *info) } else info->input_signal_events.dcd_down++; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) { if (info->serial_signals & SerialSignal_DCD) netif_carrier_on(info->netdev); @@ -2955,7 +2953,7 @@ static void mgslpc_add_device(MGSLPC_INFO *info) printk( "SyncLink PC Card %s:IO=%04X IRQ=%d\n", info->device_name, info->io_base, info->irq_level); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_init(info); #endif } @@ -2971,7 +2969,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) last->next_device = info->next_device; else mgslpc_device_list = info->next_device; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_exit(info); #endif release_resources(info); @@ -3903,7 +3901,7 @@ static int rx_get_frame(MGSLPC_INFO *info) return_frame = 1; } framesize = 0; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC { struct net_device_stats *stats = hdlc_stats(info->netdev); stats->rx_errors++; @@ -3937,7 +3935,7 @@ static int rx_get_frame(MGSLPC_INFO *info) ++framesize; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_rx(info, buf->data, framesize); else @@ -4093,7 +4091,7 @@ static void tx_timeout(unsigned long context) spin_unlock_irqrestore(&info->lock,flags); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else @@ -4101,7 +4099,7 @@ static void tx_timeout(unsigned long context) bh_transmit(info); } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC /** * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) diff --git a/trunk/drivers/char/rio/rio_linux.c b/trunk/drivers/char/rio/rio_linux.c index e79b2ede8510..7ac68cb3bedd 100644 --- a/trunk/drivers/char/rio/rio_linux.c +++ b/trunk/drivers/char/rio/rio_linux.c @@ -1026,7 +1026,6 @@ static int __init rio_init(void) found++; } else { iounmap(p->RIOHosts[p->RIONumHosts].Caddr); - p->RIOHosts[p->RIONumHosts].Caddr = NULL; } } @@ -1079,7 +1078,6 @@ static int __init rio_init(void) found++; } else { iounmap(p->RIOHosts[p->RIONumHosts].Caddr); - p->RIOHosts[p->RIONumHosts].Caddr = NULL; } #else printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); @@ -1119,10 +1117,8 @@ static int __init rio_init(void) } } - if (!okboard) { + if (!okboard) iounmap(hp->Caddr); - hp->Caddr = NULL; - } } } @@ -1192,8 +1188,6 @@ static void __exit rio_exit(void) } /* It is safe/allowed to del_timer a non-active timer */ del_timer(&hp->timer); - if (hp->Caddr) - iounmap(hp->Caddr); if (hp->Type == RIO_PCI) pci_dev_put(hp->pdev); } diff --git a/trunk/drivers/char/riscom8.c b/trunk/drivers/char/riscom8.c index 0a77bfcd5b5e..722dd3e74185 100644 --- a/trunk/drivers/char/riscom8.c +++ b/trunk/drivers/char/riscom8.c @@ -82,6 +82,11 @@ static struct riscom_board * IRQ_to_board[16]; static struct tty_driver *riscom_driver; +static unsigned long baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 76800, 0, +}; + static struct riscom_board rc_board[RC_NBOARD] = { { .base = RC_IOBASE1, diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index 645187b9141e..147c30da81ea 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -101,10 +101,8 @@ #include #include -#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_MODULE)) -#define SYNCLINK_GENERIC_HDLC 1 -#else -#define SYNCLINK_GENERIC_HDLC 0 +#ifdef CONFIG_HDLC_MODULE +#define CONFIG_HDLC 1 #endif #define GET_USER(error,value,addr) error = get_user(value,addr) @@ -322,7 +320,7 @@ struct mgsl_struct { int dosyncppp; spinlock_t netlock; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC struct net_device *netdev; #endif }; @@ -730,7 +728,7 @@ static void usc_loopmode_send_done( struct mgsl_struct * info ); static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC #define dev_to_port(D) (dev_to_hdlc(D)->priv) static void hdlcdev_tx_done(struct mgsl_struct *info); static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size); @@ -1279,7 +1277,7 @@ static void mgsl_isr_transmit_status( struct mgsl_struct *info ) info->drop_rts_on_tx_done = 0; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else @@ -1344,7 +1342,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) info->input_signal_events.dcd_up++; } else info->input_signal_events.dcd_down++; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) { if (status & MISCSTATUS_DCD) netif_carrier_on(info->netdev); @@ -4315,7 +4313,7 @@ static void mgsl_add_device( struct mgsl_struct *info ) info->max_frame_size ); } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_init(info); #endif @@ -4473,7 +4471,7 @@ static void synclink_cleanup(void) info = mgsl_device_list; while(info) { -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_exit(info); #endif mgsl_release_resources(info); @@ -6647,7 +6645,7 @@ static int mgsl_get_rx_frame(struct mgsl_struct *info) return_frame = 1; } framesize = 0; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC { struct net_device_stats *stats = hdlc_stats(info->netdev); stats->rx_errors++; @@ -6723,7 +6721,7 @@ static int mgsl_get_rx_frame(struct mgsl_struct *info) *ptmp); } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_rx(info,info->intermediate_rxbuffer,framesize); else @@ -7627,7 +7625,7 @@ static void mgsl_tx_timeout(unsigned long context) spin_unlock_irqrestore(&info->irq_spinlock,flags); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else @@ -7703,7 +7701,7 @@ static int usc_loopmode_active( struct mgsl_struct * info) return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC /** * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index e4730a7312b5..07f34d43dc7f 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -83,10 +83,8 @@ #include "linux/synclink.h" -#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) -#define SYNCLINK_GENERIC_HDLC 1 -#else -#define SYNCLINK_GENERIC_HDLC 0 +#ifdef CONFIG_HDLC_MODULE +#define CONFIG_HDLC 1 #endif /* @@ -173,7 +171,7 @@ static void set_break(struct tty_struct *tty, int break_state); /* * generic HDLC support and callbacks */ -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC #define dev_to_port(D) (dev_to_hdlc(D)->priv) static void hdlcdev_tx_done(struct slgt_info *info); static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); @@ -361,7 +359,7 @@ struct slgt_info { int netcount; int dosyncppp; spinlock_t netlock; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC struct net_device *netdev; #endif @@ -1356,7 +1354,7 @@ static void set_break(struct tty_struct *tty, int break_state) spin_unlock_irqrestore(&info->lock,flags); } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC /** * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) @@ -2004,7 +2002,7 @@ static void dcd_change(struct slgt_info *info) } else { info->input_signal_events.dcd_down++; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) { if (info->signals & SerialSignal_DCD) netif_carrier_on(info->netdev); @@ -2182,7 +2180,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status) set_signals(info); } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else @@ -3308,7 +3306,7 @@ static void add_device(struct slgt_info *info) devstr, info->device_name, info->phys_reg_addr, info->irq_level, info->max_frame_size); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_init(info); #endif } @@ -3490,7 +3488,7 @@ static void slgt_cleanup(void) /* release devices */ info = slgt_device_list; while(info) { -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_exit(info); #endif free_dma_bufs(info); @@ -3524,7 +3522,6 @@ static int __init slgt_init(void) if (!slgt_device_list) { printk("%s no devices found\n",driver_name); - pci_unregister_driver(&pci_driver); return -ENODEV; } @@ -4436,7 +4433,7 @@ static int rx_get_frame(struct slgt_info *info) framesize = 0; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (framesize == 0) { struct net_device_stats *stats = hdlc_stats(info->netdev); stats->rx_errors++; @@ -4479,7 +4476,7 @@ static int rx_get_frame(struct slgt_info *info) framesize++; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_rx(info,info->tmp_rbuf, framesize); else @@ -4782,7 +4779,7 @@ static void tx_timeout(unsigned long context) info->tx_count = 0; spin_unlock_irqrestore(&info->lock,flags); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 20a96ef250be..13a57245cf2e 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -67,10 +67,8 @@ #include #include -#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE)) -#define SYNCLINK_GENERIC_HDLC 1 -#else -#define SYNCLINK_GENERIC_HDLC 0 +#ifdef CONFIG_HDLC_MODULE +#define CONFIG_HDLC 1 #endif #define GET_USER(error,value,addr) error = get_user(value,addr) @@ -282,7 +280,7 @@ typedef struct _synclinkmp_info { int dosyncppp; spinlock_t netlock; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC struct net_device *netdev; #endif @@ -538,7 +536,7 @@ static void throttle(struct tty_struct * tty); static void unthrottle(struct tty_struct * tty); static void set_break(struct tty_struct *tty, int break_state); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC #define dev_to_port(D) (dev_to_hdlc(D)->priv) static void hdlcdev_tx_done(SLMP_INFO *info); static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size); @@ -1609,7 +1607,7 @@ static void set_break(struct tty_struct *tty, int break_state) spin_unlock_irqrestore(&info->lock,flags); } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC /** * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) @@ -2341,7 +2339,7 @@ static void isr_txeom(SLMP_INFO * info, unsigned char status) set_signals(info); } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else @@ -2525,7 +2523,7 @@ void isr_io_pin( SLMP_INFO *info, u16 status ) info->input_signal_events.dcd_up++; } else info->input_signal_events.dcd_down++; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) { if (status & SerialSignal_DCD) netif_carrier_on(info->netdev); @@ -3785,7 +3783,7 @@ void add_device(SLMP_INFO *info) info->irq_level, info->max_frame_size ); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_init(info); #endif } @@ -3979,7 +3977,7 @@ static void synclinkmp_cleanup(void) /* release devices */ info = synclinkmp_device_list; while(info) { -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC hdlcdev_exit(info); #endif free_dma_bufs(info); @@ -4981,7 +4979,7 @@ int rx_get_frame(SLMP_INFO *info) info->icount.rxcrc++; framesize = 0; -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC { struct net_device_stats *stats = hdlc_stats(info->netdev); stats->rx_errors++; @@ -5022,7 +5020,7 @@ int rx_get_frame(SLMP_INFO *info) index = 0; } -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_rx(info,info->tmp_rx_buf,framesize); else @@ -5533,7 +5531,7 @@ void tx_timeout(unsigned long context) spin_unlock_irqrestore(&info->lock,flags); -#if SYNCLINK_GENERIC_HDLC +#ifdef CONFIG_HDLC if (info->netcount) hdlcdev_tx_done(info); else diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index 05810c8d20bc..c64f5bcff947 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -182,18 +182,6 @@ static struct sysrq_key_op sysrq_showstate_op = { .enable_mask = SYSRQ_ENABLE_DUMP, }; -static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) -{ - show_state_filter(TASK_UNINTERRUPTIBLE); -} -static struct sysrq_key_op sysrq_showstate_blocked_op = { - .handler = sysrq_handle_showstate_blocked, - .help_msg = "showBlockedTasks", - .action_msg = "Show Blocked State", - .enable_mask = SYSRQ_ENABLE_DUMP, -}; - - static void sysrq_handle_showmem(int key, struct tty_struct *tty) { show_mem(); @@ -316,7 +304,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { /* May be assigned at init time by SMP VOYAGER */ NULL, /* v */ NULL, /* w */ - &sysrq_showstate_blocked_op, /* x */ + NULL, /* x */ NULL, /* y */ NULL /* z */ }; diff --git a/trunk/drivers/char/toshiba.c b/trunk/drivers/char/toshiba.c index 07067c31c4ec..dd36fd04a842 100644 --- a/trunk/drivers/char/toshiba.c +++ b/trunk/drivers/char/toshiba.c @@ -249,7 +249,6 @@ int tosh_smm(SMMRegisters *regs) return eax; } -EXPORT_SYMBOL(tosh_smm); static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 33e1f66e39cb..774fa861169a 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -1155,7 +1155,6 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { list_del(&chip->list); - misc_deregister(&chip->vendor.miscdev); put_device(dev); clear_bit(chip->dev_num, dev_mask); kfree(chip); diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index a8239dac994f..75ff0286e1ad 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -152,7 +152,7 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y); static void save_cur(struct vc_data *vc); static void reset_terminal(struct vc_data *vc, int do_clear); static void con_flush_chars(struct tty_struct *tty); -static int set_vesa_blanking(char __user *p); +static void set_vesa_blanking(char __user *p); static void set_cursor(struct vc_data *vc); static void hide_cursor(struct vc_data *vc); static void console_callback(struct work_struct *ignored); @@ -2369,7 +2369,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) ret = __put_user(data, p); break; case TIOCL_SETVESABLANK: - ret = set_vesa_blanking(p); + set_vesa_blanking(p); break; case TIOCL_GETKMSGREDIRECT: data = kmsg_redirect; @@ -3313,15 +3313,11 @@ postcore_initcall(vtconsole_class_init); * Screen blanking */ -static int set_vesa_blanking(char __user *p) +static void set_vesa_blanking(char __user *p) { - unsigned int mode; - - if (get_user(mode, p + 1)) - return -EFAULT; - - vesa_blank_mode = (mode < 4) ? mode : 0; - return 0; + unsigned int mode; + get_user(mode, p + 1); + vesa_blank_mode = (mode < 4) ? mode : 0; } void do_blank_screen(int entering_gfx) diff --git a/trunk/drivers/char/watchdog/pcwd_usb.c b/trunk/drivers/char/watchdog/pcwd_usb.c index 61138726b501..e275dd4a705d 100644 --- a/trunk/drivers/char/watchdog/pcwd_usb.c +++ b/trunk/drivers/char/watchdog/pcwd_usb.c @@ -634,7 +634,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); /* set up the memory buffer's */ - if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma))) { + if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, SLAB_ATOMIC, &usb_pcwd->intr_dma))) { printk(KERN_ERR PFX "Out of memory\n"); goto error; } diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 47ab42db122a..7a7c6e6dfe4f 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -1537,6 +1537,7 @@ int cpufreq_update_policy(unsigned int cpu) } EXPORT_SYMBOL(cpufreq_update_policy); +#ifdef CONFIG_HOTPLUG_CPU static int cpufreq_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -1576,6 +1577,7 @@ static struct notifier_block __cpuinitdata cpufreq_cpu_notifier = { .notifier_call = cpufreq_cpu_callback, }; +#endif /* CONFIG_HOTPLUG_CPU */ /********************************************************************* * REGISTER / UNREGISTER CPUFREQ DRIVER * diff --git a/trunk/drivers/dma/ioatdma.c b/trunk/drivers/dma/ioatdma.c index 8e8726104619..0358419a0e48 100644 --- a/trunk/drivers/dma/ioatdma.c +++ b/trunk/drivers/dma/ioatdma.c @@ -636,10 +636,10 @@ static int ioat_self_test(struct ioat_device *device) dma_cookie_t cookie; int err = 0; - src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); + src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL); if (!src) return -ENOMEM; - dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); + dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL); if (!dest) { kfree(src); return -ENOMEM; diff --git a/trunk/drivers/edac/edac_mc.c b/trunk/drivers/edac/edac_mc.c index 1b4fc9221803..75e9e38330ff 100644 --- a/trunk/drivers/edac/edac_mc.c +++ b/trunk/drivers/edac/edac_mc.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index e23bc0d62159..0c68d0f0d8e5 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -389,6 +389,14 @@ config BLK_DEV_RZ1000 Linux. This may slow disk throughput by a few percent, but at least things will operate 100% reliably. +config BLK_DEV_SL82C105 + tristate "Winbond SL82c105 support" + depends on PCI && (PPC || ARM) && BLK_DEV_IDEPCI + help + If you have a Winbond SL82c105 IDE controller, say Y here to enable + special configuration for this chip. This is common on various CHRP + motherboards, but could be used elsewhere. If in doubt, say Y. + config BLK_DEV_IDEDMA_PCI bool "Generic PCI bus-master DMA support" depends on PCI && BLK_DEV_IDEPCI @@ -704,14 +712,6 @@ config BLK_DEV_SIS5513 Please read the comments at the top of . -config BLK_DEV_SL82C105 - tristate "Winbond SL82c105 support" - depends on (PPC || ARM) - help - If you have a Winbond SL82c105 IDE controller, say Y here to enable - special configuration for this chip. This is common on various CHRP - motherboards, but could be used elsewhere. If in doubt, say Y. - config BLK_DEV_SLC90E66 tristate "SLC90E66 chipset support" help diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index 16890769dca6..287a66201150 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -973,8 +973,8 @@ ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name) * @drive: drive * * Automatically remove all the driver specific settings for this - * drive. This function may not be called from IRQ context. The - * caller must hold ide_setting_sem. + * drive. This function may sleep and must not be called from IRQ + * context. The caller must hold ide_setting_sem. */ static void auto_remove_settings (ide_drive_t *drive) @@ -1874,22 +1874,11 @@ void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) { unsigned long flags; + down(&ide_setting_sem); + spin_lock_irqsave(&ide_lock, flags); #ifdef CONFIG_PROC_FS ide_remove_proc_entries(drive->proc, driver->proc); #endif - down(&ide_setting_sem); - spin_lock_irqsave(&ide_lock, flags); - /* - * ide_setting_sem protects the settings list - * ide_lock protects the use of settings - * - * so we need to hold both, ide_settings_sem because we want to - * modify the settings list, and ide_lock because we cannot take - * a setting out that is being used. - * - * OTOH both ide_{read,write}_setting are only ever used under - * ide_setting_sem. - */ auto_remove_settings(drive); spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); diff --git a/trunk/drivers/ide/pci/via82cxxx.c b/trunk/drivers/ide/pci/via82cxxx.c index 61f1a9665a7f..eb7ab112c050 100644 --- a/trunk/drivers/ide/pci/via82cxxx.c +++ b/trunk/drivers/ide/pci/via82cxxx.c @@ -282,11 +282,11 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const * Find the ISA bridge to see how good the IDE is. */ via_config = via_config_find(&isa); - - /* We checked this earlier so if it fails here deeep badness - is involved */ - - BUG_ON(!via_config->id); + if (!via_config->id) { + printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); + pci_dev_put(isa); + return -ENODEV; + } /* * Setup or disable Clk66 if appropriate @@ -494,17 +494,6 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - struct pci_dev *isa = NULL; - struct via_isa_bridge *via_config; - /* - * Find the ISA bridge and check we know what it is. - */ - via_config = via_config_find(&isa); - pci_dev_put(isa); - if (!via_config->id) { - printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); - return -ENODEV; - } return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]); } diff --git a/trunk/drivers/ieee1394/eth1394.c b/trunk/drivers/ieee1394/eth1394.c index 27d6c642415d..31e5cc49d61a 100644 --- a/trunk/drivers/ieee1394/eth1394.c +++ b/trunk/drivers/ieee1394/eth1394.c @@ -133,7 +133,7 @@ struct eth1394_node_info { #define ETH1394_DRIVER_NAME "eth1394" static const char driver_name[] = ETH1394_DRIVER_NAME; -static struct kmem_cache *packet_task_cache; +static kmem_cache_t *packet_task_cache; static struct hpsb_highlevel eth1394_highlevel; diff --git a/trunk/drivers/ieee1394/hosts.c b/trunk/drivers/ieee1394/hosts.c index b935e08695a9..8f4378a1631c 100644 --- a/trunk/drivers/ieee1394/hosts.c +++ b/trunk/drivers/ieee1394/hosts.c @@ -123,7 +123,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, int i; int hostnum = 0; - h = kzalloc(sizeof(*h) + extra, GFP_KERNEL); + h = kzalloc(sizeof(*h) + extra, SLAB_KERNEL); if (!h) return NULL; diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c index e829c9336b3c..8e7b83f84485 100644 --- a/trunk/drivers/ieee1394/nodemgr.c +++ b/trunk/drivers/ieee1394/nodemgr.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "csr.h" diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index eae97d8dcf03..6e8ea9110c46 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -1225,7 +1225,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso) int ctx; int ret = -ENOMEM; - recv = kmalloc(sizeof(*recv), GFP_KERNEL); + recv = kmalloc(sizeof(*recv), SLAB_KERNEL); if (!recv) return -ENOMEM; @@ -1918,7 +1918,7 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso) int ctx; int ret = -ENOMEM; - xmit = kmalloc(sizeof(*xmit), GFP_KERNEL); + xmit = kmalloc(sizeof(*xmit), SLAB_KERNEL); if (!xmit) return -ENOMEM; @@ -3021,7 +3021,7 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, return -ENOMEM; } - d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); + d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, SLAB_KERNEL, d->prg_bus+i); OHCI_DMA_ALLOC("pool dma_rcv prg[%d]", i); if (d->prg_cpu[i] != NULL) { @@ -3117,7 +3117,7 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, OHCI_DMA_ALLOC("dma_rcv prg pool"); for (i = 0; i < d->num_desc; i++) { - d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); + d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, SLAB_KERNEL, d->prg_bus+i); OHCI_DMA_ALLOC("pool dma_trm prg[%d]", i); if (d->prg_cpu[i] != NULL) { diff --git a/trunk/drivers/ieee1394/pcilynx.c b/trunk/drivers/ieee1394/pcilynx.c index 9cab1d661472..0a7412e27eb4 100644 --- a/trunk/drivers/ieee1394/pcilynx.c +++ b/trunk/drivers/ieee1394/pcilynx.c @@ -1428,7 +1428,7 @@ static int __devinit add_card(struct pci_dev *dev, struct i2c_algo_bit_data i2c_adapter_data; error = -ENOMEM; - i2c_ad = kmalloc(sizeof(*i2c_ad), GFP_KERNEL); + i2c_ad = kmalloc(sizeof(*i2c_ad), SLAB_KERNEL); if (!i2c_ad) FAIL("failed to allocate I2C adapter memory"); memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter)); diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c index bf71e069eaf5..5ec4f5eb6b19 100644 --- a/trunk/drivers/ieee1394/raw1394.c +++ b/trunk/drivers/ieee1394/raw1394.c @@ -112,7 +112,7 @@ static struct pending_request *__alloc_pending_request(gfp_t flags) static inline struct pending_request *alloc_pending_request(void) { - return __alloc_pending_request(GFP_KERNEL); + return __alloc_pending_request(SLAB_KERNEL); } static void free_pending_request(struct pending_request *req) @@ -259,7 +259,7 @@ static void host_reset(struct hpsb_host *host) if (hi != NULL) { list_for_each_entry(fi, &hi->file_info_list, list) { if (fi->notification == RAW1394_NOTIFY_ON) { - req = __alloc_pending_request(GFP_ATOMIC); + req = __alloc_pending_request(SLAB_ATOMIC); if (req != NULL) { req->file_info = fi; @@ -306,13 +306,13 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data, if (!(fi->listen_channels & (1ULL << channel))) continue; - req = __alloc_pending_request(GFP_ATOMIC); + req = __alloc_pending_request(SLAB_ATOMIC); if (!req) break; if (!ibs) { ibs = kmalloc(sizeof(*ibs) + length, - GFP_ATOMIC); + SLAB_ATOMIC); if (!ibs) { kfree(req); break; @@ -367,13 +367,13 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction, if (!fi->fcp_buffer) continue; - req = __alloc_pending_request(GFP_ATOMIC); + req = __alloc_pending_request(SLAB_ATOMIC); if (!req) break; if (!ibs) { ibs = kmalloc(sizeof(*ibs) + length, - GFP_ATOMIC); + SLAB_ATOMIC); if (!ibs) { kfree(req); break; @@ -593,7 +593,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) switch (req->req.type) { case RAW1394_REQ_LIST_CARDS: spin_lock_irqsave(&host_info_lock, flags); - khl = kmalloc(sizeof(*khl) * host_count, GFP_ATOMIC); + khl = kmalloc(sizeof(*khl) * host_count, SLAB_ATOMIC); if (khl) { req->req.misc = host_count; @@ -1045,7 +1045,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, } if (arm_addr->notification_options & ARM_READ) { DBGMSG("arm_read -> entering notification-section"); - req = __alloc_pending_request(GFP_ATOMIC); + req = __alloc_pending_request(SLAB_ATOMIC); if (!req) { DBGMSG("arm_read -> rcode_conflict_error"); spin_unlock_irqrestore(&host_info_lock, irqflags); @@ -1064,7 +1064,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, sizeof(struct arm_response) + sizeof(struct arm_request_response); } - req->data = kmalloc(size, GFP_ATOMIC); + req->data = kmalloc(size, SLAB_ATOMIC); if (!(req->data)) { free_pending_request(req); DBGMSG("arm_read -> rcode_conflict_error"); @@ -1198,7 +1198,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid, } if (arm_addr->notification_options & ARM_WRITE) { DBGMSG("arm_write -> entering notification-section"); - req = __alloc_pending_request(GFP_ATOMIC); + req = __alloc_pending_request(SLAB_ATOMIC); if (!req) { DBGMSG("arm_write -> rcode_conflict_error"); spin_unlock_irqrestore(&host_info_lock, irqflags); @@ -1209,7 +1209,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid, sizeof(struct arm_request) + sizeof(struct arm_response) + (length) * sizeof(byte_t) + sizeof(struct arm_request_response); - req->data = kmalloc(size, GFP_ATOMIC); + req->data = kmalloc(size, SLAB_ATOMIC); if (!(req->data)) { free_pending_request(req); DBGMSG("arm_write -> rcode_conflict_error"); @@ -1400,7 +1400,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store, if (arm_addr->notification_options & ARM_LOCK) { byte_t *buf1, *buf2; DBGMSG("arm_lock -> entering notification-section"); - req = __alloc_pending_request(GFP_ATOMIC); + req = __alloc_pending_request(SLAB_ATOMIC); if (!req) { DBGMSG("arm_lock -> rcode_conflict_error"); spin_unlock_irqrestore(&host_info_lock, irqflags); @@ -1408,7 +1408,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store, The request may be retried */ } size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response); /* maximum */ - req->data = kmalloc(size, GFP_ATOMIC); + req->data = kmalloc(size, SLAB_ATOMIC); if (!(req->data)) { free_pending_request(req); DBGMSG("arm_lock -> rcode_conflict_error"); @@ -1628,7 +1628,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store, if (arm_addr->notification_options & ARM_LOCK) { byte_t *buf1, *buf2; DBGMSG("arm_lock64 -> entering notification-section"); - req = __alloc_pending_request(GFP_ATOMIC); + req = __alloc_pending_request(SLAB_ATOMIC); if (!req) { spin_unlock_irqrestore(&host_info_lock, irqflags); DBGMSG("arm_lock64 -> rcode_conflict_error"); @@ -1636,7 +1636,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store, The request may be retried */ } size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response); /* maximum */ - req->data = kmalloc(size, GFP_ATOMIC); + req->data = kmalloc(size, SLAB_ATOMIC); if (!(req->data)) { free_pending_request(req); spin_unlock_irqrestore(&host_info_lock, irqflags); @@ -1737,7 +1737,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) return (-EINVAL); } /* addr-list-entry for fileinfo */ - addr = kmalloc(sizeof(*addr), GFP_KERNEL); + addr = kmalloc(sizeof(*addr), SLAB_KERNEL); if (!addr) { req->req.length = 0; return (-ENOMEM); @@ -2103,7 +2103,7 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req) static int get_config_rom(struct file_info *fi, struct pending_request *req) { int ret = sizeof(struct raw1394_request); - quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); + quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL); int status; if (!data) @@ -2133,7 +2133,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req) static int update_config_rom(struct file_info *fi, struct pending_request *req) { int ret = sizeof(struct raw1394_request); - quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); + quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL); if (!data) return -ENOMEM; if (copy_from_user(data, int2ptr(req->req.sendb), req->req.length)) { @@ -2443,7 +2443,7 @@ static void queue_rawiso_event(struct file_info *fi) /* only one ISO activity event may be in the queue */ if (!__rawiso_event_in_queue(fi)) { struct pending_request *req = - __alloc_pending_request(GFP_ATOMIC); + __alloc_pending_request(SLAB_ATOMIC); if (req) { req->file_info = fi; @@ -2779,7 +2779,7 @@ static int raw1394_open(struct inode *inode, struct file *file) { struct file_info *fi; - fi = kzalloc(sizeof(*fi), GFP_KERNEL); + fi = kzalloc(sizeof(*fi), SLAB_KERNEL); if (!fi) return -ENOMEM; diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_vq.c b/trunk/drivers/infiniband/hw/amso1100/c2_vq.c index 36620a22413c..40caeb5f41b4 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_vq.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_vq.c @@ -164,7 +164,7 @@ void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *r) */ void *vq_repbuf_alloc(struct c2_dev *c2dev) { - return kmem_cache_alloc(c2dev->host_msg_cache, GFP_ATOMIC); + return kmem_cache_alloc(c2dev->host_msg_cache, SLAB_ATOMIC); } /* diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_av.c b/trunk/drivers/infiniband/hw/ehca/ehca_av.c index 0d6e2c4bb245..214e2fdddeef 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_av.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_av.c @@ -57,7 +57,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) struct ehca_shca *shca = container_of(pd->device, struct ehca_shca, ib_device); - av = kmem_cache_alloc(av_cache, GFP_KERNEL); + av = kmem_cache_alloc(av_cache, SLAB_KERNEL); if (!av) { ehca_err(pd->device, "Out of memory pd=%p ah_attr=%p", pd, ah_attr); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_cq.c b/trunk/drivers/infiniband/hw/ehca/ehca_cq.c index 93995b658d94..458fe19648a1 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_cq.c @@ -134,7 +134,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) return ERR_PTR(-EINVAL); - my_cq = kmem_cache_alloc(cq_cache, GFP_KERNEL); + my_cq = kmem_cache_alloc(cq_cache, SLAB_KERNEL); if (!my_cq) { ehca_err(device, "Out of memory for ehca_cq struct device=%p", device); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_main.c b/trunk/drivers/infiniband/hw/ehca/ehca_main.c index cc47e4c13a18..3d1c1c535038 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_main.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_main.c @@ -108,7 +108,7 @@ static struct kmem_cache *ctblk_cache = NULL; void *ehca_alloc_fw_ctrlblock(void) { - void *ret = kmem_cache_zalloc(ctblk_cache, GFP_KERNEL); + void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL); if (!ret) ehca_gen_err("Out of memory for ctblk"); return ret; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c index 0a5e2214cc5f..abce676c0ae0 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -53,7 +53,7 @@ static struct ehca_mr *ehca_mr_new(void) { struct ehca_mr *me; - me = kmem_cache_alloc(mr_cache, GFP_KERNEL); + me = kmem_cache_alloc(mr_cache, SLAB_KERNEL); if (me) { memset(me, 0, sizeof(struct ehca_mr)); spin_lock_init(&me->mrlock); @@ -72,7 +72,7 @@ static struct ehca_mw *ehca_mw_new(void) { struct ehca_mw *me; - me = kmem_cache_alloc(mw_cache, GFP_KERNEL); + me = kmem_cache_alloc(mw_cache, SLAB_KERNEL); if (me) { memset(me, 0, sizeof(struct ehca_mw)); spin_lock_init(&me->mwlock); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_pd.c b/trunk/drivers/infiniband/hw/ehca/ehca_pd.c index d5345e5b3cd6..2c3cdc6f7b39 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_pd.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_pd.c @@ -50,7 +50,7 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device, { struct ehca_pd *pd; - pd = kmem_cache_alloc(pd_cache, GFP_KERNEL); + pd = kmem_cache_alloc(pd_cache, SLAB_KERNEL); if (!pd) { ehca_err(device, "device=%p context=%p out of memory", device, context); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c index c6c9cef203e3..8682aa50c707 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c @@ -450,7 +450,7 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, if (pd->uobject && udata) context = pd->uobject->context; - my_qp = kmem_cache_alloc(qp_cache, GFP_KERNEL); + my_qp = kmem_cache_alloc(qp_cache, SLAB_KERNEL); if (!my_qp) { ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); return ERR_PTR(-ENOMEM); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_av.c b/trunk/drivers/infiniband/hw/mthca/mthca_av.c index 27caf3b0648a..57cdc1bc5f50 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_av.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_av.c @@ -189,7 +189,7 @@ int mthca_create_ah(struct mthca_dev *dev, on_hca_fail: if (ah->type == MTHCA_AH_PCI_POOL) { ah->av = pci_pool_alloc(dev->av_table.pool, - GFP_ATOMIC, &ah->avdma); + SLAB_ATOMIC, &ah->avdma); if (!ah->av) return -ENOMEM; diff --git a/trunk/drivers/input/gameport/gameport.c b/trunk/drivers/input/gameport/gameport.c index 79dfb4b25c97..a0af97efe6ac 100644 --- a/trunk/drivers/input/gameport/gameport.c +++ b/trunk/drivers/input/gameport/gameport.c @@ -23,7 +23,6 @@ #include #include /* HZ */ #include -#include /*#include */ diff --git a/trunk/drivers/input/misc/hp_sdc_rtc.c b/trunk/drivers/input/misc/hp_sdc_rtc.c index 31d5a13bfd6b..ab4da79ee560 100644 --- a/trunk/drivers/input/misc/hp_sdc_rtc.c +++ b/trunk/drivers/input/misc/hp_sdc_rtc.c @@ -695,9 +695,7 @@ static int __init hp_sdc_rtc_init(void) if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) return ret; - if (misc_register(&hp_sdc_rtc_dev) != 0) - printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n"); - + misc_register(&hp_sdc_rtc_dev); create_proc_read_entry ("driver/rtc", 0, NULL, hp_sdc_rtc_read_proc, NULL); diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c index 5f1d4032fd57..211943f85cb6 100644 --- a/trunk/drivers/input/serio/serio.c +++ b/trunk/drivers/input/serio/serio.c @@ -35,7 +35,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Serio abstraction core"); diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 0517c7387d67..f56d6a0f0624 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -189,7 +189,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) { struct spi_device *spi = to_spi_device(dev); struct ads7846 *ts = dev_get_drvdata(dev); - struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); + struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); int status; int sample; int i; diff --git a/trunk/drivers/isdn/gigaset/bas-gigaset.c b/trunk/drivers/isdn/gigaset/bas-gigaset.c index 63b629b1cdb2..0c937325a1b3 100644 --- a/trunk/drivers/isdn/gigaset/bas-gigaset.c +++ b/trunk/drivers/isdn/gigaset/bas-gigaset.c @@ -572,7 +572,7 @@ static int atread_submit(struct cardstate *cs, int timeout) ucs->rcvbuf, ucs->rcvbuf_size, read_ctrl_callback, cs->inbuf); - if ((ret = usb_submit_urb(ucs->urb_cmd_in, GFP_ATOMIC)) != 0) { + if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { update_basstate(ucs, 0, BS_ATRDPEND); dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", get_usb_rcmsg(ret)); @@ -747,7 +747,7 @@ static void read_int_callback(struct urb *urb) check_pending(ucs); resubmit: - rc = usb_submit_urb(urb, GFP_ATOMIC); + rc = usb_submit_urb(urb, SLAB_ATOMIC); if (unlikely(rc != 0 && rc != -ENODEV)) { dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", get_usb_rcmsg(rc)); @@ -807,7 +807,7 @@ static void read_iso_callback(struct urb *urb) urb->number_of_packets = BAS_NUMFRAMES; gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", __func__); - rc = usb_submit_urb(urb, GFP_ATOMIC); + rc = usb_submit_urb(urb, SLAB_ATOMIC); if (unlikely(rc != 0 && rc != -ENODEV)) { dev_err(bcs->cs->dev, "could not resubmit isochronous read " @@ -900,7 +900,7 @@ static int starturbs(struct bc_state *bcs) } dump_urb(DEBUG_ISO, "Initial isoc read", urb); - if ((rc = usb_submit_urb(urb, GFP_ATOMIC)) != 0) + if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) goto error; } @@ -935,7 +935,7 @@ static int starturbs(struct bc_state *bcs) /* submit two URBs, keep third one */ for (k = 0; k < 2; ++k) { dump_urb(DEBUG_ISO, "Initial isoc write", urb); - rc = usb_submit_urb(ubc->isoouturbs[k].urb, GFP_ATOMIC); + rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); if (rc != 0) goto error; } @@ -1042,7 +1042,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) return 0; /* no data to send */ urb->number_of_packets = nframe; - rc = usb_submit_urb(urb, GFP_ATOMIC); + rc = usb_submit_urb(urb, SLAB_ATOMIC); if (unlikely(rc)) { if (rc == -ENODEV) /* device removed - give up silently */ @@ -1341,7 +1341,7 @@ static void read_iso_tasklet(unsigned long data) urb->dev = bcs->cs->hw.bas->udev; urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = BAS_NUMFRAMES; - rc = usb_submit_urb(urb, GFP_ATOMIC); + rc = usb_submit_urb(urb, SLAB_ATOMIC); if (unlikely(rc != 0 && rc != -ENODEV)) { dev_err(cs->dev, "could not resubmit isochronous read URB: %s\n", @@ -1458,7 +1458,7 @@ static void write_ctrl_callback(struct urb *urb) ucs->retry_ctrl); /* urb->dev is clobbered by USB subsystem */ urb->dev = ucs->udev; - rc = usb_submit_urb(urb, GFP_ATOMIC); + rc = usb_submit_urb(urb, SLAB_ATOMIC); if (unlikely(rc)) { dev_err(&ucs->interface->dev, "could not resubmit request 0x%02x: %s\n", @@ -1517,7 +1517,7 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) (unsigned char*) &ucs->dr_ctrl, NULL, 0, write_ctrl_callback, ucs); ucs->retry_ctrl = 0; - ret = usb_submit_urb(ucs->urb_ctrl, GFP_ATOMIC); + ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC); if (unlikely(ret)) { dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", req, get_usb_rcmsg(ret)); @@ -1763,7 +1763,7 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) usb_sndctrlpipe(ucs->udev, 0), (unsigned char*) &ucs->dr_cmd_out, buf, len, write_command_callback, cs); - rc = usb_submit_urb(ucs->urb_cmd_out, GFP_ATOMIC); + rc = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC); if (unlikely(rc)) { update_basstate(ucs, 0, BS_ATWRPEND); dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", @@ -2218,21 +2218,21 @@ static int gigaset_probe(struct usb_interface *interface, * - three for the different uses of the default control pipe * - three for each isochronous pipe */ - if (!(ucs->urb_int_in = usb_alloc_urb(0, GFP_KERNEL)) || - !(ucs->urb_cmd_in = usb_alloc_urb(0, GFP_KERNEL)) || - !(ucs->urb_cmd_out = usb_alloc_urb(0, GFP_KERNEL)) || - !(ucs->urb_ctrl = usb_alloc_urb(0, GFP_KERNEL))) + if (!(ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL)) || + !(ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL)) || + !(ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL)) || + !(ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL))) goto allocerr; for (j = 0; j < 2; ++j) { ubc = cs->bcs[j].hw.bas; for (i = 0; i < BAS_OUTURBS; ++i) if (!(ubc->isoouturbs[i].urb = - usb_alloc_urb(BAS_NUMFRAMES, GFP_KERNEL))) + usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL))) goto allocerr; for (i = 0; i < BAS_INURBS; ++i) if (!(ubc->isoinurbs[i] = - usb_alloc_urb(BAS_NUMFRAMES, GFP_KERNEL))) + usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL))) goto allocerr; } @@ -2246,7 +2246,7 @@ static int gigaset_probe(struct usb_interface *interface, (endpoint->bEndpointAddress) & 0x0f), ucs->int_in_buf, 3, read_int_callback, cs, endpoint->bInterval); - if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) { + if ((rc = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL)) != 0) { dev_err(cs->dev, "could not submit interrupt URB: %s\n", get_usb_rcmsg(rc)); goto error; diff --git a/trunk/drivers/isdn/gigaset/usb-gigaset.c b/trunk/drivers/isdn/gigaset/usb-gigaset.c index 04f2ad7ba8b0..5ebf49ac9b23 100644 --- a/trunk/drivers/isdn/gigaset/usb-gigaset.c +++ b/trunk/drivers/isdn/gigaset/usb-gigaset.c @@ -410,7 +410,7 @@ static void gigaset_read_int_callback(struct urb *urb) if (resubmit) { spin_lock_irqsave(&cs->lock, flags); - r = cs->connected ? usb_submit_urb(urb, GFP_ATOMIC) : -ENODEV; + r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; spin_unlock_irqrestore(&cs->lock, flags); if (r) dev_err(cs->dev, "error %d when resubmitting urb.\n", @@ -486,7 +486,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) atomic_set(&ucs->busy, 1); spin_lock_irqsave(&cs->lock, flags); - status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV; + status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC) : -ENODEV; spin_unlock_irqrestore(&cs->lock, flags); if (status) { @@ -664,7 +664,7 @@ static int write_modem(struct cardstate *cs) ucs->bulk_out_endpointAddr & 0x0f), ucs->bulk_out_buffer, count, gigaset_write_bulk_callback, cs); - ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC); + ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); } else { ret = -ENODEV; } @@ -763,7 +763,7 @@ static int gigaset_probe(struct usb_interface *interface, goto error; } - ucs->bulk_out_urb = usb_alloc_urb(0, GFP_KERNEL); + ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); if (!ucs->bulk_out_urb) { dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n"); retval = -ENOMEM; @@ -774,7 +774,7 @@ static int gigaset_probe(struct usb_interface *interface, atomic_set(&ucs->busy, 0); - ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL); + ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); if (!ucs->read_urb) { dev_err(cs->dev, "No free urbs available\n"); retval = -ENOMEM; @@ -797,7 +797,7 @@ static int gigaset_probe(struct usb_interface *interface, gigaset_read_int_callback, cs->inbuf + 0, endpoint->bInterval); - retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL); + retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); if (retval) { dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval); goto error; diff --git a/trunk/drivers/isdn/hisax/isdnhdlc.h b/trunk/drivers/isdn/hisax/isdnhdlc.h index 5655b5f9c48e..269315988dc8 100644 --- a/trunk/drivers/isdn/hisax/isdnhdlc.h +++ b/trunk/drivers/isdn/hisax/isdnhdlc.h @@ -41,10 +41,10 @@ struct isdnhdlc_vars { unsigned char shift_reg; unsigned char ffvalue; - unsigned int data_received:1; // set if transferring data - unsigned int dchannel:1; // set if D channel (send idle instead of flags) - unsigned int do_adapt56:1; // set if 56K adaptation - unsigned int do_closing:1; // set if in closing phase (need to send CRC + flag + int data_received:1; // set if transferring data + int dchannel:1; // set if D channel (send idle instead of flags) + int do_adapt56:1; // set if 56K adaptation + int do_closing:1; // set if in closing phase (need to send CRC + flag }; diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 176142c61492..9c39b98d5a5b 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -76,12 +76,6 @@ config LEDS_NET48XX This option enables support for the Soekris net4801 and net4826 error LED. -config LEDS_WRAP - tristate "LED Support for the WRAP series LEDs" - depends on LEDS_CLASS && SCx200_GPIO - help - This option enables support for the PCEngines WRAP programmable LEDs. - comment "LED Triggers" config LEDS_TRIGGERS diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile index 500de3dc962a..6aa2aed7539d 100644 --- a/trunk/drivers/leds/Makefile +++ b/trunk/drivers/leds/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o -obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o # LED Triggers obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o diff --git a/trunk/drivers/leds/leds-wrap.c b/trunk/drivers/leds/leds-wrap.c deleted file mode 100644 index 27fb2d8e991f..000000000000 --- a/trunk/drivers/leds/leds-wrap.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * LEDs driver for PCEngines WRAP - * - * Copyright (C) 2006 Kristian Kielhofner - * - * Based on leds-net48xx.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DRVNAME "wrap-led" -#define WRAP_ERROR_LED_GPIO 3 -#define WRAP_EXTRA_LED_GPIO 18 - -static struct platform_device *pdev; - -static void wrap_error_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value) - scx200_gpio_set_low(WRAP_ERROR_LED_GPIO); - else - scx200_gpio_set_high(WRAP_ERROR_LED_GPIO); -} - -static void wrap_extra_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value) - scx200_gpio_set_low(WRAP_EXTRA_LED_GPIO); - else - scx200_gpio_set_high(WRAP_EXTRA_LED_GPIO); -} - -static struct led_classdev wrap_error_led = { - .name = "wrap:error", - .brightness_set = wrap_error_led_set, -}; - -static struct led_classdev wrap_extra_led = { - .name = "wrap:extra", - .brightness_set = wrap_extra_led_set, -}; - -#ifdef CONFIG_PM -static int wrap_led_suspend(struct platform_device *dev, - pm_message_t state) -{ - led_classdev_suspend(&wrap_error_led); - led_classdev_suspend(&wrap_extra_led); - return 0; -} - -static int wrap_led_resume(struct platform_device *dev) -{ - led_classdev_resume(&wrap_error_led); - led_classdev_resume(&wrap_extra_led); - return 0; -} -#else -#define wrap_led_suspend NULL -#define wrap_led_resume NULL -#endif - -static int wrap_led_probe(struct platform_device *pdev) -{ - int ret; - - ret = led_classdev_register(&pdev->dev, &wrap_error_led); - if (ret == 0) { - ret = led_classdev_register(&pdev->dev, &wrap_extra_led); - if (ret < 0) - led_classdev_unregister(&wrap_error_led); - } - return ret; -} - -static int wrap_led_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&wrap_error_led); - led_classdev_unregister(&wrap_extra_led); - return 0; -} - -static struct platform_driver wrap_led_driver = { - .probe = wrap_led_probe, - .remove = wrap_led_remove, - .suspend = wrap_led_suspend, - .resume = wrap_led_resume, - .driver = { - .name = DRVNAME, - .owner = THIS_MODULE, - }, -}; - -static int __init wrap_led_init(void) -{ - int ret; - - if (!scx200_gpio_present()) { - ret = -ENODEV; - goto out; - } - - ret = platform_driver_register(&wrap_led_driver); - if (ret < 0) - goto out; - - pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); - if (IS_ERR(pdev)) { - ret = PTR_ERR(pdev); - platform_driver_unregister(&wrap_led_driver); - goto out; - } - -out: - return ret; -} - -static void __exit wrap_led_exit(void) -{ - platform_device_unregister(pdev); - platform_driver_unregister(&wrap_led_driver); -} - -module_init(wrap_led_init); -module_exit(wrap_led_exit); - -MODULE_AUTHOR("Kristian Kielhofner "); -MODULE_DESCRIPTION("PCEngines WRAP LED driver"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/macintosh/apm_emu.c b/trunk/drivers/macintosh/apm_emu.c index 8862a83b8d84..1293876a2ebd 100644 --- a/trunk/drivers/macintosh/apm_emu.c +++ b/trunk/drivers/macintosh/apm_emu.c @@ -529,8 +529,7 @@ static int __init apm_emu_init(void) if (apm_proc) apm_proc->owner = THIS_MODULE; - if (misc_register(&apm_device) != 0) - printk(KERN_INFO "Could not create misc. device for apm\n"); + misc_register(&apm_device); pmu_register_sleep_notifier(&apm_sleep_notifier); diff --git a/trunk/drivers/macintosh/therm_adt746x.c b/trunk/drivers/macintosh/therm_adt746x.c index 3d3bf1643e73..13b953ae8ebc 100644 --- a/trunk/drivers/macintosh/therm_adt746x.c +++ b/trunk/drivers/macintosh/therm_adt746x.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/macintosh/via-pmu.c b/trunk/drivers/macintosh/via-pmu.c index c8558d4ed506..e63ea1c1f3c1 100644 --- a/trunk/drivers/macintosh/via-pmu.c +++ b/trunk/drivers/macintosh/via-pmu.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/macintosh/windfarm_core.c b/trunk/drivers/macintosh/windfarm_core.c index e947af982f93..ab3faa702d58 100644 --- a/trunk/drivers/macintosh/windfarm_core.c +++ b/trunk/drivers/macintosh/windfarm_core.c @@ -34,7 +34,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index c7bee4f2eedb..ed2d4ef27fd8 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -101,7 +101,7 @@ struct crypt_config { #define MIN_POOL_PAGES 32 #define MIN_BIO_PAGES 8 -static struct kmem_cache *_crypt_io_pool; +static kmem_cache_t *_crypt_io_pool; /* * Different IV generation algorithms: diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index cf8bf052138e..e77ee6fd1044 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -101,7 +101,7 @@ typedef int (*action_fn) (struct pgpath *pgpath); #define MIN_IOS 256 /* Mempool size */ -static struct kmem_cache *_mpio_cache; +static kmem_cache_t *_mpio_cache; struct workqueue_struct *kmultipathd; static void process_queued_ios(struct work_struct *work); diff --git a/trunk/drivers/md/dm-snap.c b/trunk/drivers/md/dm-snap.c index b0ce2ce82278..91c7aa1fed0e 100644 --- a/trunk/drivers/md/dm-snap.c +++ b/trunk/drivers/md/dm-snap.c @@ -88,8 +88,8 @@ struct pending_exception { * Hash table mapping origin volumes to lists of snapshots and * a lock to protect it */ -static struct kmem_cache *exception_cache; -static struct kmem_cache *pending_cache; +static kmem_cache_t *exception_cache; +static kmem_cache_t *pending_cache; static mempool_t *pending_pool; /* @@ -228,7 +228,7 @@ static int init_exception_table(struct exception_table *et, uint32_t size) return 0; } -static void exit_exception_table(struct exception_table *et, struct kmem_cache *mem) +static void exit_exception_table(struct exception_table *et, kmem_cache_t *mem) { struct list_head *slot; struct exception *ex, *next; diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 7ec1b112a6d5..fc4f743f3b53 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -121,8 +121,8 @@ struct mapped_device { }; #define MIN_IOS 256 -static struct kmem_cache *_io_cache; -static struct kmem_cache *_tio_cache; +static kmem_cache_t *_io_cache; +static kmem_cache_t *_tio_cache; static int __init local_init(void) { diff --git a/trunk/drivers/md/kcopyd.c b/trunk/drivers/md/kcopyd.c index b46f6c575f7e..b3c01496c737 100644 --- a/trunk/drivers/md/kcopyd.c +++ b/trunk/drivers/md/kcopyd.c @@ -203,7 +203,7 @@ struct kcopyd_job { /* FIXME: this should scale with the number of pages */ #define MIN_JOBS 512 -static struct kmem_cache *_job_cache; +static kmem_cache_t *_job_cache; static mempool_t *_job_pool; /* diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 6c4345bde07e..8cbf9c9df1c3 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -39,10 +39,10 @@ #include #include #include /* for invalidate_bdev */ +#include #include #include #include -#include #include diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 52914d5cec76..69c3e201fa3b 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -348,7 +348,7 @@ static int grow_one_stripe(raid5_conf_t *conf) static int grow_stripes(raid5_conf_t *conf, int num) { - struct kmem_cache *sc; + kmem_cache_t *sc; int devs = conf->raid_disks; sprintf(conf->cache_name[0], "raid5/%s", mdname(conf->mddev)); @@ -397,7 +397,7 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) LIST_HEAD(newstripes); struct disk_info *ndisks; int err = 0; - struct kmem_cache *sc; + kmem_cache_t *sc; int i; if (newsize <= conf->pool_size) diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index 9123147e376f..206c13e47a06 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -287,7 +287,7 @@ static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2) int i; cinergyt2->streambuf = usb_buffer_alloc(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, - GFP_KERNEL, &cinergyt2->streambuf_dmahandle); + SLAB_KERNEL, &cinergyt2->streambuf_dmahandle); if (!cinergyt2->streambuf) { dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n"); return -ENOMEM; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index e85972222ab4..a2ab2eebfc68 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/media/dvb/dvb-usb/usb-urb.c b/trunk/drivers/media/dvb/dvb-usb/usb-urb.c index 397f51a7b2ad..78035ee824ca 100644 --- a/trunk/drivers/media/dvb/dvb-usb/usb-urb.c +++ b/trunk/drivers/media/dvb/dvb-usb/usb-urb.c @@ -116,7 +116,7 @@ static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { deb_mem("allocating buffer %d\n",stream->buf_num); if (( stream->buf_list[stream->buf_num] = - usb_buffer_alloc(stream->udev, size, GFP_ATOMIC, + usb_buffer_alloc(stream->udev, size, SLAB_ATOMIC, &stream->dma_addr[stream->buf_num]) ) == NULL) { deb_mem("not enough memory for urb-buffer allocation.\n"); usb_free_stream_buffers(stream); diff --git a/trunk/drivers/media/dvb/frontends/l64781.c b/trunk/drivers/media/dvb/frontends/l64781.c index 1aeacb1c4af7..f3bc82e44a28 100644 --- a/trunk/drivers/media/dvb/frontends/l64781.c +++ b/trunk/drivers/media/dvb/frontends/l64781.c @@ -36,7 +36,7 @@ struct l64781_state { struct dvb_frontend frontend; /* private demodulator data */ - unsigned int first:1; + int first:1; }; #define dprintk(args...) \ diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 10b121ada833..8135f3e76aeb 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1244,7 +1244,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) return -ENOMEM; } dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE, - GFP_ATOMIC, &dec->irq_dma_handle); + SLAB_ATOMIC, &dec->irq_dma_handle); if(!dec->irq_buffer) { return -ENOMEM; } diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig index 920b63f8cf05..6d96b17a7f81 100644 --- a/trunk/drivers/media/radio/Kconfig +++ b/trunk/drivers/media/radio/Kconfig @@ -173,6 +173,38 @@ config RADIO_MAESTRO To compile this driver as a module, choose M here: the module will be called radio-maestro. +config RADIO_MIROPCM20 + tristate "miroSOUND PCM20 radio" + depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER + ---help--- + Choose Y here if you have this FM radio card. You also need to say Y + to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound") + for this to work. + + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux API. Information on + this API and pointers to "v4l" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called miropcm20. + +config RADIO_MIROPCM20_RDS + tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)" + depends on RADIO_MIROPCM20 && EXPERIMENTAL + ---help--- + Choose Y here if you want to see RDS/RBDS information like + RadioText, Programme Service name, Clock Time and date, Programme + Type and Traffic Announcement/Programme identification. + + It's not possible to read the raw RDS packets from the device, so + the driver cant provide an V4L interface for this. But the + availability of RDS is reported over V4L by the basic driver + already. Here RDS can be read from files in /dev/v4l/rds. + + To compile this driver as a module, choose M here: the + module will be called miropcm20-rds. + config RADIO_SF16FMI tristate "SF16FMI Radio" depends on ISA && VIDEO_V4L2 diff --git a/trunk/drivers/media/video/msp3400-driver.c b/trunk/drivers/media/video/msp3400-driver.c index e1b56dc13c3f..cf43df3fe708 100644 --- a/trunk/drivers/media/video/msp3400-driver.c +++ b/trunk/drivers/media/video/msp3400-driver.c @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include "msp3400-driver.h" /* ---------------------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/tvaudio.c b/trunk/drivers/media/video/tvaudio.c index d506dfaa45a9..fcaef4bf8289 100644 --- a/trunk/drivers/media/video/tvaudio.c +++ b/trunk/drivers/media/video/tvaudio.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/media/video/video-buf-dvb.c b/trunk/drivers/media/video/video-buf-dvb.c index fcc5467e7636..f53edf1923b7 100644 --- a/trunk/drivers/media/video/video-buf-dvb.c +++ b/trunk/drivers/media/video/video-buf-dvb.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 9986de5cb3d6..3c8dc72dc8e9 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -36,7 +36,6 @@ #include #include #include -#include /* Wake up at about 30 fps */ #define WAKE_NUMERATOR 30 diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 6e068cf1049b..051b7c5b8f03 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -347,7 +347,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_interrupt - MPT adapter (IOC) specific interrupt handler. * @irq: irq number (not used) * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure @@ -387,16 +387,14 @@ mpt_interrupt(int irq, void *bus_id) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mpt_base_reply - MPT base driver's callback routine +/* + * mpt_base_reply - MPT base driver's callback routine; all base driver + * "internal" request/reply processing is routed here. + * Currently used for EventNotification and EventAck handling. * @ioc: Pointer to MPT_ADAPTER structure * @mf: Pointer to original MPT request frame * @reply: Pointer to MPT reply frame (NULL if TurboReply) * - * MPT base driver's callback routine; all base driver - * "internal" request/reply processing is routed here. - * Currently used for EventNotification and EventAck handling. - * * Returns 1 indicating original alloc'd request frame ptr * should be freed, or 0 if it shouldn't. */ @@ -532,7 +530,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value) * * This routine is called by a protocol-specific driver (SCSI host, - * LAN, SCSI target) to register its reply callback routine. Each + * LAN, SCSI target) to register it's reply callback routine. Each * protocol-specific driver must do this before it will be able to * use any IOC resources, such as obtaining request frames. * @@ -574,7 +572,7 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) * mpt_deregister - Deregister a protocol drivers resources. * @cb_idx: previously registered callback handle * - * Each protocol-specific driver should call this routine when its + * Each protocol-specific driver should call this routine when it's * module is unloaded. */ void @@ -619,7 +617,7 @@ mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc) * * Each protocol-specific driver should call this routine * when it does not (or can no longer) handle events, - * or when its module is unloaded. + * or when it's module is unloaded. */ void mpt_event_deregister(int cb_idx) @@ -658,7 +656,7 @@ mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func) * * Each protocol-specific driver should call this routine * when it does not (or can no longer) handle IOC reset handling, - * or when its module is unloaded. + * or when it's module is unloaded. */ void mpt_reset_deregister(int cb_idx) @@ -672,8 +670,6 @@ mpt_reset_deregister(int cb_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mpt_device_driver_register - Register device driver hooks - * @dd_cbfunc: driver callbacks struct - * @cb_idx: MPT protocol driver index */ int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) @@ -700,7 +696,6 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mpt_device_driver_deregister - DeRegister device driver hooks - * @cb_idx: MPT protocol driver index */ void mpt_device_driver_deregister(int cb_idx) @@ -892,7 +887,8 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_send_handshake_request - Send MPT request via doorbell handshake method. + * mpt_send_handshake_request - Send MPT request via doorbell + * handshake method. * @handle: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @reqBytes: Size of the request in bytes @@ -985,13 +981,10 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_host_page_access_control - control the IOC's Host Page Buffer access + * mpt_host_page_access_control - provides mechanism for the host + * driver to control the IOC's Host Page Buffer access. * @ioc: Pointer to MPT adapter structure * @access_control_value: define bits below - * @sleepFlag: Specifies whether the process can sleep - * - * Provides mechanism for the host driver to control the IOC's - * Host Page Buffer access. * * Access Control Value - bits[15:12] * 0h Reserved @@ -1029,10 +1022,10 @@ mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int slee /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mpt_host_page_alloc - allocate system memory for the fw - * @ioc: Pointer to pointer to IOC adapter - * @ioc_init: Pointer to ioc init config page - * * If we already allocated memory in past, then resend the same pointer. + * ioc@: Pointer to pointer to IOC adapter + * ioc_init@: Pointer to ioc init config page + * * Returns 0 for success, non-zero for failure. */ static int @@ -1098,15 +1091,12 @@ return 0; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure. + * mpt_verify_adapter - Given a unique IOC identifier, set pointer to + * the associated MPT adapter structure. * @iocid: IOC unique identifier (integer) * @iocpp: Pointer to pointer to IOC adapter * - * Given a unique IOC identifier, set pointer to the associated MPT - * adapter structure. - * - * Returns iocid and sets iocpp if iocid is found. - * Returns -1 if iocid is not found. + * Returns iocid and sets iocpp. */ int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) @@ -1125,10 +1115,9 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_attach - Install a PCI intelligent MPT adapter. * @pdev: Pointer to pci_dev structure - * @id: PCI device ID information * * This routine performs all the steps necessary to bring the IOC of * a MPT adapter to a OPERATIONAL state. This includes registering @@ -1428,9 +1417,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_detach - Remove a PCI intelligent MPT adapter. * @pdev: Pointer to pci_dev structure + * */ void @@ -1476,10 +1466,10 @@ mpt_detach(struct pci_dev *pdev) */ #ifdef CONFIG_PM /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_suspend - Fusion MPT base driver suspend routine. - * @pdev: Pointer to pci_dev structure - * @state: new state to enter + * + * */ int mpt_suspend(struct pci_dev *pdev, pm_message_t state) @@ -1515,9 +1505,10 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_resume - Fusion MPT base driver resume routine. - * @pdev: Pointer to pci_dev structure + * + * */ int mpt_resume(struct pci_dev *pdev) @@ -1575,7 +1566,7 @@ mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_do_ioc_recovery - Initialize or recover MPT adapter. * @ioc: Pointer to MPT adapter structure * @reason: Event word / reason @@ -1901,15 +1892,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mpt_detect_bound_ports - Search for matching PCI bus/dev_function +/* + * mpt_detect_bound_ports - Search for PCI bus/dev_function + * which matches PCI bus/dev_function (+/-1) for newly discovered 929, + * 929X, 1030 or 1035. * @ioc: Pointer to MPT adapter structure * @pdev: Pointer to (struct pci_dev) structure * - * Search for PCI bus/dev_function which matches - * PCI bus/dev_function (+/-1) for newly discovered 929, - * 929X, 1030 or 1035. - * * If match on PCI dev_function +/-1 is found, bind the two MPT adapters * using alt_ioc pointer fields in their %MPT_ADAPTER structures. */ @@ -1956,9 +1945,9 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_adapter_disable - Disable misbehaving MPT adapter. - * @ioc: Pointer to MPT adapter structure + * @this: Pointer to MPT adapter structure */ static void mpt_adapter_disable(MPT_ADAPTER *ioc) @@ -2057,8 +2046,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mpt_adapter_dispose - Free all resources associated with an MPT adapter +/* + * mpt_adapter_dispose - Free all resources associated with a MPT + * adapter. * @ioc: Pointer to MPT adapter structure * * This routine unregisters h/w resources and frees all alloc'd memory @@ -2109,8 +2099,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * MptDisplayIocCapabilities - Disply IOC's capabilities. +/* + * MptDisplayIocCapabilities - Disply IOC's capacilities. * @ioc: Pointer to MPT adapter structure */ static void @@ -2152,7 +2142,7 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * MakeIocReady - Get IOC to a READY state, using KickStart if needed. * @ioc: Pointer to MPT_ADAPTER structure * @force: Force hard KickStart of IOC @@ -2289,7 +2279,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_GetIocState - Get the current state of a MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @cooked: Request raw or cooked IOC state @@ -2314,7 +2304,7 @@ mpt_GetIocState(MPT_ADAPTER *ioc, int cooked) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * GetIocFacts - Send IOCFacts request to MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @sleepFlag: Specifies whether the process can sleep @@ -2488,7 +2478,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * GetPortFacts - Send PortFacts request to MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @portnum: Port number @@ -2555,7 +2545,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * SendIocInit - Send IOCInit request to MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @sleepFlag: Specifies whether the process can sleep @@ -2640,7 +2630,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) } /* No need to byte swap the multibyte fields in the reply - * since we don't even look at its contents. + * since we don't even look at it's contents. */ dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n", @@ -2682,7 +2672,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * SendPortEnable - Send PortEnable request to MPT adapter port. * @ioc: Pointer to MPT_ADAPTER structure * @portnum: Port number to enable @@ -2733,13 +2723,9 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) return rc; } -/** - * mpt_alloc_fw_memory - allocate firmware memory - * @ioc: Pointer to MPT_ADAPTER structure - * @size: total FW bytes - * - * If memory has already been allocated, the same (cached) value - * is returned. +/* + * ioc: Pointer to MPT_ADAPTER structure + * size - total FW bytes */ void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) @@ -2756,12 +2742,9 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) ioc->alloc_total += size; } } -/** - * mpt_free_fw_memory - free firmware memory - * @ioc: Pointer to MPT_ADAPTER structure - * - * If alt_img is NULL, delete from ioc structure. - * Else, delete a secondary image in same format. +/* + * If alt_img is NULL, delete from ioc structure. + * Else, delete a secondary image in same format. */ void mpt_free_fw_memory(MPT_ADAPTER *ioc) @@ -2780,7 +2763,7 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port. * @ioc: Pointer to MPT_ADAPTER structure * @sleepFlag: Specifies whether the process can sleep @@ -2882,10 +2865,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_downloadboot - DownloadBoot code * @ioc: Pointer to MPT_ADAPTER structure - * @pFwHeader: Pointer to firmware header info + * @flag: Specify which part of IOC memory is to be uploaded. * @sleepFlag: Specifies whether the process can sleep * * FwDownloadBoot requires Programmed IO access. @@ -3088,7 +3071,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * KickStart - Perform hard reset of MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @force: Force hard reset @@ -3162,12 +3145,12 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_diag_reset - Perform hard reset of the adapter. * @ioc: Pointer to MPT_ADAPTER structure * @ignore: Set if to honor and clear to ignore * the reset history bit - * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread, + * @sleepflag: CAN_SLEEP if called in a non-interrupt thread, * else set to NO_SLEEP (use mdelay instead) * * This routine places the adapter in diagnostic mode via the @@ -3453,12 +3436,11 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * SendIocReset - Send IOCReset request to MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @reset_type: reset type, expected values are * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET - * @sleepFlag: Specifies whether the process can sleep * * Send IOCReset request to the MPT adapter. * @@ -3512,12 +3494,11 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * initChainBuffers - Allocate memory for and initialize chain buffers - * @ioc: Pointer to MPT_ADAPTER structure - * - * Allocates memory for and initializes chain buffers, - * chain buffer control arrays and spinlock. +/* + * initChainBuffers - Allocate memory for and initialize + * chain buffers, chain buffer control arrays and spinlock. + * @hd: Pointer to MPT_SCSI_HOST structure + * @init: If set, initialize the spin lock. */ static int initChainBuffers(MPT_ADAPTER *ioc) @@ -3613,7 +3594,7 @@ initChainBuffers(MPT_ADAPTER *ioc) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * PrimeIocFifos - Initialize IOC request and reply FIFOs. * @ioc: Pointer to MPT_ADAPTER structure * @@ -3910,15 +3891,15 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge +/* + * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit + * in it's IntStatus register. * @ioc: Pointer to MPT_ADAPTER structure * @howlong: How long to wait (in seconds) * @sleepFlag: Specifies whether the process can sleep * * This routine waits (up to ~2 seconds max) for IOC doorbell - * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS - * bit in its IntStatus register being clear. + * handshake ACKnowledge. * * Returns a negative value on failure, else wait loop count. */ @@ -3961,14 +3942,14 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit +/* + * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit + * in it's IntStatus register. * @ioc: Pointer to MPT_ADAPTER structure * @howlong: How long to wait (in seconds) * @sleepFlag: Specifies whether the process can sleep * - * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt - * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register. + * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt. * * Returns a negative value on failure, else wait loop count. */ @@ -4010,8 +3991,8 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * WaitForDoorbellReply - Wait for and capture an IOC handshake reply. +/* + * WaitForDoorbellReply - Wait for and capture a IOC handshake reply. * @ioc: Pointer to MPT_ADAPTER structure * @howlong: How long to wait (in seconds) * @sleepFlag: Specifies whether the process can sleep @@ -4096,7 +4077,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * GetLanConfigPages - Fetch LANConfig pages. * @ioc: Pointer to MPT_ADAPTER structure * @@ -4207,9 +4188,12 @@ GetLanConfigPages(MPT_ADAPTER *ioc) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table +/* + * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table * @ioc: Pointer to MPT_ADAPTER structure + * @sas_address: 64bit SAS Address for operation. + * @target_id: specified target for operation + * @bus: specified bus for operation * @persist_opcode: see below * * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for @@ -4218,7 +4202,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc) * * NOTE: Don't use not this function during interrupt time. * - * Returns 0 for success, non-zero error + * Returns: 0 for success, non-zero error */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -4415,7 +4399,7 @@ mptbase_raid_process_event_data(MPT_ADAPTER *ioc, } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * GetIoUnitPage2 - Retrieve BIOS version and boot order information. * @ioc: Pointer to MPT_ADAPTER structure * @@ -4473,8 +4457,7 @@ GetIoUnitPage2(MPT_ADAPTER *ioc) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2 +/* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2 * @ioc: Pointer to a Adapter Strucutre * @portnum: IOC port number * @@ -4661,8 +4644,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mpt_readScsiDevicePageHeaders - save version and length of SDP1 +/* mpt_readScsiDevicePageHeaders - save version and length of SDP1 * @ioc: Pointer to a Adapter Strucutre * @portnum: IOC port number * @@ -5014,8 +4996,9 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * SendEventNotification - Send EventNotification (on or off) request to adapter +/* + * SendEventNotification - Send EventNotification (on or off) request + * to MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @EvSwitch: Event switch flags */ @@ -5079,8 +5062,8 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mpt_config - Generic function to issue config message - * @ioc: Pointer to an adapter structure - * @pCfg: Pointer to a configuration structure. Struct contains + * @ioc - Pointer to an adapter structure + * @cfg - Pointer to a configuration structure. Struct contains * action, page address, direction, physical address * and pointer to a configuration page header * Page header is updated. @@ -5205,8 +5188,8 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mpt_timer_expired - Callback for timer process. +/* + * mpt_timer_expired - Call back for timer process. * Used only internal config functionality. * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long */ @@ -5231,12 +5214,12 @@ mpt_timer_expired(unsigned long data) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_ioc_reset - Base cleanup for hard reset * @ioc: Pointer to the adapter structure * @reset_phase: Indicates pre- or post-reset functionality * - * Remark: Frees resources with internally generated commands. + * Remark: Free's resources with internally generated commands. */ static int mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) @@ -5288,7 +5271,7 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff... */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries. * * Returns 0 for success, non-zero for failure. @@ -5314,7 +5297,7 @@ procmpt_create(void) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries. * * Returns 0 for success, non-zero for failure. @@ -5328,16 +5311,16 @@ procmpt_destroy(void) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * procmpt_summary_read - Handle read request of a summary file +/* + * procmpt_summary_read - Handle read request from /proc/mpt/summary + * or from /proc/mpt/iocN/summary. * @buf: Pointer to area to write information * @start: Pointer to start pointer * @offset: Offset to start writing - * @request: Amount of read data requested + * @request: * @eof: Pointer to EOF integer * @data: Pointer * - * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary. * Returns number of characters written to process performing the read. */ static int @@ -5372,12 +5355,12 @@ procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eo } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * procmpt_version_read - Handle read request from /proc/mpt/version. * @buf: Pointer to area to write information * @start: Pointer to start pointer * @offset: Offset to start writing - * @request: Amount of read data requested + * @request: * @eof: Pointer to EOF integer * @data: Pointer * @@ -5428,12 +5411,12 @@ procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eo } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info. * @buf: Pointer to area to write information * @start: Pointer to start pointer * @offset: Offset to start writing - * @request: Amount of read data requested + * @request: * @eof: Pointer to EOF integer * @data: Pointer * @@ -5594,17 +5577,16 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_HardResetHandler - Generic reset handler + * mpt_HardResetHandler - Generic reset handler, issue SCSI Task + * Management call based on input arg values. If TaskMgmt fails, + * return associated SCSI request. * @ioc: Pointer to MPT_ADAPTER structure * @sleepFlag: Indicates if sleep or schedule must be called. * - * Issues SCSI Task Management call based on input arg values. - * If TaskMgmt fails, returns associated SCSI request. - * * Remark: _HardResetHandler can be invoked from an interrupt thread (timer) * or a non-interrupt thread. In the former, must not call schedule(). * - * Note: A return of -1 is a FATAL error case, as it means a + * Remark: A return of -1 is a FATAL error case, as it means a * FW reload/initialization failed. * * Returns 0 for SUCCESS or -1 if FAILED. @@ -5953,14 +5935,13 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * ProcessEventNotification - Route EventNotificationReply to all event handlers +/* + * ProcessEventNotification - Route a received EventNotificationReply to + * all currently regeistered event handlers. * @ioc: Pointer to MPT_ADAPTER structure * @pEventReply: Pointer to EventNotification reply frame * @evHandlers: Pointer to integer, number of event handlers * - * Routes a received EventNotificationReply to all currently registered - * event handlers. * Returns sum of event handlers return values. */ static int @@ -6075,7 +6056,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_fc_log_info - Log information returned from Fibre Channel IOC. * @ioc: Pointer to MPT_ADAPTER structure * @log_info: U32 LogInfo reply word from the IOC @@ -6096,7 +6077,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. * @ioc: Pointer to MPT_ADAPTER structure * @mr: Pointer to MPT reply frame @@ -6219,7 +6200,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) }; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_sas_log_info - Log information returned from SAS IOC. * @ioc: Pointer to MPT_ADAPTER structure * @log_info: U32 LogInfo reply word from the IOC @@ -6274,7 +6255,7 @@ union loginfo_type { } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC. * @ioc: Pointer to MPT_ADAPTER structure * @ioc_status: U32 IOCStatus word from IOC @@ -6435,7 +6416,7 @@ EXPORT_SYMBOL(mpt_free_fw_memory); EXPORT_SYMBOL(mptbase_sas_persist_operation); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * fusion_init - Fusion MPT base driver initialization routine. * * Returns 0 for success, non-zero for failure. @@ -6475,7 +6456,7 @@ fusion_init(void) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** +/* * fusion_exit - Perform driver unload cleanup. * * This routine frees all resources associated with each MPT adapter diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index ca2f9107f145..ef2b55e19910 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -1395,7 +1395,8 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer. + * mptfc_init - Register MPT adapter(s) as SCSI host(s) with + * linux scsi mid-layer. * * Returns 0 for success, non-zero for failure. */ @@ -1439,7 +1440,7 @@ mptfc_init(void) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mptfc_remove - Remove fc infrastructure for devices + * mptfc_remove - Removed fc infrastructure for devices * @pdev: Pointer to pci_dev structure * */ diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index 2c72c36b8171..30524dc54b16 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -1230,15 +1230,15 @@ mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_proc_info - Return information about MPT adapter - * @host: scsi host struct - * @buffer: if write, user data; if read, buffer for user - * @start: returns the buffer address - * @offset: if write, 0; if read, the current offset into the buffer from - * the previous read. - * @length: if write, return length; - * @func: write = 1; read = 0 * * (linux scsi_host_template.info routine) + * + * buffer: if write, user data; if read, buffer for user + * length: if write, return length; + * offset: if write, 0; if read, the current offset into the buffer from + * the previous read. + * hostno: scsi host number + * func: if write = 1; if read = 0 */ int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, @@ -1902,7 +1902,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant) + * mptscsih_host_reset - Perform a SCSI host adapter RESET! + * new_eh variant * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to * * (linux scsi_host_template.eh_host_reset_handler routine) @@ -1948,7 +1949,8 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mptscsih_tm_pending_wait - wait for pending task management request to complete + * mptscsih_tm_pending_wait - wait for pending task management request to + * complete. * @hd: Pointer to MPT host structure. * * Returns {SUCCESS,FAILED}. @@ -1980,7 +1982,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) /** * mptscsih_tm_wait_for_completion - wait for completion of TM task * @hd: Pointer to MPT host structure. - * @timeout: timeout in seconds * * Returns {SUCCESS,FAILED}. */ @@ -3428,7 +3429,8 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) /** * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. * @hd: Pointer to a SCSI HOST structure - * @vdevice: virtual target device + * @vtarget: per device private data + * @lun: lun * * Uses the ISR, but with special processing. * MUST be single-threaded. diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c index 36641da59289..f422c0d0621c 100644 --- a/trunk/drivers/message/fusion/mptspi.c +++ b/trunk/drivers/message/fusion/mptspi.c @@ -1100,7 +1100,8 @@ static struct pci_driver mptspi_driver = { /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mptspi_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer. + * mptspi_init - Register MPT adapter(s) as SCSI host(s) with + * linux scsi mid-layer. * * Returns 0 for success, non-zero for failure. */ @@ -1134,6 +1135,7 @@ mptspi_init(void) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptspi_exit - Unregisters MPT adapter(s) + * */ static void __exit mptspi_exit(void) diff --git a/trunk/drivers/message/i2o/bus-osm.c b/trunk/drivers/message/i2o/bus-osm.c index c463dc2efc09..d96c687aee93 100644 --- a/trunk/drivers/message/i2o/bus-osm.c +++ b/trunk/drivers/message/i2o/bus-osm.c @@ -56,9 +56,6 @@ static int i2o_bus_scan(struct i2o_device *dev) /** * i2o_bus_store_scan - Scan the I2O Bus Adapter * @d: device which should be scanned - * @attr: device_attribute - * @buf: output buffer - * @count: buffer size * * Returns count. */ diff --git a/trunk/drivers/message/i2o/device.c b/trunk/drivers/message/i2o/device.c index b9df143e4ff1..ee183053fa23 100644 --- a/trunk/drivers/message/i2o/device.c +++ b/trunk/drivers/message/i2o/device.c @@ -54,8 +54,8 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd, * @dev: I2O device to claim * @drv: I2O driver which wants to claim the device * - * Do the leg work to assign a device to a given OSM. If the claim succeeds, - * the owner is the primary. If the attempt fails a negative errno code + * Do the leg work to assign a device to a given OSM. If the claim succeed + * the owner of the rimary. If the attempt fails a negative errno code * is returned. On success zero is returned. */ int i2o_device_claim(struct i2o_device *dev) @@ -208,23 +208,24 @@ static struct i2o_device *i2o_device_alloc(void) /** * i2o_device_add - allocate a new I2O device and add it to the IOP - * @c: I2O controller that the device is on + * @iop: I2O controller where the device is on * @entry: LCT entry of the I2O device * * Allocate a new I2O device and initialize it with the LCT entry. The * device is appended to the device list of the controller. * - * Returns zero on success, or a -ve errno. + * Returns a pointer to the I2O device on success or negative error code + * on failure. */ -static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) +static struct i2o_device *i2o_device_add(struct i2o_controller *c, + i2o_lct_entry * entry) { struct i2o_device *i2o_dev, *tmp; - int rc; i2o_dev = i2o_device_alloc(); if (IS_ERR(i2o_dev)) { printk(KERN_ERR "i2o: unable to allocate i2o device\n"); - return PTR_ERR(i2o_dev); + return i2o_dev; } i2o_dev->lct_data = *entry; @@ -235,9 +236,7 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) i2o_dev->iop = c; i2o_dev->device.parent = &c->device; - rc = device_register(&i2o_dev->device); - if (rc) - goto err; + device_register(&i2o_dev->device); list_add_tail(&i2o_dev->list, &c->devices); @@ -271,16 +270,12 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) pr_debug("i2o: device %s added\n", i2o_dev->device.bus_id); - return 0; - -err: - kfree(i2o_dev); - return rc; + return i2o_dev; } /** * i2o_device_remove - remove an I2O device from the I2O core - * @i2o_dev: I2O device which should be released + * @dev: I2O device which should be released * * Is used on I2O controller removal or LCT modification, when the device * is removed from the system. Note that the device could still hang diff --git a/trunk/drivers/message/i2o/driver.c b/trunk/drivers/message/i2o/driver.c index 9104b65ff70f..7fc7399bd2ec 100644 --- a/trunk/drivers/message/i2o/driver.c +++ b/trunk/drivers/message/i2o/driver.c @@ -34,7 +34,9 @@ static spinlock_t i2o_drivers_lock; static struct i2o_driver **i2o_drivers; /** - * i2o_bus_match - Tell if I2O device class id matches the class ids of the I2O driver (OSM) + * i2o_bus_match - Tell if a I2O device class id match the class ids of + * the I2O driver (OSM) + * * @dev: device which should be verified * @drv: the driver to match against * @@ -246,7 +248,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) /** * i2o_driver_notify_controller_add_all - Send notify of added controller - * @c: newly added controller + * to all I2O drivers * * Send notifications to all registered drivers that a new controller was * added. @@ -265,8 +267,8 @@ void i2o_driver_notify_controller_add_all(struct i2o_controller *c) } /** - * i2o_driver_notify_controller_remove_all - Send notify of removed controller - * @c: controller that is being removed + * i2o_driver_notify_controller_remove_all - Send notify of removed + * controller to all I2O drivers * * Send notifications to all registered drivers that a controller was * removed. @@ -285,8 +287,8 @@ void i2o_driver_notify_controller_remove_all(struct i2o_controller *c) } /** - * i2o_driver_notify_device_add_all - Send notify of added device - * @i2o_dev: newly added I2O device + * i2o_driver_notify_device_add_all - Send notify of added device to all + * I2O drivers * * Send notifications to all registered drivers that a device was added. */ @@ -304,8 +306,8 @@ void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev) } /** - * i2o_driver_notify_device_remove_all - Send notify of removed device - * @i2o_dev: device that is being removed + * i2o_driver_notify_device_remove_all - Send notify of removed device to + * all I2O drivers * * Send notifications to all registered drivers that a device was removed. */ @@ -360,7 +362,7 @@ int __init i2o_driver_init(void) /** * i2o_driver_exit - clean up I2O drivers (OSMs) * - * Unregisters the I2O bus and frees driver array. + * Unregisters the I2O bus and free driver array. */ void __exit i2o_driver_exit(void) { diff --git a/trunk/drivers/message/i2o/exec-osm.c b/trunk/drivers/message/i2o/exec-osm.c index 902753b2c661..9e529d8dd5cb 100644 --- a/trunk/drivers/message/i2o/exec-osm.c +++ b/trunk/drivers/message/i2o/exec-osm.c @@ -94,8 +94,8 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void) }; /** - * i2o_exec_wait_free - Free an i2o_exec_wait struct - * @wait: I2O wait data which should be cleaned up + * i2o_exec_wait_free - Free a i2o_exec_wait struct + * @i2o_exec_wait: I2O wait data which should be cleaned up */ static void i2o_exec_wait_free(struct i2o_exec_wait *wait) { @@ -105,7 +105,7 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait) /** * i2o_msg_post_wait_mem - Post and wait a message with DMA buffers * @c: controller - * @msg: message to post + * @m: message to post * @timeout: time in seconds to wait * @dma: i2o_dma struct of the DMA buffer to free on failure * @@ -269,7 +269,6 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, /** * i2o_exec_show_vendor_id - Displays Vendor ID of controller * @d: device of which the Vendor ID should be displayed - * @attr: device_attribute to display * @buf: buffer into which the Vendor ID should be printed * * Returns number of bytes printed into buffer. @@ -291,7 +290,6 @@ static ssize_t i2o_exec_show_vendor_id(struct device *d, /** * i2o_exec_show_product_id - Displays Product ID of controller * @d: device of which the Product ID should be displayed - * @attr: device_attribute to display * @buf: buffer into which the Product ID should be printed * * Returns number of bytes printed into buffer. @@ -367,7 +365,7 @@ static int i2o_exec_remove(struct device *dev) /** * i2o_exec_lct_modified - Called on LCT NOTIFY reply - * @work: work struct for a specific controller + * @c: I2O controller on which the LCT has modified * * This function handles asynchronus LCT NOTIFY replies. It parses the * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY diff --git a/trunk/drivers/message/i2o/i2o_block.c b/trunk/drivers/message/i2o/i2o_block.c index da9859f2caf2..70ae00253321 100644 --- a/trunk/drivers/message/i2o/i2o_block.c +++ b/trunk/drivers/message/i2o/i2o_block.c @@ -259,7 +259,7 @@ static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id) /** * i2o_block_device_power - Power management for device dev * @dev: I2O device which should receive the power management request - * @op: Operation to send + * @operation: Operation which should be send * * Send a power management request to the device dev. * @@ -315,7 +315,7 @@ static inline struct i2o_block_request *i2o_block_request_alloc(void) * i2o_block_request_free - Frees a I2O block request * @ireq: I2O block request which should be freed * - * Frees the allocated memory (give it back to the request mempool). + * Fres the allocated memory (give it back to the request mempool). */ static inline void i2o_block_request_free(struct i2o_block_request *ireq) { @@ -326,7 +326,6 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq) * i2o_block_sglist_alloc - Allocate the SG list and map it * @c: I2O controller to which the request belongs * @ireq: I2O block request - * @mptr: message body pointer * * Builds the SG list and map it to be accessable by the controller. * @@ -491,7 +490,7 @@ static void i2o_block_end_request(struct request *req, int uptodate, * i2o_block_reply - Block OSM reply handler. * @c: I2O controller from which the message arrives * @m: message id of reply - * @msg: the actual I2O message reply + * qmsg: the actuall I2O message reply * * This function gets all the message replies. * @@ -603,8 +602,6 @@ static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls, /** * i2o_block_open - Open the block device - * @inode: inode for block device being opened - * @file: file to open * * Power up the device, mount and lock the media. This function is called, * if the block device is opened for access. @@ -632,8 +629,6 @@ static int i2o_block_open(struct inode *inode, struct file *file) /** * i2o_block_release - Release the I2O block device - * @inode: inode for block device being released - * @file: file to close * * Unlock and unmount the media, and power down the device. Gets called if * the block device is closed. @@ -680,8 +675,6 @@ static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo) /** * i2o_block_ioctl - Issue device specific ioctl calls. - * @inode: inode for block device ioctl - * @file: file for ioctl * @cmd: ioctl command * @arg: arg * @@ -909,7 +902,7 @@ static int i2o_block_transfer(struct request *req) /** * i2o_block_request_fn - request queue handling function - * @q: request queue from which the request could be fetched + * q: request queue from which the request could be fetched * * Takes the next request from the queue, transfers it and if no error * occurs dequeue it from the queue. On arrival of the reply the message diff --git a/trunk/drivers/message/i2o/i2o_block.h b/trunk/drivers/message/i2o/i2o_block.h index 67f921b4419b..d9fdc95b440d 100644 --- a/trunk/drivers/message/i2o/i2o_block.h +++ b/trunk/drivers/message/i2o/i2o_block.h @@ -64,7 +64,7 @@ /* I2O Block OSM mempool struct */ struct i2o_block_mempool { - struct kmem_cache *slab; + kmem_cache_t *slab; mempool_t *pool; }; diff --git a/trunk/drivers/message/i2o/i2o_config.c b/trunk/drivers/message/i2o/i2o_config.c index 1de30d711671..7d23e082bf26 100644 --- a/trunk/drivers/message/i2o/i2o_config.c +++ b/trunk/drivers/message/i2o/i2o_config.c @@ -265,11 +265,7 @@ static int i2o_cfg_swdl(unsigned long arg) return -ENOMEM; } - if (__copy_from_user(buffer.virt, kxfer.buf, fragsize)) { - i2o_msg_nop(c, msg); - i2o_dma_free(&c->pdev->dev, &buffer); - return -EFAULT; - } + __copy_from_user(buffer.virt, kxfer.buf, fragsize); msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7); msg->u.head[1] = @@ -520,6 +516,7 @@ static int i2o_cfg_evt_get(unsigned long arg, struct file *fp) return 0; } +#ifdef CONFIG_I2O_EXT_ADAPTEC #ifdef CONFIG_COMPAT static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long arg) @@ -762,7 +759,6 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, #endif -#ifdef CONFIG_I2O_EXT_ADAPTEC static int i2o_cfg_passthru(unsigned long arg) { struct i2o_cmd_passthru __user *cmd = diff --git a/trunk/drivers/message/i2o/i2o_proc.c b/trunk/drivers/message/i2o/i2o_proc.c index a61cb17c5c12..3d2e76eea93e 100644 --- a/trunk/drivers/message/i2o/i2o_proc.c +++ b/trunk/drivers/message/i2o/i2o_proc.c @@ -163,7 +163,7 @@ static int print_serial_number(struct seq_file *seq, u8 * serialno, int max_len) * i2o_get_class_name - do i2o class name lookup * @class: class number * - * Return a descriptive string for an i2o class. + * Return a descriptive string for an i2o class */ static const char *i2o_get_class_name(int class) { diff --git a/trunk/drivers/message/i2o/i2o_scsi.c b/trunk/drivers/message/i2o/i2o_scsi.c index 1045c8a518bb..6ebf38213f9f 100644 --- a/trunk/drivers/message/i2o/i2o_scsi.c +++ b/trunk/drivers/message/i2o/i2o_scsi.c @@ -220,7 +220,7 @@ static int i2o_scsi_probe(struct device *dev) u32 id = -1; u64 lun = -1; int channel = -1; - int i, rc; + int i; i2o_shost = i2o_scsi_get_host(c); if (!i2o_shost) @@ -304,20 +304,14 @@ static int i2o_scsi_probe(struct device *dev) return PTR_ERR(scsi_dev); } - rc = sysfs_create_link(&i2o_dev->device.kobj, - &scsi_dev->sdev_gendev.kobj, "scsi"); - if (rc) - goto err; + sysfs_create_link(&i2o_dev->device.kobj, &scsi_dev->sdev_gendev.kobj, + "scsi"); osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %ld\n", i2o_dev->lct_data.tid, channel, le32_to_cpu(id), (long unsigned int)le64_to_cpu(lun)); return 0; - -err: - scsi_remove_device(scsi_dev); - return rc; }; static const char *i2o_scsi_info(struct Scsi_Host *SChost) @@ -411,7 +405,8 @@ static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev) }; /** - * i2o_scsi_notify_device_remove - Retrieve notifications of removed devices + * i2o_scsi_notify_device_remove - Retrieve notifications of removed + * devices * @i2o_dev: the I2O device which was removed * * If a I2O device is removed, we catch the notification to remove the @@ -431,7 +426,8 @@ static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev) }; /** - * i2o_scsi_notify_controller_add - Retrieve notifications of added controllers + * i2o_scsi_notify_controller_add - Retrieve notifications of added + * controllers * @c: the controller which was added * * If a I2O controller is added, we catch the notification to add a @@ -461,7 +457,8 @@ static void i2o_scsi_notify_controller_add(struct i2o_controller *c) }; /** - * i2o_scsi_notify_controller_remove - Retrieve notifications of removed controllers + * i2o_scsi_notify_controller_remove - Retrieve notifications of removed + * controllers * @c: the controller which was removed * * If a I2O controller is removed, we catch the notification to remove the @@ -748,7 +745,7 @@ static int i2o_scsi_abort(struct scsi_cmnd *SCpnt) * @capacity: size in sectors * @ip: geometry array * - * This is anyone's guess quite frankly. We use the same rules everyone + * This is anyones guess quite frankly. We use the same rules everyone * else appears to and hope. It seems to work. */ diff --git a/trunk/drivers/message/i2o/pci.c b/trunk/drivers/message/i2o/pci.c index 3661e6e065d2..8287f95c8c42 100644 --- a/trunk/drivers/message/i2o/pci.c +++ b/trunk/drivers/message/i2o/pci.c @@ -259,7 +259,6 @@ static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id) /** * i2o_pci_irq_enable - Allocate interrupt for I2O controller - * @c: i2o_controller that the request is for * * Allocate an interrupt for the I2O controller, and activate interrupts * on the I2O controller. @@ -306,7 +305,7 @@ static void i2o_pci_irq_disable(struct i2o_controller *c) /** * i2o_pci_probe - Probe the PCI device for an I2O controller - * @pdev: PCI device to test + * @dev: PCI device to test * @id: id which matched with the PCI device id table * * Probe the PCI device for any device which is a memory of the @@ -448,7 +447,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, /** * i2o_pci_remove - Removes a I2O controller from the system - * @pdev: I2O controller which should be removed + * pdev: I2O controller which should be removed * * Reset the I2O controller, disable interrupts and remove all allocated * resources. diff --git a/trunk/drivers/mfd/ucb1x00-ts.c b/trunk/drivers/mfd/ucb1x00-ts.c index ce1a48108210..82938ad6ddbd 100644 --- a/trunk/drivers/mfd/ucb1x00-ts.c +++ b/trunk/drivers/mfd/ucb1x00-ts.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/misc/tifm_core.c b/trunk/drivers/misc/tifm_core.c index d61df5c3ac36..ee326136d03b 100644 --- a/trunk/drivers/misc/tifm_core.c +++ b/trunk/drivers/misc/tifm_core.c @@ -219,9 +219,8 @@ static int tifm_device_remove(struct device *dev) struct tifm_driver *drv = fm_dev->drv; if (drv) { - if (drv->remove) - drv->remove(fm_dev); - fm_dev->drv = NULL; + if (drv->remove) drv->remove(fm_dev); + fm_dev->drv = 0; } put_device(dev); diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index 334e078ffaff..ef4a731ca5c2 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -451,7 +451,7 @@ static int __devinit m25p_probe(struct spi_device *spi) return -ENODEV; } - flash = kzalloc(sizeof *flash, GFP_KERNEL); + flash = kzalloc(sizeof *flash, SLAB_KERNEL); if (!flash) return -ENOMEM; diff --git a/trunk/drivers/net/de600.c b/trunk/drivers/net/de600.c index 8396e411f1ce..690bb40b353d 100644 --- a/trunk/drivers/net/de600.c +++ b/trunk/drivers/net/de600.c @@ -43,6 +43,7 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj * modify the following "#define": (see for more info) #define REALLY_SLOW_IO */ +#define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */ /* use 0 for production, 1 for verification, >2 for debug */ #ifdef DE600_DEBUG diff --git a/trunk/drivers/net/irda/stir4200.c b/trunk/drivers/net/irda/stir4200.c index c14a74634fd5..3b4c47875935 100644 --- a/trunk/drivers/net/irda/stir4200.c +++ b/trunk/drivers/net/irda/stir4200.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/net/lasi_82596.c b/trunk/drivers/net/lasi_82596.c index ea392f2a5aa2..f4d815bca643 100644 --- a/trunk/drivers/net/lasi_82596.c +++ b/trunk/drivers/net/lasi_82596.c @@ -119,14 +119,14 @@ #define DEB(x,y) if (i596_debug & (x)) { y; } -#define CHECK_WBACK(priv, addr,len) \ - do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_TO_DEVICE); } while (0) +#define CHECK_WBACK(addr,len) \ + do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0) -#define CHECK_INV(priv, addr,len) \ - do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_FROM_DEVICE); } while(0) +#define CHECK_INV(addr,len) \ + do { dma_cache_sync((void *)addr, len, DMA_FROM_DEVICE); } while(0) -#define CHECK_WBACK_INV(priv, addr,len) \ - do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0) +#define CHECK_WBACK_INV(addr,len) \ + do { dma_cache_sync((void *)addr, len, DMA_BIDIRECTIONAL); } while (0) #define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/ @@ -449,10 +449,10 @@ static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x) static inline int wait_istat(struct net_device *dev, struct i596_private *lp, int delcnt, char *str) { - CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp)); + CHECK_INV(&(lp->iscp), sizeof(struct i596_iscp)); while (--delcnt && lp->iscp.stat) { udelay(10); - CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp)); + CHECK_INV(&(lp->iscp), sizeof(struct i596_iscp)); } if (!delcnt) { printk("%s: %s, iscp.stat %04x, didn't clear\n", @@ -466,10 +466,10 @@ static inline int wait_istat(struct net_device *dev, struct i596_private *lp, in static inline int wait_cmd(struct net_device *dev, struct i596_private *lp, int delcnt, char *str) { - CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_INV(&(lp->scb), sizeof(struct i596_scb)); while (--delcnt && lp->scb.command) { udelay(10); - CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_INV(&(lp->scb), sizeof(struct i596_scb)); } if (!delcnt) { printk("%s: %s, status %4.4x, cmd %4.4x.\n", @@ -522,7 +522,7 @@ static void i596_display_data(struct net_device *dev) rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size); rbd = rbd->v_next; } while (rbd != lp->rbd_head); - CHECK_INV(lp, lp, sizeof(struct i596_private)); + CHECK_INV(lp, sizeof(struct i596_private)); } @@ -592,7 +592,7 @@ static inline void init_rx_bufs(struct net_device *dev) rfd->b_next = WSWAPrfd(virt_to_dma(lp,lp->rfds)); rfd->cmd = CMD_EOL|CMD_FLEX; - CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private)); + CHECK_WBACK_INV(lp, sizeof(struct i596_private)); } static inline void remove_rx_bufs(struct net_device *dev) @@ -629,7 +629,7 @@ static void rebuild_rx_bufs(struct net_device *dev) lp->rbd_head = lp->rbds; lp->rfds[0].rbd = WSWAPrbd(virt_to_dma(lp,lp->rbds)); - CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private)); + CHECK_WBACK_INV(lp, sizeof(struct i596_private)); } @@ -663,8 +663,8 @@ static int init_i596_mem(struct net_device *dev) DEB(DEB_INIT, printk("%s: starting i82596.\n", dev->name)); - CHECK_WBACK(lp, &(lp->scp), sizeof(struct i596_scp)); - CHECK_WBACK(lp, &(lp->iscp), sizeof(struct i596_iscp)); + CHECK_WBACK(&(lp->scp), sizeof(struct i596_scp)); + CHECK_WBACK(&(lp->iscp), sizeof(struct i596_iscp)); MPU_PORT(dev, PORT_ALTSCP, virt_to_dma(lp,&lp->scp)); @@ -678,25 +678,25 @@ static int init_i596_mem(struct net_device *dev) rebuild_rx_bufs(dev); lp->scb.command = 0; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); enable_irq(dev->irq); /* enable IRQs from LAN */ DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name)); memcpy(lp->cf_cmd.i596_config, init_setup, 14); lp->cf_cmd.cmd.command = CmdConfigure; - CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd)); + CHECK_WBACK(&(lp->cf_cmd), sizeof(struct cf_cmd)); i596_add_cmd(dev, &lp->cf_cmd.cmd); DEB(DEB_INIT, printk("%s: queuing CmdSASetup\n", dev->name)); memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6); lp->sa_cmd.cmd.command = CmdSASetup; - CHECK_WBACK(lp, &(lp->sa_cmd), sizeof(struct sa_cmd)); + CHECK_WBACK(&(lp->sa_cmd), sizeof(struct sa_cmd)); i596_add_cmd(dev, &lp->sa_cmd.cmd); DEB(DEB_INIT, printk("%s: queuing CmdTDR\n", dev->name)); lp->tdr_cmd.cmd.command = CmdTDR; - CHECK_WBACK(lp, &(lp->tdr_cmd), sizeof(struct tdr_cmd)); + CHECK_WBACK(&(lp->tdr_cmd), sizeof(struct tdr_cmd)); i596_add_cmd(dev, &lp->tdr_cmd.cmd); spin_lock_irqsave (&lp->lock, flags); @@ -708,7 +708,7 @@ static int init_i596_mem(struct net_device *dev) DEB(DEB_INIT, printk("%s: Issuing RX_START\n", dev->name)); lp->scb.command = RX_START; lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds)); - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); CA(dev); @@ -740,13 +740,13 @@ static inline int i596_rx(struct net_device *dev) rfd = lp->rfd_head; /* Ref next frame to check */ - CHECK_INV(lp, rfd, sizeof(struct i596_rfd)); + CHECK_INV(rfd, sizeof(struct i596_rfd)); while ((rfd->stat) & STAT_C) { /* Loop while complete frames */ if (rfd->rbd == I596_NULL) rbd = NULL; else if (rfd->rbd == lp->rbd_head->b_addr) { rbd = lp->rbd_head; - CHECK_INV(lp, rbd, sizeof(struct i596_rbd)); + CHECK_INV(rbd, sizeof(struct i596_rbd)); } else { printk("%s: rbd chain broken!\n", dev->name); @@ -790,7 +790,7 @@ static inline int i596_rx(struct net_device *dev) dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE); rbd->v_data = newskb->data; rbd->b_data = WSWAPchar(dma_addr); - CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd)); + CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); } else skb = dev_alloc_skb(pkt_len + 2); @@ -842,7 +842,7 @@ static inline int i596_rx(struct net_device *dev) if (rbd != NULL && (rbd->count & 0x4000)) { rbd->count = 0; lp->rbd_head = rbd->v_next; - CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd)); + CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); } /* Tidy the frame descriptor, marking it as end of list */ @@ -860,10 +860,10 @@ static inline int i596_rx(struct net_device *dev) lp->scb.rfd = rfd->b_next; lp->rfd_head = rfd->v_next; - CHECK_WBACK_INV(lp, rfd->v_prev, sizeof(struct i596_rfd)); - CHECK_WBACK_INV(lp, rfd, sizeof(struct i596_rfd)); + CHECK_WBACK_INV(rfd->v_prev, sizeof(struct i596_rfd)); + CHECK_WBACK_INV(rfd, sizeof(struct i596_rfd)); rfd = lp->rfd_head; - CHECK_INV(lp, rfd, sizeof(struct i596_rfd)); + CHECK_INV(rfd, sizeof(struct i596_rfd)); } DEB(DEB_RXFRAME, printk("frames %d\n", frames)); @@ -902,12 +902,12 @@ static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private ptr->v_next = NULL; ptr->b_next = I596_NULL; } - CHECK_WBACK_INV(lp, ptr, sizeof(struct i596_cmd)); + CHECK_WBACK_INV(ptr, sizeof(struct i596_cmd)); } wait_cmd(dev, lp, 100, "i596_cleanup_cmd timed out"); lp->scb.cmd = I596_NULL; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); } @@ -925,7 +925,7 @@ static inline void i596_reset(struct net_device *dev, struct i596_private *lp) /* FIXME: this command might cause an lpmc */ lp->scb.command = CUC_ABORT | RX_ABORT; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); CA(dev); /* wait for shutdown */ @@ -951,20 +951,20 @@ static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) cmd->command |= (CMD_EOL | CMD_INTR); cmd->v_next = NULL; cmd->b_next = I596_NULL; - CHECK_WBACK(lp, cmd, sizeof(struct i596_cmd)); + CHECK_WBACK(cmd, sizeof(struct i596_cmd)); spin_lock_irqsave (&lp->lock, flags); if (lp->cmd_head != NULL) { lp->cmd_tail->v_next = cmd; lp->cmd_tail->b_next = WSWAPcmd(virt_to_dma(lp,&cmd->status)); - CHECK_WBACK(lp, lp->cmd_tail, sizeof(struct i596_cmd)); + CHECK_WBACK(lp->cmd_tail, sizeof(struct i596_cmd)); } else { lp->cmd_head = cmd; wait_cmd(dev, lp, 100, "i596_add_cmd timed out"); lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&cmd->status)); lp->scb.command = CUC_START; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); CA(dev); } lp->cmd_tail = cmd; @@ -998,12 +998,12 @@ static int i596_test(struct net_device *dev) data = virt_to_dma(lp,tint); tint[1] = -1; - CHECK_WBACK(lp, tint, PAGE_SIZE); + CHECK_WBACK(tint,PAGE_SIZE); MPU_PORT(dev, 1, data); for(data = 1000000; data; data--) { - CHECK_INV(lp, tint, PAGE_SIZE); + CHECK_INV(tint,PAGE_SIZE); if(tint[1] != -1) break; @@ -1061,7 +1061,7 @@ static void i596_tx_timeout (struct net_device *dev) /* Issue a channel attention signal */ DEB(DEB_ERRORS, printk("Kicking board.\n")); lp->scb.command = CUC_START | RX_START; - CHECK_WBACK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK_INV(&(lp->scb), sizeof(struct i596_scb)); CA (dev); lp->last_restart = lp->stats.tx_packets; } @@ -1118,8 +1118,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) tbd->data = WSWAPchar(tx_cmd->dma_addr); DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued")); - CHECK_WBACK_INV(lp, tx_cmd, sizeof(struct tx_cmd)); - CHECK_WBACK_INV(lp, tbd, sizeof(struct i596_tbd)); + CHECK_WBACK_INV(tx_cmd, sizeof(struct tx_cmd)); + CHECK_WBACK_INV(tbd, sizeof(struct i596_tbd)); i596_add_cmd(dev, &tx_cmd->cmd); lp->stats.tx_packets++; @@ -1228,7 +1228,7 @@ static int __devinit i82596_probe(struct net_device *dev, lp->dma_addr = dma_addr; lp->dev = gen_dev; - CHECK_WBACK_INV(lp, dev->mem_start, sizeof(struct i596_private)); + CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private)); i = register_netdev(dev); if (i) { @@ -1295,7 +1295,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) DEB(DEB_INTS, printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700)); while (lp->cmd_head != NULL) { - CHECK_INV(lp, lp->cmd_head, sizeof(struct i596_cmd)); + CHECK_INV(lp->cmd_head, sizeof(struct i596_cmd)); if (!(lp->cmd_head->status & STAT_C)) break; @@ -1358,7 +1358,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) } ptr->v_next = NULL; ptr->b_next = I596_NULL; - CHECK_WBACK(lp, ptr, sizeof(struct i596_cmd)); + CHECK_WBACK(ptr, sizeof(struct i596_cmd)); lp->last_cmd = jiffies; } @@ -1372,13 +1372,13 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) ptr->command &= 0x1fff; ptr = ptr->v_next; - CHECK_WBACK_INV(lp, prev, sizeof(struct i596_cmd)); + CHECK_WBACK_INV(prev, sizeof(struct i596_cmd)); } if ((lp->cmd_head != NULL)) ack_cmd |= CUC_START; lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&lp->cmd_head->status)); - CHECK_WBACK_INV(lp, &lp->scb, sizeof(struct i596_scb)); + CHECK_WBACK_INV(&lp->scb, sizeof(struct i596_scb)); } if ((status & 0x1000) || (status & 0x4000)) { if ((status & 0x4000)) @@ -1397,7 +1397,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) } wait_cmd(dev, lp, 100, "i596 interrupt, timeout"); lp->scb.command = ack_cmd; - CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb)); + CHECK_WBACK(&lp->scb, sizeof(struct i596_scb)); /* DANGER: I suspect that some kind of interrupt acknowledgement aside from acking the 82596 might be needed @@ -1426,7 +1426,7 @@ static int i596_close(struct net_device *dev) wait_cmd(dev, lp, 100, "close1 timed out"); lp->scb.command = CUC_ABORT | RX_ABORT; - CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb)); + CHECK_WBACK(&lp->scb, sizeof(struct i596_scb)); CA(dev); @@ -1486,7 +1486,7 @@ static void set_multicast_list(struct net_device *dev) dev->name); else { lp->cf_cmd.cmd.command = CmdConfigure; - CHECK_WBACK_INV(lp, &lp->cf_cmd, sizeof(struct cf_cmd)); + CHECK_WBACK_INV(&lp->cf_cmd, sizeof(struct cf_cmd)); i596_add_cmd(dev, &lp->cf_cmd.cmd); } } @@ -1514,7 +1514,7 @@ static void set_multicast_list(struct net_device *dev) DEB(DEB_MULTI, printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5])); } - CHECK_WBACK_INV(lp, &lp->mc_cmd, sizeof(struct mc_cmd)); + CHECK_WBACK_INV(&lp->mc_cmd, sizeof(struct mc_cmd)); i596_add_cmd(dev, &cmd->cmd); } } diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index 44a22701da97..efcdaf1c5f73 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -49,7 +49,6 @@ #include #include #include -#include #include "airo.h" diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index b61c17b3e298..39c96641bc72 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -1975,7 +1975,7 @@ static int __devinit parport_ECPPS2_supported(struct parport *pb){return 0;} /* --- IRQ detection -------------------------------------- */ /* Only if supports ECP mode */ -static int programmable_irq_support(struct parport *pb) +static int __devinit programmable_irq_support(struct parport *pb) { int irq, intrLine; unsigned char oecr = inb (ECONTROL (pb)); @@ -1992,7 +1992,7 @@ static int programmable_irq_support(struct parport *pb) return irq; } -static int irq_probe_ECP(struct parport *pb) +static int __devinit irq_probe_ECP(struct parport *pb) { int i; unsigned long irqs; @@ -2020,7 +2020,7 @@ static int irq_probe_ECP(struct parport *pb) * This detection seems that only works in National Semiconductors * This doesn't work in SMC, LGS, and Winbond */ -static int irq_probe_EPP(struct parport *pb) +static int __devinit irq_probe_EPP(struct parport *pb) { #ifndef ADVANCED_DETECT return PARPORT_IRQ_NONE; @@ -2059,7 +2059,7 @@ static int irq_probe_EPP(struct parport *pb) #endif /* Advanced detection */ } -static int irq_probe_SPP(struct parport *pb) +static int __devinit irq_probe_SPP(struct parport *pb) { /* Don't even try to do this. */ return PARPORT_IRQ_NONE; @@ -2747,7 +2747,6 @@ enum parport_pc_pci_cards { titan_1284p2, avlab_1p, avlab_2p, - oxsemi_952, oxsemi_954, oxsemi_840, aks_0100, @@ -2823,7 +2822,6 @@ static struct parport_pc_pci { /* avlab_2p */ { 2, { { 0, 1}, { 2, 3 },} }, /* The Oxford Semi cards are unusual: 954 doesn't support ECP, * and 840 locks up if you write 1 to bit 2! */ - /* oxsemi_952 */ { 1, { { 0, 1 }, } }, /* oxsemi_954 */ { 1, { { 0, -1 }, } }, /* oxsemi_840 */ { 1, { { 0, -1 }, } }, /* aks_0100 */ { 1, { { 0, -1 }, } }, @@ -2897,8 +2895,6 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ { 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, /* AFAVLAB_TK9902 */ { 0x14db, 0x2121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2p}, - { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952PP, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_952 }, { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954PP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_954 }, { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_12PCI840, diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 9168401401bc..9fc9a34ef24a 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -26,7 +26,7 @@ static DEFINE_SPINLOCK(msi_lock); static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; -static struct kmem_cache* msi_cachep; +static kmem_cache_t* msi_cachep; static int pci_msi_enable = 1; diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index 6a3c1e728900..0eeac60042b3 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -873,7 +873,6 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus) dev->dev.release = pci_release_dev; pci_dev_get(dev); - set_dev_node(&dev->dev, pcibus_to_node(bus)); dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask = 0xffffffffull; diff --git a/trunk/drivers/pcmcia/cs.c b/trunk/drivers/pcmcia/cs.c index 606a46740338..f9cd831a3f31 100644 --- a/trunk/drivers/pcmcia/cs.c +++ b/trunk/drivers/pcmcia/cs.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/pnp/card.c b/trunk/drivers/pnp/card.c index 91c047a7e635..227600cd6360 100644 --- a/trunk/drivers/pnp/card.c +++ b/trunk/drivers/pnp/card.c @@ -164,17 +164,9 @@ static DEVICE_ATTR(card_id,S_IRUGO,pnp_show_card_ids,NULL); static int pnp_interface_attach_card(struct pnp_card *card) { - int rc = device_create_file(&card->dev,&dev_attr_name); - if (rc) return rc; - - rc = device_create_file(&card->dev,&dev_attr_card_id); - if (rc) goto err_name; - + device_create_file(&card->dev,&dev_attr_name); + device_create_file(&card->dev,&dev_attr_card_id); return 0; - -err_name: - device_remove_file(&card->dev,&dev_attr_name); - return rc; } /** @@ -314,20 +306,16 @@ struct pnp_dev * pnp_request_card_device(struct pnp_card_link *clink, const char down_write(&dev->dev.bus->subsys.rwsem); dev->card_link = clink; dev->dev.driver = &drv->link.driver; - if (pnp_bus_type.probe(&dev->dev)) - goto err_out; - if (device_bind_driver(&dev->dev)) - goto err_out; - + if (pnp_bus_type.probe(&dev->dev)) { + dev->dev.driver = NULL; + dev->card_link = NULL; + up_write(&dev->dev.bus->subsys.rwsem); + return NULL; + } + device_bind_driver(&dev->dev); up_write(&dev->dev.bus->subsys.rwsem); return dev; - -err_out: - dev->dev.driver = NULL; - dev->card_link = NULL; - up_write(&dev->dev.bus->subsys.rwsem); - return NULL; } /** diff --git a/trunk/drivers/pnp/interface.c b/trunk/drivers/pnp/interface.c index ac9fcd499f3f..9d8b415eca79 100644 --- a/trunk/drivers/pnp/interface.c +++ b/trunk/drivers/pnp/interface.c @@ -461,19 +461,8 @@ static DEVICE_ATTR(id,S_IRUGO,pnp_show_current_ids,NULL); int pnp_interface_attach_device(struct pnp_dev *dev) { - int rc = device_create_file(&dev->dev,&dev_attr_options); - if (rc) goto err; - rc = device_create_file(&dev->dev,&dev_attr_resources); - if (rc) goto err_opt; - rc = device_create_file(&dev->dev,&dev_attr_id); - if (rc) goto err_res; - + device_create_file(&dev->dev,&dev_attr_options); + device_create_file(&dev->dev,&dev_attr_resources); + device_create_file(&dev->dev,&dev_attr_id); return 0; - -err_res: - device_remove_file(&dev->dev,&dev_attr_resources); -err_opt: - device_remove_file(&dev->dev,&dev_attr_options); -err: - return rc; } diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c index 33adeba1a31f..81a6c83d89a6 100644 --- a/trunk/drivers/pnp/pnpbios/core.c +++ b/trunk/drivers/pnp/pnpbios/core.c @@ -61,7 +61,6 @@ #include #include #include -#include #include #include @@ -531,8 +530,7 @@ static int __init pnpbios_init(void) if (check_legacy_ioport(PNPBIOS_BASE)) return -ENODEV; #endif - if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table) || - paravirt_enabled()) { + if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table)) { printk(KERN_INFO "PnPBIOS: Disabled\n"); return -ENODEV; } diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 2a63ab2b47f4..fc766a7a611e 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -154,23 +154,15 @@ config RTC_DRV_DS1672 will be called rtc-ds1672. config RTC_DRV_DS1742 - tristate "Dallas DS1742/1743" + tristate "Dallas DS1742" depends on RTC_CLASS help If you say yes here you get support for the - Dallas DS1742/1743 timekeeping chip. + Dallas DS1742 timekeeping chip. This driver can also be built as a module. If so, the module will be called rtc-ds1742. -config RTC_DRV_OMAP - tristate "TI OMAP1" - depends on RTC_CLASS && ( \ - ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 ) - help - Say "yes" here to support the real time clock on TI OMAP1 chips. - This driver can also be built as a module called rtc-omap. - config RTC_DRV_PCF8563 tristate "Philips PCF8563/Epson RTC8564" depends on RTC_CLASS && I2C diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index bd4c45d333f0..3ba5ff6e6800 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o -obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o diff --git a/trunk/drivers/rtc/rtc-ds1672.c b/trunk/drivers/rtc/rtc-ds1672.c index dfef1637bfb8..67e816a9a39f 100644 --- a/trunk/drivers/rtc/rtc-ds1672.c +++ b/trunk/drivers/rtc/rtc-ds1672.c @@ -237,22 +237,17 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) /* read control register */ err = ds1672_get_control(client, &control); if (err) - goto exit_devreg; + goto exit_detach; if (control & DS1672_REG_CONTROL_EOSC) dev_warn(&client->dev, "Oscillator not enabled. " "Set time to enable.\n"); /* Register sysfs hooks */ - err = device_create_file(&client->dev, &dev_attr_control); - if (err) - goto exit_devreg; + device_create_file(&client->dev, &dev_attr_control); return 0; -exit_devreg: - rtc_device_unregister(rtc); - exit_detach: i2c_detach_client(client); diff --git a/trunk/drivers/rtc/rtc-ds1742.c b/trunk/drivers/rtc/rtc-ds1742.c index 17633bfa8480..6273a3d240a2 100644 --- a/trunk/drivers/rtc/rtc-ds1742.c +++ b/trunk/drivers/rtc/rtc-ds1742.c @@ -6,10 +6,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * Copyright (C) 2006 Torsten Ertbjerg Rasmussen - * - nvram size determined from resource - * - this ds1742 driver now supports ds1743. */ #include @@ -21,19 +17,20 @@ #include #include -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.2" -#define RTC_SIZE 8 +#define RTC_REG_SIZE 0x800 +#define RTC_OFFSET 0x7f8 -#define RTC_CONTROL 0 -#define RTC_CENTURY 0 -#define RTC_SECONDS 1 -#define RTC_MINUTES 2 -#define RTC_HOURS 3 -#define RTC_DAY 4 -#define RTC_DATE 5 -#define RTC_MONTH 6 -#define RTC_YEAR 7 +#define RTC_CONTROL (RTC_OFFSET + 0) +#define RTC_CENTURY (RTC_OFFSET + 0) +#define RTC_SECONDS (RTC_OFFSET + 1) +#define RTC_MINUTES (RTC_OFFSET + 2) +#define RTC_HOURS (RTC_OFFSET + 3) +#define RTC_DAY (RTC_OFFSET + 4) +#define RTC_DATE (RTC_OFFSET + 5) +#define RTC_MONTH (RTC_OFFSET + 6) +#define RTC_YEAR (RTC_OFFSET + 7) #define RTC_CENTURY_MASK 0x3f #define RTC_SECONDS_MASK 0x7f @@ -51,10 +48,7 @@ struct rtc_plat_data { struct rtc_device *rtc; - void __iomem *ioaddr_nvram; - void __iomem *ioaddr_rtc; - size_t size_nvram; - size_t size; + void __iomem *ioaddr; unsigned long baseaddr; unsigned long last_jiffies; }; @@ -63,7 +57,7 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr_rtc; + void __iomem *ioaddr = pdata->ioaddr; u8 century; century = BIN2BCD((tm->tm_year + 1900) / 100); @@ -88,7 +82,7 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr_rtc; + void __iomem *ioaddr = pdata->ioaddr; unsigned int year, month, day, hour, minute, second, week; unsigned int century; @@ -133,10 +127,10 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf, struct platform_device *pdev = to_platform_device(container_of(kobj, struct device, kobj)); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr_nvram; + void __iomem *ioaddr = pdata->ioaddr; ssize_t count; - for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--) + for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) *buf++ = readb(ioaddr + pos++); return count; } @@ -147,10 +141,10 @@ static ssize_t ds1742_nvram_write(struct kobject *kobj, char *buf, struct platform_device *pdev = to_platform_device(container_of(kobj, struct device, kobj)); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr_nvram; + void __iomem *ioaddr = pdata->ioaddr; ssize_t count; - for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--) + for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) writeb(*buf++, ioaddr + pos++); return count; } @@ -161,6 +155,7 @@ static struct bin_attribute ds1742_nvram_attr = { .mode = S_IRUGO | S_IWUGO, .owner = THIS_MODULE, }, + .size = RTC_OFFSET, .read = ds1742_nvram_read, .write = ds1742_nvram_write, }; @@ -180,23 +175,19 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev) pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; - pdata->size = res->end - res->start + 1; - if (!request_mem_region(res->start, pdata->size, pdev->name)) { + if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { ret = -EBUSY; goto out; } pdata->baseaddr = res->start; - ioaddr = ioremap(pdata->baseaddr, pdata->size); + ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE); if (!ioaddr) { ret = -ENOMEM; goto out; } - pdata->ioaddr_nvram = ioaddr; - pdata->size_nvram = pdata->size - RTC_SIZE; - pdata->ioaddr_rtc = ioaddr + pdata->size_nvram; + pdata->ioaddr = ioaddr; /* turn RTC on if it was not on */ - ioaddr = pdata->ioaddr_rtc; sec = readb(ioaddr + RTC_SECONDS); if (sec & RTC_STOP) { sec &= RTC_SECONDS_MASK; @@ -217,8 +208,6 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev) pdata->rtc = rtc; pdata->last_jiffies = jiffies; platform_set_drvdata(pdev, pdata); - ds1742_nvram_attr.size = max(ds1742_nvram_attr.size, - pdata->size_nvram); ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr); if (ret) goto out; @@ -226,10 +215,10 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev) out: if (pdata->rtc) rtc_device_unregister(pdata->rtc); - if (pdata->ioaddr_nvram) - iounmap(pdata->ioaddr_nvram); + if (ioaddr) + iounmap(ioaddr); if (pdata->baseaddr) - release_mem_region(pdata->baseaddr, pdata->size); + release_mem_region(pdata->baseaddr, RTC_REG_SIZE); kfree(pdata); return ret; } @@ -240,8 +229,8 @@ static int __devexit ds1742_rtc_remove(struct platform_device *pdev) sysfs_remove_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr); rtc_device_unregister(pdata->rtc); - iounmap(pdata->ioaddr_nvram); - release_mem_region(pdata->baseaddr, pdata->size); + iounmap(pdata->ioaddr); + release_mem_region(pdata->baseaddr, RTC_REG_SIZE); kfree(pdata); return 0; } diff --git a/trunk/drivers/rtc/rtc-omap.c b/trunk/drivers/rtc/rtc-omap.c deleted file mode 100644 index eac5fb1fc02f..000000000000 --- a/trunk/drivers/rtc/rtc-omap.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * TI OMAP1 Real Time Clock interface for Linux - * - * Copyright (C) 2003 MontaVista Software, Inc. - * Author: George G. Davis or - * - * Copyright (C) 2006 David Brownell (new RTC framework) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -/* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock - * with century-range alarm matching, driven by the 32kHz clock. - * - * The main user-visible ways it differs from PC RTCs are by omitting - * "don't care" alarm fields and sub-second periodic IRQs, and having - * an autoadjust mechanism to calibrate to the true oscillator rate. - * - * Board-specific wiring options include using split power mode with - * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset), - * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from - * low power modes). See the BOARD-SPECIFIC CUSTOMIZATION comment. - */ - -#define OMAP_RTC_BASE 0xfffb4800 - -/* RTC registers */ -#define OMAP_RTC_SECONDS_REG 0x00 -#define OMAP_RTC_MINUTES_REG 0x04 -#define OMAP_RTC_HOURS_REG 0x08 -#define OMAP_RTC_DAYS_REG 0x0C -#define OMAP_RTC_MONTHS_REG 0x10 -#define OMAP_RTC_YEARS_REG 0x14 -#define OMAP_RTC_WEEKS_REG 0x18 - -#define OMAP_RTC_ALARM_SECONDS_REG 0x20 -#define OMAP_RTC_ALARM_MINUTES_REG 0x24 -#define OMAP_RTC_ALARM_HOURS_REG 0x28 -#define OMAP_RTC_ALARM_DAYS_REG 0x2c -#define OMAP_RTC_ALARM_MONTHS_REG 0x30 -#define OMAP_RTC_ALARM_YEARS_REG 0x34 - -#define OMAP_RTC_CTRL_REG 0x40 -#define OMAP_RTC_STATUS_REG 0x44 -#define OMAP_RTC_INTERRUPTS_REG 0x48 - -#define OMAP_RTC_COMP_LSB_REG 0x4c -#define OMAP_RTC_COMP_MSB_REG 0x50 -#define OMAP_RTC_OSC_REG 0x54 - -/* OMAP_RTC_CTRL_REG bit fields: */ -#define OMAP_RTC_CTRL_SPLIT (1<<7) -#define OMAP_RTC_CTRL_DISABLE (1<<6) -#define OMAP_RTC_CTRL_SET_32_COUNTER (1<<5) -#define OMAP_RTC_CTRL_TEST (1<<4) -#define OMAP_RTC_CTRL_MODE_12_24 (1<<3) -#define OMAP_RTC_CTRL_AUTO_COMP (1<<2) -#define OMAP_RTC_CTRL_ROUND_30S (1<<1) -#define OMAP_RTC_CTRL_STOP (1<<0) - -/* OMAP_RTC_STATUS_REG bit fields: */ -#define OMAP_RTC_STATUS_POWER_UP (1<<7) -#define OMAP_RTC_STATUS_ALARM (1<<6) -#define OMAP_RTC_STATUS_1D_EVENT (1<<5) -#define OMAP_RTC_STATUS_1H_EVENT (1<<4) -#define OMAP_RTC_STATUS_1M_EVENT (1<<3) -#define OMAP_RTC_STATUS_1S_EVENT (1<<2) -#define OMAP_RTC_STATUS_RUN (1<<1) -#define OMAP_RTC_STATUS_BUSY (1<<0) - -/* OMAP_RTC_INTERRUPTS_REG bit fields: */ -#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) -#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) - - -#define rtc_read(addr) omap_readb(OMAP_RTC_BASE + (addr)) -#define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) - - -/* platform_bus isn't hotpluggable, so for static linkage it'd be safe - * to get rid of probe() and remove() code ... too bad the driver struct - * remembers probe(), that's about 25% of the runtime footprint!! - */ -#ifndef MODULE -#undef __devexit -#undef __devexit_p -#define __devexit __exit -#define __devexit_p __exit_p -#endif - - -/* we rely on the rtc framework to handle locking (rtc->ops_lock), - * so the only other requirement is that register accesses which - * require BUSY to be clear are made with IRQs locally disabled - */ -static void rtc_wait_not_busy(void) -{ - int count = 0; - u8 status; - - /* BUSY may stay active for 1/32768 second (~30 usec) */ - for (count = 0; count < 50; count++) { - status = rtc_read(OMAP_RTC_STATUS_REG); - if ((status & (u8)OMAP_RTC_STATUS_BUSY) == 0) - break; - udelay(1); - } - /* now we have ~15 usec to read/write various registers */ -} - -static irqreturn_t rtc_irq(int irq, void *class_dev) -{ - unsigned long events = 0; - u8 irq_data; - - irq_data = rtc_read(OMAP_RTC_STATUS_REG); - - /* alarm irq? */ - if (irq_data & OMAP_RTC_STATUS_ALARM) { - rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); - events |= RTC_IRQF | RTC_AF; - } - - /* 1/sec periodic/update irq? */ - if (irq_data & OMAP_RTC_STATUS_1S_EVENT) - events |= RTC_IRQF | RTC_UF; - - rtc_update_irq(class_dev, 1, events); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_RTC_INTF_DEV - -static int -omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - u8 reg; - - switch (cmd) { - case RTC_AIE_OFF: - case RTC_AIE_ON: - case RTC_UIE_OFF: - case RTC_UIE_ON: - break; - default: - return -ENOIOCTLCMD; - } - - local_irq_disable(); - rtc_wait_not_busy(); - reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); - switch (cmd) { - /* AIE = Alarm Interrupt Enable */ - case RTC_AIE_OFF: - reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; - break; - case RTC_AIE_ON: - reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; - break; - /* UIE = Update Interrupt Enable (1/second) */ - case RTC_UIE_OFF: - reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER; - break; - case RTC_UIE_ON: - reg |= OMAP_RTC_INTERRUPTS_IT_TIMER; - break; - } - rtc_wait_not_busy(); - rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); - local_irq_enable(); - - return 0; -} - -#else -#define omap_rtc_ioctl NULL -#endif - -/* this hardware doesn't support "don't care" alarm fields */ -static int tm2bcd(struct rtc_time *tm) -{ - if (rtc_valid_tm(tm) != 0) - return -EINVAL; - - tm->tm_sec = BIN2BCD(tm->tm_sec); - tm->tm_min = BIN2BCD(tm->tm_min); - tm->tm_hour = BIN2BCD(tm->tm_hour); - tm->tm_mday = BIN2BCD(tm->tm_mday); - - tm->tm_mon = BIN2BCD(tm->tm_mon + 1); - - /* epoch == 1900 */ - if (tm->tm_year < 100 || tm->tm_year > 199) - return -EINVAL; - tm->tm_year = BIN2BCD(tm->tm_year - 100); - - return 0; -} - -static void bcd2tm(struct rtc_time *tm) -{ - tm->tm_sec = BCD2BIN(tm->tm_sec); - tm->tm_min = BCD2BIN(tm->tm_min); - tm->tm_hour = BCD2BIN(tm->tm_hour); - tm->tm_mday = BCD2BIN(tm->tm_mday); - tm->tm_mon = BCD2BIN(tm->tm_mon) - 1; - /* epoch == 1900 */ - tm->tm_year = BCD2BIN(tm->tm_year) + 100; -} - - -static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - /* we don't report wday/yday/isdst ... */ - local_irq_disable(); - rtc_wait_not_busy(); - - tm->tm_sec = rtc_read(OMAP_RTC_SECONDS_REG); - tm->tm_min = rtc_read(OMAP_RTC_MINUTES_REG); - tm->tm_hour = rtc_read(OMAP_RTC_HOURS_REG); - tm->tm_mday = rtc_read(OMAP_RTC_DAYS_REG); - tm->tm_mon = rtc_read(OMAP_RTC_MONTHS_REG); - tm->tm_year = rtc_read(OMAP_RTC_YEARS_REG); - - local_irq_enable(); - - bcd2tm(tm); - return 0; -} - -static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - if (tm2bcd(tm) < 0) - return -EINVAL; - local_irq_disable(); - rtc_wait_not_busy(); - - rtc_write(tm->tm_year, OMAP_RTC_YEARS_REG); - rtc_write(tm->tm_mon, OMAP_RTC_MONTHS_REG); - rtc_write(tm->tm_mday, OMAP_RTC_DAYS_REG); - rtc_write(tm->tm_hour, OMAP_RTC_HOURS_REG); - rtc_write(tm->tm_min, OMAP_RTC_MINUTES_REG); - rtc_write(tm->tm_sec, OMAP_RTC_SECONDS_REG); - - local_irq_enable(); - - return 0; -} - -static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - local_irq_disable(); - rtc_wait_not_busy(); - - alm->time.tm_sec = rtc_read(OMAP_RTC_ALARM_SECONDS_REG); - alm->time.tm_min = rtc_read(OMAP_RTC_ALARM_MINUTES_REG); - alm->time.tm_hour = rtc_read(OMAP_RTC_ALARM_HOURS_REG); - alm->time.tm_mday = rtc_read(OMAP_RTC_ALARM_DAYS_REG); - alm->time.tm_mon = rtc_read(OMAP_RTC_ALARM_MONTHS_REG); - alm->time.tm_year = rtc_read(OMAP_RTC_ALARM_YEARS_REG); - - local_irq_enable(); - - bcd2tm(&alm->time); - alm->pending = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG) - & OMAP_RTC_INTERRUPTS_IT_ALARM); - alm->enabled = alm->pending && device_may_wakeup(dev); - - return 0; -} - -static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - u8 reg; - - /* Much userspace code uses RTC_ALM_SET, thus "don't care" for - * day/month/year specifies alarms up to 24 hours in the future. - * So we need to handle that ... but let's ignore the "don't care" - * values for hours/minutes/seconds. - */ - if (alm->time.tm_mday <= 0 - && alm->time.tm_mon < 0 - && alm->time.tm_year < 0) { - struct rtc_time tm; - unsigned long now, then; - - omap_rtc_read_time(dev, &tm); - rtc_tm_to_time(&tm, &now); - - alm->time.tm_mday = tm.tm_mday; - alm->time.tm_mon = tm.tm_mon; - alm->time.tm_year = tm.tm_year; - rtc_tm_to_time(&alm->time, &then); - - /* sometimes the alarm wraps into tomorrow */ - if (then < now) { - rtc_time_to_tm(now + 24 * 60 * 60, &tm); - alm->time.tm_mday = tm.tm_mday; - alm->time.tm_mon = tm.tm_mon; - alm->time.tm_year = tm.tm_year; - } - } - - if (tm2bcd(&alm->time) < 0) - return -EINVAL; - - local_irq_disable(); - rtc_wait_not_busy(); - - rtc_write(alm->time.tm_year, OMAP_RTC_ALARM_YEARS_REG); - rtc_write(alm->time.tm_mon, OMAP_RTC_ALARM_MONTHS_REG); - rtc_write(alm->time.tm_mday, OMAP_RTC_ALARM_DAYS_REG); - rtc_write(alm->time.tm_hour, OMAP_RTC_ALARM_HOURS_REG); - rtc_write(alm->time.tm_min, OMAP_RTC_ALARM_MINUTES_REG); - rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG); - - reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); - if (alm->enabled) - reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; - else - reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; - rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); - - local_irq_enable(); - - return 0; -} - -static struct rtc_class_ops omap_rtc_ops = { - .ioctl = omap_rtc_ioctl, - .read_time = omap_rtc_read_time, - .set_time = omap_rtc_set_time, - .read_alarm = omap_rtc_read_alarm, - .set_alarm = omap_rtc_set_alarm, -}; - -static int omap_rtc_alarm; -static int omap_rtc_timer; - -static int __devinit omap_rtc_probe(struct platform_device *pdev) -{ - struct resource *res, *mem; - struct rtc_device *rtc; - u8 reg, new_ctrl; - - omap_rtc_timer = platform_get_irq(pdev, 0); - if (omap_rtc_timer <= 0) { - pr_debug("%s: no update irq?\n", pdev->name); - return -ENOENT; - } - - omap_rtc_alarm = platform_get_irq(pdev, 1); - if (omap_rtc_alarm <= 0) { - pr_debug("%s: no alarm irq?\n", pdev->name); - return -ENOENT; - } - - /* NOTE: using static mapping for RTC registers */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res && res->start != OMAP_RTC_BASE) { - pr_debug("%s: RTC registers at %08x, expected %08x\n", - pdev->name, (unsigned) res->start, OMAP_RTC_BASE); - return -ENOENT; - } - - if (res) - mem = request_mem_region(res->start, - res->end - res->start + 1, - pdev->name); - else - mem = NULL; - if (!mem) { - pr_debug("%s: RTC registers at %08x are not free\n", - pdev->name, OMAP_RTC_BASE); - return -EBUSY; - } - - rtc = rtc_device_register(pdev->name, &pdev->dev, - &omap_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - pr_debug("%s: can't register RTC device, err %ld\n", - pdev->name, PTR_ERR(rtc)); - goto fail; - } - platform_set_drvdata(pdev, rtc); - class_set_devdata(&rtc->class_dev, mem); - - /* clear pending irqs, and set 1/second periodic, - * which we'll use instead of update irqs - */ - rtc_write(0, OMAP_RTC_INTERRUPTS_REG); - - /* clear old status */ - reg = rtc_read(OMAP_RTC_STATUS_REG); - if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) { - pr_info("%s: RTC power up reset detected\n", - pdev->name); - rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG); - } - if (reg & (u8) OMAP_RTC_STATUS_ALARM) - rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); - - /* handle periodic and alarm irqs */ - if (request_irq(omap_rtc_timer, rtc_irq, SA_INTERRUPT, - rtc->class_dev.class_id, &rtc->class_dev)) { - pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", - pdev->name, omap_rtc_timer); - goto fail0; - } - if (request_irq(omap_rtc_alarm, rtc_irq, SA_INTERRUPT, - rtc->class_dev.class_id, &rtc->class_dev)) { - pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", - pdev->name, omap_rtc_alarm); - goto fail1; - } - - /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ - reg = rtc_read(OMAP_RTC_CTRL_REG); - if (reg & (u8) OMAP_RTC_CTRL_STOP) - pr_info("%s: already running\n", pdev->name); - - /* force to 24 hour mode */ - new_ctrl = reg & ~(OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP); - new_ctrl |= OMAP_RTC_CTRL_STOP; - - /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: - * - * - Boards wired so that RTC_WAKE_INT does something, and muxed - * right (W13_1610_RTC_WAKE_INT is the default after chip reset), - * should initialize the device wakeup flag appropriately. - * - * - Boards wired so RTC_ON_nOFF is used as the reset signal, - * rather than nPWRON_RESET, should forcibly enable split - * power mode. (Some chip errata report that RTC_CTRL_SPLIT - * is write-only, and always reads as zero...) - */ - device_init_wakeup(&pdev->dev, 0); - - if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) - pr_info("%s: split power mode\n", pdev->name); - - if (reg != new_ctrl) - rtc_write(new_ctrl, OMAP_RTC_CTRL_REG); - - return 0; - -fail1: - free_irq(omap_rtc_timer, NULL); -fail0: - rtc_device_unregister(rtc); -fail: - release_resource(mem); - return -EIO; -} - -static int __devexit omap_rtc_remove(struct platform_device *pdev) -{ - struct rtc_device *rtc = platform_get_drvdata(pdev);; - - device_init_wakeup(&pdev->dev, 0); - - /* leave rtc running, but disable irqs */ - rtc_write(0, OMAP_RTC_INTERRUPTS_REG); - - free_irq(omap_rtc_timer, rtc); - free_irq(omap_rtc_alarm, rtc); - - release_resource(class_get_devdata(&rtc->class_dev)); - rtc_device_unregister(rtc); - return 0; -} - -#ifdef CONFIG_PM - -static struct timespec rtc_delta; -static u8 irqstat; - -static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct rtc_time rtc_tm; - struct timespec time; - - time.tv_nsec = 0; - omap_rtc_read_time(NULL, &rtc_tm); - rtc_tm_to_time(&rtc_tm, &time.tv_sec); - - save_time_delta(&rtc_delta, &time); - irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); - - /* FIXME the RTC alarm is not currently acting as a wakeup event - * source, and in fact this enable() call is just saving a flag - * that's never used... - */ - if (device_may_wakeup(&pdev->dev)) - enable_irq_wake(omap_rtc_alarm); - else - rtc_write(0, OMAP_RTC_INTERRUPTS_REG); - - return 0; -} - -static int omap_rtc_resume(struct platform_device *pdev) -{ - struct rtc_time rtc_tm; - struct timespec time; - - time.tv_nsec = 0; - omap_rtc_read_time(NULL, &rtc_tm); - rtc_tm_to_time(&rtc_tm, &time.tv_sec); - - restore_time_delta(&rtc_delta, &time); - if (device_may_wakeup(&pdev->dev)) - disable_irq_wake(omap_rtc_alarm); - else - rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG); - return 0; -} - -#else -#define omap_rtc_suspend NULL -#define omap_rtc_resume NULL -#endif - -static void omap_rtc_shutdown(struct platform_device *pdev) -{ - rtc_write(0, OMAP_RTC_INTERRUPTS_REG); -} - -MODULE_ALIAS("omap_rtc"); -static struct platform_driver omap_rtc_driver = { - .probe = omap_rtc_probe, - .remove = __devexit_p(omap_rtc_remove), - .suspend = omap_rtc_suspend, - .resume = omap_rtc_resume, - .shutdown = omap_rtc_shutdown, - .driver = { - .name = "omap_rtc", - .owner = THIS_MODULE, - }, -}; - -static int __init rtc_init(void) -{ - return platform_driver_register(&omap_rtc_driver); -} -module_init(rtc_init); - -static void __exit rtc_exit(void) -{ - platform_driver_unregister(&omap_rtc_driver); -} -module_exit(rtc_exit); - -MODULE_AUTHOR("George G. Davis (and others)"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-rs5c372.c b/trunk/drivers/rtc/rtc-rs5c372.c index e2c7698fdba3..a44fe4efa216 100644 --- a/trunk/drivers/rtc/rtc-rs5c372.c +++ b/trunk/drivers/rtc/rtc-rs5c372.c @@ -13,7 +13,7 @@ #include #include -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.2" /* Addresses to scan */ static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END }; @@ -39,14 +39,6 @@ static int rs5c372_attach(struct i2c_adapter *adapter); static int rs5c372_detach(struct i2c_client *client); static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind); -struct rs5c372 { - u8 reg_addr; - u8 regs[17]; - struct i2c_msg msg[1]; - struct i2c_client client; - struct rtc_device *rtc; -}; - static struct i2c_driver rs5c372_driver = { .driver = { .name = "rs5c372", @@ -57,16 +49,18 @@ static struct i2c_driver rs5c372_driver = { static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) { + unsigned char buf[7] = { RS5C372_REG_BASE }; - struct rs5c372 *rs5c372 = i2c_get_clientdata(client); - u8 *buf = &(rs5c372->regs[1]); - - /* this implements the 3rd reading method, according - * to the datasheet. rs5c372 defaults to internal - * address 0xF, so 0x0 is in regs[1] + /* this implements the 1st reading method, according + * to the datasheet. buf[0] is initialized with + * address ptr and transmission format register. */ + struct i2c_msg msgs[] = { + { client->addr, 0, 1, buf }, + { client->addr, I2C_M_RD, 7, buf }, + }; - if ((i2c_transfer(client->adapter, rs5c372->msg, 1)) != 1) { + if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { dev_err(&client->dev, "%s: read error\n", __FUNCTION__); return -EIO; } @@ -120,14 +114,23 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) { - struct rs5c372 *rs5c372 = i2c_get_clientdata(client); - u8 tmp = rs5c372->regs[RS5C372_REG_TRIM + 1]; + unsigned char buf = RS5C372_REG_TRIM; + + struct i2c_msg msgs[] = { + { client->addr, 0, 1, &buf }, + { client->addr, I2C_M_RD, 1, &buf }, + }; + + if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { + dev_err(&client->dev, "%s: read error\n", __FUNCTION__); + return -EIO; + } if (osc) - *osc = (tmp & RS5C372_TRIM_XSL) ? 32000 : 32768; + *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768; if (trim) { - *trim = tmp & RS5C372_TRIM_MASK; + *trim = buf & RS5C372_TRIM_MASK; dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim); } @@ -198,7 +201,7 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) { int err = 0; struct i2c_client *client; - struct rs5c372 *rs5c372; + struct rtc_device *rtc; dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); @@ -207,11 +210,10 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) goto exit; } - if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) { + if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - client = &rs5c372->client; /* I2C client */ client->addr = address; @@ -220,47 +222,32 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) strlcpy(client->name, rs5c372_driver.driver.name, I2C_NAME_SIZE); - i2c_set_clientdata(client, rs5c372); - - rs5c372->msg[0].addr = address; - rs5c372->msg[0].flags = I2C_M_RD; - rs5c372->msg[0].len = sizeof(rs5c372->regs); - rs5c372->msg[0].buf = rs5c372->regs; - /* Inform the i2c layer */ if ((err = i2c_attach_client(client))) goto exit_kfree; dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - rs5c372->rtc = rtc_device_register(rs5c372_driver.driver.name, - &client->dev, &rs5c372_rtc_ops, THIS_MODULE); + rtc = rtc_device_register(rs5c372_driver.driver.name, &client->dev, + &rs5c372_rtc_ops, THIS_MODULE); - if (IS_ERR(rs5c372->rtc)) { - err = PTR_ERR(rs5c372->rtc); + if (IS_ERR(rtc)) { + err = PTR_ERR(rtc); goto exit_detach; } - err = device_create_file(&client->dev, &dev_attr_trim); - if (err) - goto exit_devreg; - err = device_create_file(&client->dev, &dev_attr_osc); - if (err) - goto exit_trim; + i2c_set_clientdata(client, rtc); - return 0; - -exit_trim: - device_remove_file(&client->dev, &dev_attr_trim); + device_create_file(&client->dev, &dev_attr_trim); + device_create_file(&client->dev, &dev_attr_osc); -exit_devreg: - rtc_device_unregister(rs5c372->rtc); + return 0; exit_detach: i2c_detach_client(client); exit_kfree: - kfree(rs5c372); + kfree(client); exit: return err; @@ -269,15 +256,16 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) static int rs5c372_detach(struct i2c_client *client) { int err; - struct rs5c372 *rs5c372 = i2c_get_clientdata(client); + struct rtc_device *rtc = i2c_get_clientdata(client); - if (rs5c372->rtc) - rtc_device_unregister(rs5c372->rtc); + if (rtc) + rtc_device_unregister(rtc); if ((err = i2c_detach_client(client))) return err; - kfree(rs5c372); + kfree(client); + return 0; } diff --git a/trunk/drivers/rtc/rtc-test.c b/trunk/drivers/rtc/rtc-test.c index f50a1b8e1607..6ef9c62d5032 100644 --- a/trunk/drivers/rtc/rtc-test.c +++ b/trunk/drivers/rtc/rtc-test.c @@ -123,18 +123,11 @@ static int test_probe(struct platform_device *plat_dev) err = PTR_ERR(rtc); return err; } - - err = device_create_file(&plat_dev->dev, &dev_attr_irq); - if (err) - goto err; + device_create_file(&plat_dev->dev, &dev_attr_irq); platform_set_drvdata(plat_dev, rtc); return 0; - -err: - rtc_device_unregister(rtc); - return err; } static int __devexit test_remove(struct platform_device *plat_dev) diff --git a/trunk/drivers/rtc/rtc-x1205.c b/trunk/drivers/rtc/rtc-x1205.c index 9a67487d086b..522c69753bbf 100644 --- a/trunk/drivers/rtc/rtc-x1205.c +++ b/trunk/drivers/rtc/rtc-x1205.c @@ -562,19 +562,11 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) else dev_err(&client->dev, "couldn't read status\n"); - err = device_create_file(&client->dev, &dev_attr_atrim); - if (err) goto exit_devreg; - err = device_create_file(&client->dev, &dev_attr_dtrim); - if (err) goto exit_atrim; + device_create_file(&client->dev, &dev_attr_atrim); + device_create_file(&client->dev, &dev_attr_dtrim); return 0; -exit_atrim: - device_remove_file(&client->dev, &dev_attr_atrim); - -exit_devreg: - rtc_device_unregister(rtc); - exit_detach: i2c_detach_client(client); diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index cf28ccc57948..17fdd8c9f740 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -25,7 +25,7 @@ #include "dasd_int.h" -struct kmem_cache *dasd_page_cache; +kmem_cache_t *dasd_page_cache; EXPORT_SYMBOL_GPL(dasd_page_cache); /* diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index fdaa471e845f..5ecea3e4fdef 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -1215,7 +1215,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) dst = page_address(bv->bv_page) + bv->bv_offset; if (dasd_page_cache) { char *copy = kmem_cache_alloc(dasd_page_cache, - GFP_DMA | __GFP_NOWARN); + SLAB_DMA | __GFP_NOWARN); if (copy && rq_data_dir(req) == WRITE) memcpy(copy + bv->bv_offset, dst, bv->bv_len); if (copy) diff --git a/trunk/drivers/s390/block/dasd_fba.c b/trunk/drivers/s390/block/dasd_fba.c index b857fd5893fd..80926c548228 100644 --- a/trunk/drivers/s390/block/dasd_fba.c +++ b/trunk/drivers/s390/block/dasd_fba.c @@ -308,7 +308,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) dst = page_address(bv->bv_page) + bv->bv_offset; if (dasd_page_cache) { char *copy = kmem_cache_alloc(dasd_page_cache, - GFP_DMA | __GFP_NOWARN); + SLAB_DMA | __GFP_NOWARN); if (copy && rq_data_dir(req) == WRITE) memcpy(copy + bv->bv_offset, dst, bv->bv_len); if (copy) diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index dc5dd509434d..9f52004f6fc2 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -474,7 +474,7 @@ extern struct dasd_profile_info_t dasd_global_profile; extern unsigned int dasd_profile_level; extern struct block_device_operations dasd_device_operations; -extern struct kmem_cache *dasd_page_cache; +extern kmem_cache_t *dasd_page_cache; struct dasd_ccw_req * dasd_kmalloc_request(char *, int, int, struct dasd_device *); diff --git a/trunk/drivers/s390/scsi/zfcp_def.h b/trunk/drivers/s390/scsi/zfcp_def.h index 32933ed54b8a..74c0eac083e4 100644 --- a/trunk/drivers/s390/scsi/zfcp_def.h +++ b/trunk/drivers/s390/scsi/zfcp_def.h @@ -1032,9 +1032,9 @@ struct zfcp_data { wwn_t init_wwpn; fcp_lun_t init_fcp_lun; char *driver_version; - struct kmem_cache *fsf_req_qtcb_cache; - struct kmem_cache *sr_buffer_cache; - struct kmem_cache *gid_pn_cache; + kmem_cache_t *fsf_req_qtcb_cache; + kmem_cache_t *sr_buffer_cache; + kmem_cache_t *gid_pn_cache; }; /** diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index 067f1519eb04..277826cdd0c8 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -109,7 +109,7 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags) ptr = kmalloc(size, GFP_ATOMIC); else ptr = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache, - GFP_ATOMIC); + SLAB_ATOMIC); } if (unlikely(!ptr)) diff --git a/trunk/drivers/scsi/53c700.c b/trunk/drivers/scsi/53c700.c index 68103e508db7..335a25540c08 100644 --- a/trunk/drivers/scsi/53c700.c +++ b/trunk/drivers/scsi/53c700.c @@ -313,7 +313,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, hostdata->status = memory + STATUS_OFFSET; /* all of these offsets are L1_CACHE_BYTES separated. It is fatal * if this isn't sufficient separation to avoid dma flushing issues */ - BUG_ON(!dma_is_consistent(hostdata->dev, pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); + BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET); hostdata->dev = dev; @@ -362,11 +362,11 @@ NCR_700_detect(struct scsi_host_template *tpnt, for (j = 0; j < PATCHES; j++) script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]); /* now patch up fixed addresses. */ - script_patch_32(hostdata->dev, script, MessageLocation, + script_patch_32(script, MessageLocation, pScript + MSGOUT_OFFSET); - script_patch_32(hostdata->dev, script, StatusAddress, + script_patch_32(script, StatusAddress, pScript + STATUS_OFFSET); - script_patch_32(hostdata->dev, script, ReceiveMsgAddress, + script_patch_32(script, ReceiveMsgAddress, pScript + MSGIN_OFFSET); hostdata->script = script; @@ -821,9 +821,8 @@ process_extended_message(struct Scsi_Host *host, shost_printk(KERN_WARNING, host, "Unexpected SDTR msg\n"); hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->dev, hostdata->script, - MessageCount, 1); + dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->script, MessageCount, 1); /* SendMsgOut returns, so set up the return * address */ resume_offset = hostdata->pScript + Ent_SendMessageWithATN; @@ -834,9 +833,8 @@ process_extended_message(struct Scsi_Host *host, printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n", host->host_no, pun, lun); hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->dev, hostdata->script, MessageCount, - 1); + dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->script, MessageCount, 1); resume_offset = hostdata->pScript + Ent_SendMessageWithATN; break; @@ -849,9 +847,8 @@ process_extended_message(struct Scsi_Host *host, printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->dev, hostdata->script, MessageCount, - 1); + dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->script, MessageCount, 1); /* SendMsgOut returns, so set up the return * address */ resume_offset = hostdata->pScript + Ent_SendMessageWithATN; @@ -932,9 +929,8 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->dev, hostdata->script, MessageCount, - 1); + dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->script, MessageCount, 1); /* SendMsgOut returns, so set up the return * address */ resume_offset = hostdata->pScript + Ent_SendMessageWithATN; @@ -943,7 +939,7 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata } NCR_700_writel(temp, host, TEMP_REG); /* set us up to receive another message */ - dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); + dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); return resume_offset; } @@ -1023,9 +1019,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, slot->SG[1].ins = bS_to_host(SCRIPT_RETURN); slot->SG[1].pAddr = 0; slot->resume_offset = hostdata->pScript; - dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE); - dma_cache_sync(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); - + dma_cache_sync(slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE); + dma_cache_sync(SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); + /* queue the command for reissue */ slot->state = NCR_700_SLOT_QUEUED; slot->flags = NCR_700_FLAG_AUTOSENSE; @@ -1140,12 +1136,11 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, hostdata->cmd = slot->cmnd; /* re-patch for this command */ - script_patch_32_abs(hostdata->dev, hostdata->script, - CommandAddress, slot->pCmd); - script_patch_16(hostdata->dev, hostdata->script, + script_patch_32_abs(hostdata->script, CommandAddress, + slot->pCmd); + script_patch_16(hostdata->script, CommandCount, slot->cmnd->cmd_len); - script_patch_32_abs(hostdata->dev, hostdata->script, - SGScriptStartAddress, + script_patch_32_abs(hostdata->script, SGScriptStartAddress, to32bit(&slot->pSG[0].ins)); /* Note: setting SXFER only works if we're @@ -1155,13 +1150,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, * should therefore always clear ACK */ NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device), host, SXFER_REG); - dma_cache_sync(hostdata->dev, hostdata->msgin, + dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); - dma_cache_sync(hostdata->dev, hostdata->msgout, + dma_cache_sync(hostdata->msgout, MSG_ARRAY_SIZE, DMA_TO_DEVICE); /* I'm just being paranoid here, the command should * already have been flushed from the cache */ - dma_cache_sync(hostdata->dev, slot->cmnd->cmnd, + dma_cache_sync(slot->cmnd->cmnd, slot->cmnd->cmd_len, DMA_TO_DEVICE); @@ -1225,7 +1220,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, hostdata->reselection_id = reselection_id; /* just in case we have a stale simple tag message, clear it */ hostdata->msgin[1] = 0; - dma_cache_sync(hostdata->dev, hostdata->msgin, + dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL); if(hostdata->tag_negotiated & (1<pScript + Ent_GetReselectionWithTag; @@ -1341,7 +1336,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp) hostdata->cmd = NULL; /* clear any stale simple tag message */ hostdata->msgin[1] = 0; - dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, + dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL); if(id == 0xff) { @@ -1438,30 +1433,29 @@ NCR_700_start_command(struct scsi_cmnd *SCp) NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } - script_patch_16(hostdata->dev, hostdata->script, MessageCount, count); + script_patch_16(hostdata->script, MessageCount, count); - script_patch_ID(hostdata->dev, hostdata->script, + script_patch_ID(hostdata->script, Device_ID, 1<dev, hostdata->script, CommandAddress, + script_patch_32_abs(hostdata->script, CommandAddress, slot->pCmd); - script_patch_16(hostdata->dev, hostdata->script, CommandCount, - SCp->cmd_len); + script_patch_16(hostdata->script, CommandCount, SCp->cmd_len); /* finally plumb the beginning of the SG list into the script * */ - script_patch_32_abs(hostdata->dev, hostdata->script, - SGScriptStartAddress, to32bit(&slot->pSG[0].ins)); + script_patch_32_abs(hostdata->script, SGScriptStartAddress, + to32bit(&slot->pSG[0].ins)); NCR_700_clear_fifo(SCp->device->host); if(slot->resume_offset == 0) slot->resume_offset = hostdata->pScript; /* now perform all the writebacks and invalidates */ - dma_cache_sync(hostdata->dev, hostdata->msgout, count, DMA_TO_DEVICE); - dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, + dma_cache_sync(hostdata->msgout, count, DMA_TO_DEVICE); + dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); - dma_cache_sync(hostdata->dev, SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE); - dma_cache_sync(hostdata->dev, hostdata->status, 1, DMA_FROM_DEVICE); + dma_cache_sync(SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE); + dma_cache_sync(hostdata->status, 1, DMA_FROM_DEVICE); /* set the synchronous period/offset */ NCR_700_writeb(NCR_700_get_SXFER(SCp->device), @@ -1637,7 +1631,7 @@ NCR_700_intr(int irq, void *dev_id) slot->SG[i].ins = bS_to_host(SCRIPT_NOP); slot->SG[i].pAddr = 0; } - dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); + dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); /* and pretend we disconnected after * the command phase */ resume_offset = hostdata->pScript + Ent_MsgInDuringData; @@ -1903,9 +1897,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) } slot->SG[i].ins = bS_to_host(SCRIPT_RETURN); slot->SG[i].pAddr = 0; - dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); + dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); DEBUG((" SETTING %08lx to %x\n", - (&slot->pSG[i].ins), + (&slot->pSG[i].ins), slot->SG[i].ins)); } slot->resume_offset = 0; diff --git a/trunk/drivers/scsi/53c700.h b/trunk/drivers/scsi/53c700.h index f38822db4210..f5c3caf344a7 100644 --- a/trunk/drivers/scsi/53c700.h +++ b/trunk/drivers/scsi/53c700.h @@ -415,31 +415,31 @@ struct NCR_700_Host_Parameters { #define NCR_710_MIN_XFERP 0 #define NCR_700_MIN_PERIOD 25 /* for SDTR message, 100ns */ -#define script_patch_32(dev, script, symbol, value) \ +#define script_patch_32(script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ __u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]) + value; \ (script)[A_##symbol##_used[i]] = bS_to_host(val); \ - dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching %s at %d to 0x%lx\n", \ #symbol, A_##symbol##_used[i], (value))); \ } \ } -#define script_patch_32_abs(dev, script, symbol, value) \ +#define script_patch_32_abs(script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ (script)[A_##symbol##_used[i]] = bS_to_host(value); \ - dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching %s at %d to 0x%lx\n", \ #symbol, A_##symbol##_used[i], (value))); \ } \ } /* Used for patching the SCSI ID in the SELECT instruction */ -#define script_patch_ID(dev, script, symbol, value) \ +#define script_patch_ID(script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ @@ -447,13 +447,13 @@ struct NCR_700_Host_Parameters { val &= 0xff00ffff; \ val |= ((value) & 0xff) << 16; \ (script)[A_##symbol##_used[i]] = bS_to_host(val); \ - dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching ID field %s at %d to 0x%x\n", \ #symbol, A_##symbol##_used[i], val)); \ } \ } -#define script_patch_16(dev, script, symbol, value) \ +#define script_patch_16(script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ @@ -461,7 +461,7 @@ struct NCR_700_Host_Parameters { val &= 0xffff0000; \ val |= ((value) & 0xffff); \ (script)[A_##symbol##_used[i]] = bS_to_host(val); \ - dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching short field %s at %d to 0x%x\n", \ #symbol, A_##symbol##_used[i], val)); \ } \ diff --git a/trunk/drivers/scsi/aic94xx/aic94xx.h b/trunk/drivers/scsi/aic94xx/aic94xx.h index 32f513b1b78a..71a031df7a34 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx.h +++ b/trunk/drivers/scsi/aic94xx/aic94xx.h @@ -56,8 +56,8 @@ /* 2*ITNL timeout + 1 second */ #define AIC94XX_SCB_TIMEOUT (5*HZ) -extern struct kmem_cache *asd_dma_token_cache; -extern struct kmem_cache *asd_ascb_cache; +extern kmem_cache_t *asd_dma_token_cache; +extern kmem_cache_t *asd_ascb_cache; extern char sas_addr_str[2*SAS_ADDR_SIZE + 1]; static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr) diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c index da94e126ca83..af7e01134364 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -1047,7 +1047,7 @@ irqreturn_t asd_hw_isr(int irq, void *dev_id) static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha, gfp_t gfp_flags) { - extern struct kmem_cache *asd_ascb_cache; + extern kmem_cache_t *asd_ascb_cache; struct asd_seq_data *seq = &asd_ha->seq; struct asd_ascb *ascb; unsigned long flags; diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_init.c b/trunk/drivers/scsi/aic94xx/aic94xx_init.c index fbc82b00a418..42302ef05ee5 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_init.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_init.c @@ -450,8 +450,8 @@ static inline void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha) asd_ha->scb_pool = NULL; } -struct kmem_cache *asd_dma_token_cache; -struct kmem_cache *asd_ascb_cache; +kmem_cache_t *asd_dma_token_cache; +kmem_cache_t *asd_ascb_cache; static int asd_create_global_caches(void) { diff --git a/trunk/drivers/scsi/ide-scsi.c b/trunk/drivers/scsi/ide-scsi.c index 8f6b5bf580f6..1427a41e8441 100644 --- a/trunk/drivers/scsi/ide-scsi.c +++ b/trunk/drivers/scsi/ide-scsi.c @@ -110,7 +110,6 @@ typedef struct ide_scsi_obj { } idescsi_scsi_t; static DEFINE_MUTEX(idescsi_ref_mutex); -static int idescsi_nocd; /* Set by module param to skip cd */ #define ide_scsi_g(disk) \ container_of((disk)->private_data, struct ide_scsi_obj, driver) @@ -1128,9 +1127,6 @@ static int ide_scsi_probe(ide_drive_t *drive) warned = 1; } - if (idescsi_nocd && drive->media == ide_cdrom) - return -ENODEV; - if (!strstr("ide-scsi", drive->driver_req) || !drive->present || drive->media == ide_disk || @@ -1191,8 +1187,6 @@ static void __exit exit_idescsi_module(void) driver_unregister(&idescsi_driver.gen_driver); } -module_param(idescsi_nocd, int, 0600); -MODULE_PARM_DESC(idescsi_nocd, "Disable handling of CD-ROMs so they may be driven by ide-cd"); module_init(init_idescsi_module); module_exit(exit_idescsi_module); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index b318500785e5..ccd4dafce8e2 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -6940,7 +6940,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) return -ENOMEM; for (i = 0; i < IPR_NUM_CMD_BLKS; i++) { - ipr_cmd = pci_pool_alloc (ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr); + ipr_cmd = pci_pool_alloc (ioa_cfg->ipr_cmd_pool, SLAB_KERNEL, &dma_addr); if (!ipr_cmd) { ipr_free_cmd_blks(ioa_cfg); diff --git a/trunk/drivers/scsi/libsas/sas_init.c b/trunk/drivers/scsi/libsas/sas_init.c index 2f0c07fc3f48..d65bc4e0f214 100644 --- a/trunk/drivers/scsi/libsas/sas_init.c +++ b/trunk/drivers/scsi/libsas/sas_init.c @@ -36,7 +36,7 @@ #include "../scsi_sas_internal.h" -struct kmem_cache *sas_task_cache; +kmem_cache_t *sas_task_cache; /*------------ SAS addr hash -----------*/ void sas_hash_addr(u8 *hashed, const u8 *sas_addr) diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index d03523d3bf38..cbe0cad83b68 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -24,7 +24,7 @@ char qla2x00_version_str[40]; /* * SRB allocation cache */ -static struct kmem_cache *srb_cachep; +static kmem_cache_t *srb_cachep; /* * Ioctl related information. diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index 9ef693c8809a..969c9e431028 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -19,7 +19,7 @@ char qla4xxx_version_str[40]; /* * SRB allocation cache */ -static struct kmem_cache *srb_cachep; +static kmem_cache_t *srb_cachep; /* * Module parameter information and variables diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 24cffd98ee63..fafc00deaade 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -136,7 +136,7 @@ const char * scsi_device_type(unsigned type) EXPORT_SYMBOL(scsi_device_type); struct scsi_host_cmd_pool { - struct kmem_cache *slab; + kmem_cache_t *slab; unsigned int users; char *name; unsigned int slab_flags; diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 1748e27501cd..fb616c69151f 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -36,7 +36,7 @@ struct scsi_host_sg_pool { size_t size; char *name; - struct kmem_cache *slab; + kmem_cache_t *slab; mempool_t *pool; }; @@ -241,7 +241,7 @@ struct scsi_io_context { char sense[SCSI_SENSE_BUFFERSIZE]; }; -static struct kmem_cache *scsi_io_context_cache; +static kmem_cache_t *scsi_io_context_cache; static void scsi_end_async(struct request *req, int uptodate) { diff --git a/trunk/drivers/scsi/scsi_tgt_lib.c b/trunk/drivers/scsi/scsi_tgt_lib.c index d402aff5f314..386dbae17b44 100644 --- a/trunk/drivers/scsi/scsi_tgt_lib.c +++ b/trunk/drivers/scsi/scsi_tgt_lib.c @@ -33,7 +33,7 @@ #include "scsi_tgt_priv.h" static struct workqueue_struct *scsi_tgtd; -static struct kmem_cache *scsi_tgt_cmd_cache; +static kmem_cache_t *scsi_tgt_cmd_cache; /* * TODO: this struct will be killed when the block layer supports large bios diff --git a/trunk/drivers/serial/8250_exar_st16c554.c b/trunk/drivers/serial/8250_exar_st16c554.c deleted file mode 100644 index 567143ace159..000000000000 --- a/trunk/drivers/serial/8250_exar_st16c554.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * linux/drivers/serial/8250_exar.c - * - * Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com > - * Based on 8250_boca. - * - * Copyright (C) 2005 Russell King. - * Data taken from include/asm-i386/serial.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -#define PORT(_base,_irq) \ - { \ - .iobase = _base, \ - .irq = _irq, \ - .uartclk = 1843200, \ - .iotype = UPIO_PORT, \ - .flags = UPF_BOOT_AUTOCONF, \ - } - -static struct plat_serial8250_port exar_data[] = { - PORT(0x100, 5), - PORT(0x108, 5), - PORT(0x110, 5), - PORT(0x118, 5), - { }, -}; - -static struct platform_device exar_device = { - .name = "serial8250", - .id = PLAT8250_DEV_EXAR_ST16C554, - .dev = { - .platform_data = exar_data, - }, -}; - -static int __init exar_init(void) -{ - return platform_device_register(&exar_device); -} - -module_init(exar_init); - -MODULE_AUTHOR("Paul B Schroeder"); -MODULE_DESCRIPTION("8250 serial probe module for Exar cards"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/serial/8250_pnp.c b/trunk/drivers/serial/8250_pnp.c index d3d6b82706b5..71d907c8288b 100644 --- a/trunk/drivers/serial/8250_pnp.c +++ b/trunk/drivers/serial/8250_pnp.c @@ -464,38 +464,11 @@ static void __devexit serial_pnp_remove(struct pnp_dev *dev) serial8250_unregister_port(line - 1); } -#ifdef CONFIG_PM -static int serial_pnp_suspend(struct pnp_dev *dev, pm_message_t state) -{ - long line = (long)pnp_get_drvdata(dev); - - if (!line) - return -ENODEV; - serial8250_suspend_port(line - 1); - return 0; -} - -static int serial_pnp_resume(struct pnp_dev *dev) -{ - long line = (long)pnp_get_drvdata(dev); - - if (!line) - return -ENODEV; - serial8250_resume_port(line - 1); - return 0; -} -#else -#define serial_pnp_suspend NULL -#define serial_pnp_resume NULL -#endif /* CONFIG_PM */ - static struct pnp_driver serial_pnp_driver = { .name = "serial", + .id_table = pnp_dev_table, .probe = serial_pnp_probe, .remove = __devexit_p(serial_pnp_remove), - .suspend = serial_pnp_suspend, - .resume = serial_pnp_resume, - .id_table = pnp_dev_table, }; static int __init serial8250_pnp_init(void) diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index fc12d5df10e2..0b71e7d18903 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -210,17 +210,6 @@ config SERIAL_8250_BOCA To compile this driver as a module, choose M here: the module will be called 8250_boca. -config SERIAL_8250_EXAR_ST16C554 - tristate "Support Exar ST16C554/554D Quad UART" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - The Uplogix Envoy TU301 uses this Exar Quad UART. If you are - tinkering with your Envoy TU301, or have a machine with this UART, - say Y here. - - To compile this driver as a module, choose M here: the module - will be called 8250_exar_st16c554. - config SERIAL_8250_HUB6 tristate "Support Hub6 cards" depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS @@ -522,25 +511,6 @@ config SERIAL_IMX_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_UARTLITE - tristate "Xilinx uartlite serial port support" - depends on PPC32 - select SERIAL_CORE - help - Say Y here if you want to use the Xilinx uartlite serial controller. - - To compile this driver as a module, choose M here: the - module will be called uartlite.ko. - -config SERIAL_UARTLITE_CONSOLE - bool "Support for console on Xilinx uartlite serial port" - depends on SERIAL_UARTLITE=y - select SERIAL_CORE_CONSOLE - help - Say Y here if you wish to use a Xilinx uartlite as the system - console (the system console is the device which receives all kernel - messages and warnings and which allows logins in single user mode). - config SERIAL_SUNCORE bool depends on SPARC diff --git a/trunk/drivers/serial/Makefile b/trunk/drivers/serial/Makefile index df3632cd7df9..b4d8a7c182e3 100644 --- a/trunk/drivers/serial/Makefile +++ b/trunk/drivers/serial/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o -obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o @@ -56,5 +55,4 @@ obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o -obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o diff --git a/trunk/drivers/serial/amba-pl010.c b/trunk/drivers/serial/amba-pl010.c index 4d3626ef4643..4213fabc62bf 100644 --- a/trunk/drivers/serial/amba-pl010.c +++ b/trunk/drivers/serial/amba-pl010.c @@ -129,8 +129,6 @@ static void pl010_rx_chars(struct uart_port *port) */ rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX; if (unlikely(rsr & UART01x_RSR_ANY)) { - writel(0, port->membase + UART01x_ECR); - if (rsr & UART01x_RSR_BE) { rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); port->icount.brk++; diff --git a/trunk/drivers/serial/dz.c b/trunk/drivers/serial/dz.c index af1544f3356f..53662b33b841 100644 --- a/trunk/drivers/serial/dz.c +++ b/trunk/drivers/serial/dz.c @@ -1,13 +1,11 @@ /* - * dz.c: Serial port driver for DECstations equipped + * dz.c: Serial port driver for DECStations equiped * with the DZ chipset. * * Copyright (C) 1998 Olivier A. D. Lebaillif * * Email: olivier.lebaillif@ifrsys.com * - * Copyright (C) 2004, 2006 Maciej W. Rozycki - * * [31-AUG-98] triemer * Changed IRQ to use Harald's dec internals interrupts.h * removed base_addr code - moving address assignment to setup.c @@ -28,16 +26,10 @@ #undef DEBUG_DZ -#if defined(CONFIG_SERIAL_DZ_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include #include #include #include #include -#include #include #include #include @@ -53,10 +45,14 @@ #include #include +#define CONSOLE_LINE (3) /* for definition of struct console */ + #include "dz.h" +#define DZ_INTR_DEBUG 1 + static char *dz_name = "DECstation DZ serial driver version "; -static char *dz_version = "1.03"; +static char *dz_version = "1.02"; struct dz_port { struct uart_port port; @@ -65,6 +61,22 @@ struct dz_port { static struct dz_port dz_ports[DZ_NB_PORT]; +#ifdef DEBUG_DZ +/* + * debugging code to send out chars via prom + */ +static void debug_console(const char *s, int count) +{ + unsigned i; + + for (i = 0; i < count; i++) { + if (*s == 10) + prom_printf("%c", 13); + prom_printf("%c", *s++); + } +} +#endif + /* * ------------------------------------------------------------ * dz_in () and dz_out () @@ -78,7 +90,6 @@ static inline unsigned short dz_in(struct dz_port *dport, unsigned offset) { volatile unsigned short *addr = (volatile unsigned short *) (dport->port.membase + offset); - return *addr; } @@ -87,7 +98,6 @@ static inline void dz_out(struct dz_port *dport, unsigned offset, { volatile unsigned short *addr = (volatile unsigned short *) (dport->port.membase + offset); - *addr = value; } @@ -134,7 +144,7 @@ static void dz_stop_rx(struct uart_port *uport) spin_lock_irqsave(&dport->port.lock, flags); dport->cflag &= ~DZ_CREAD; - dz_out(dport, DZ_LPR, dport->cflag | dport->port.line); + dz_out(dport, DZ_LPR, dport->cflag); spin_unlock_irqrestore(&dport->port.lock, flags); } @@ -145,14 +155,14 @@ static void dz_enable_ms(struct uart_port *port) /* * ------------------------------------------------------------ + * Here starts the interrupt handling routines. All of the + * following subroutines are declared as inline and are folded + * into dz_interrupt. They were separated out for readability's + * sake. * - * Here start the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * dz_interrupt. They were separated out for readability's sake. - * - * Note: dz_interrupt() is a "fast" interrupt, which means that it + * Note: rs_interrupt() is a "fast" interrupt, which means that it * runs with interrupts turned off. People who may want to modify - * dz_interrupt() should try to keep the interrupt handler as fast as + * rs_interrupt() should try to keep the interrupt handler as fast as * possible. After you are done making modifications, it is not a bad * idea to do: * @@ -170,74 +180,92 @@ static void dz_enable_ms(struct uart_port *port) * This routine deals with inputs from any lines. * ------------------------------------------------------------ */ -static inline void dz_receive_chars(struct dz_port *dport_in, - struct pt_regs *regs) +static inline void dz_receive_chars(struct dz_port *dport) { - struct dz_port *dport; struct tty_struct *tty = NULL; struct uart_icount *icount; - int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; - unsigned short status; + int ignore = 0; + unsigned short status, tmp; unsigned char ch, flag; - int i; - while ((status = dz_in(dport_in, DZ_RBUF)) & DZ_DVAL) { - dport = &dz_ports[LINE(status)]; - tty = dport->port.info->tty; /* point to the proper dev */ + /* this code is going to be a problem... + the call to tty_flip_buffer is going to need + to be rethought... + */ + do { + status = dz_in(dport, DZ_RBUF); - ch = UCHAR(status); /* grab the char */ + /* punt so we don't get duplicate characters */ + if (!(status & DZ_DVAL)) + goto ignore_char; - icount = &dport->port.icount; - icount->rx++; + ch = UCHAR(status); /* grab the char */ flag = TTY_NORMAL; - if (status & DZ_FERR) { /* frame error */ - /* - * There is no separate BREAK status bit, so - * treat framing errors as BREAKs for Magic SysRq - * and SAK; normally, otherwise. - */ - if (uart_handle_break(&dport->port)) - continue; - if (dport->port.flags & UPF_SAK) - flag = TTY_BREAK; - else - flag = TTY_FRAME; - } else if (status & DZ_OERR) /* overrun error */ - flag = TTY_OVERRUN; - else if (status & DZ_PERR) /* parity error */ - flag = TTY_PARITY; - /* keep track of the statistics */ - switch (flag) { - case TTY_FRAME: - icount->frame++; - break; - case TTY_PARITY: - icount->parity++; - break; - case TTY_OVERRUN: - icount->overrun++; - break; - case TTY_BREAK: - icount->brk++; - break; - default: - break; +#if 0 + if (info->is_console) { + if (ch == 0) + return; /* it's a break ... */ } +#endif - if (uart_handle_sysrq_char(&dport->port, ch, regs)) - continue; + tty = dport->port.info->tty;/* now tty points to the proper dev */ + icount = &dport->port.icount; + + if (!tty) + break; - if ((status & dport->port.ignore_status_mask) == 0) { - uart_insert_char(&dport->port, - status, DZ_OERR, ch, flag); - lines_rx[LINE(status)] = 1; + icount->rx++; + + /* keep track of the statistics */ + if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) { + if (status & DZ_PERR) /* parity error */ + icount->parity++; + else if (status & DZ_FERR) /* frame error */ + icount->frame++; + if (status & DZ_OERR) /* overrun error */ + icount->overrun++; + + /* check to see if we should ignore the character + and mask off conditions that should be ignored + */ + + if (status & dport->port.ignore_status_mask) { + if (++ignore > 100) + break; + goto ignore_char; + } + /* mask off the error conditions we want to ignore */ + tmp = status & dport->port.read_status_mask; + + if (tmp & DZ_PERR) { + flag = TTY_PARITY; +#ifdef DEBUG_DZ + debug_console("PERR\n", 5); +#endif + } else if (tmp & DZ_FERR) { + flag = TTY_FRAME; +#ifdef DEBUG_DZ + debug_console("FERR\n", 5); +#endif + } + if (tmp & DZ_OERR) { +#ifdef DEBUG_DZ + debug_console("OERR\n", 5); +#endif + tty_insert_flip_char(tty, ch, flag); + ch = 0; + flag = TTY_OVERRUN; + } } - } - for (i = 0; i < DZ_NB_PORT; i++) - if (lines_rx[i]) - tty_flip_buffer_push(dz_ports[i].port.info->tty); + tty_insert_flip_char(tty, ch, flag); + ignore_char: + ; + } while (status & DZ_DVAL); + + if (tty) + tty_flip_buffer_push(tty); } /* @@ -247,32 +275,26 @@ static inline void dz_receive_chars(struct dz_port *dport_in, * This routine deals with outputs to any lines. * ------------------------------------------------------------ */ -static inline void dz_transmit_chars(struct dz_port *dport_in) +static inline void dz_transmit_chars(struct dz_port *dport) { - struct dz_port *dport; - struct circ_buf *xmit; - unsigned short status; + struct circ_buf *xmit = &dport->port.info->xmit; unsigned char tmp; - status = dz_in(dport_in, DZ_CSR); - dport = &dz_ports[LINE(status)]; - xmit = &dport->port.info->xmit; - - if (dport->port.x_char) { /* XON/XOFF chars */ + if (dport->port.x_char) { /* XON/XOFF chars */ dz_out(dport, DZ_TDR, dport->port.x_char); dport->port.icount.tx++; dport->port.x_char = 0; return; } - /* If nothing to do or stopped or hardware stopped. */ + /* if nothing to do or stopped or hardware stopped */ if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) { dz_stop_tx(&dport->port); return; } /* - * If something to do... (remember the dz has no output fifo, - * so we go one char at a time) :-< + * if something to do ... (rember the dz has no output fifo so we go + * one char at a time :-< */ tmp = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1); @@ -282,29 +304,23 @@ static inline void dz_transmit_chars(struct dz_port *dport_in) if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS) uart_write_wakeup(&dport->port); - /* Are we are done. */ + /* Are we done */ if (uart_circ_empty(xmit)) dz_stop_tx(&dport->port); } /* * ------------------------------------------------------------ - * check_modem_status() + * check_modem_status () * - * DS 3100 & 5100: Only valid for the MODEM line, duh! - * DS 5000/200: Valid for the MODEM and PRINTER line. + * Only valid for the MODEM line duh ! * ------------------------------------------------------------ */ static inline void check_modem_status(struct dz_port *dport) { - /* - * FIXME: - * 1. No status change interrupt; use a timer. - * 2. Handle the 3100/5000 as appropriate. --macro - */ unsigned short status; - /* If not the modem line just return. */ + /* if not ne modem line just return */ if (dport->port.line != DZ_MODEM) return; @@ -325,18 +341,21 @@ static inline void check_modem_status(struct dz_port *dport) */ static irqreturn_t dz_interrupt(int irq, void *dev) { - struct dz_port *dport = (struct dz_port *)dev; + struct dz_port *dport; unsigned short status; /* get the reason why we just got an irq */ - status = dz_in(dport, DZ_CSR); + status = dz_in((struct dz_port *)dev, DZ_CSR); + dport = &dz_ports[LINE(status)]; - if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE)) - dz_receive_chars(dport, regs); + if (status & DZ_RDONE) + dz_receive_chars(dport); - if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE)) + if (status & DZ_TRDY) dz_transmit_chars(dport); + /* FIXME: what about check modem status??? --rmk */ + return IRQ_HANDLED; } @@ -348,13 +367,13 @@ static irqreturn_t dz_interrupt(int irq, void *dev) static unsigned int dz_get_mctrl(struct uart_port *uport) { - /* - * FIXME: Handle the 3100/5000 as appropriate. --macro - */ struct dz_port *dport = (struct dz_port *)uport; unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; if (dport->port.line == DZ_MODEM) { + /* + * CHECKME: This is a guess from the other code... --rmk + */ if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR) mctrl &= ~TIOCM_DSR; } @@ -364,9 +383,6 @@ static unsigned int dz_get_mctrl(struct uart_port *uport) static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl) { - /* - * FIXME: Handle the 3100/5000 as appropriate. --macro - */ struct dz_port *dport = (struct dz_port *)uport; unsigned short tmp; @@ -393,6 +409,13 @@ static int dz_startup(struct uart_port *uport) unsigned long flags; unsigned short tmp; + /* The dz lines for the mouse/keyboard must be + * opened using their respective drivers. + */ + if ((dport->port.line == DZ_KEYBOARD) || + (dport->port.line == DZ_MOUSE)) + return -ENODEV; + spin_lock_irqsave(&dport->port.lock, flags); /* enable the interrupt and the scanning */ @@ -419,8 +442,7 @@ static void dz_shutdown(struct uart_port *uport) } /* - * ------------------------------------------------------------------- - * dz_tx_empty() -- get the transmitter empty status + * get_lsr_info - get line status register info * * Purpose: Let user call ioctl() to get info when the UART physically * is emptied. On bus types like RS485, the transmitter must @@ -428,28 +450,21 @@ static void dz_shutdown(struct uart_port *uport) * the transmit shift register is empty, not be done when the * transmit holding register is empty. This functionality * allows an RS485 driver to be written in user space. - * ------------------------------------------------------------------- */ static unsigned int dz_tx_empty(struct uart_port *uport) { struct dz_port *dport = (struct dz_port *)uport; - unsigned short tmp, mask = 1 << dport->port.line; + unsigned short status = dz_in(dport, DZ_LPR); - tmp = dz_in(dport, DZ_TCR); - tmp &= mask; - - return tmp ? 0 : TIOCSER_TEMT; + /* FIXME: this appears to be obviously broken --rmk. */ + return status ? TIOCSER_TEMT : 0; } static void dz_break_ctl(struct uart_port *uport, int break_state) { - /* - * FIXME: Can't access BREAK bits in TDR easily; - * reuse the code for polled TX. --macro - */ struct dz_port *dport = (struct dz_port *)uport; unsigned long flags; - unsigned short tmp, mask = 1 << dport->port.line; + unsigned short tmp, mask = 1 << uport->line; spin_lock_irqsave(&uport->lock, flags); tmp = dz_in(dport, DZ_TCR); @@ -546,7 +561,7 @@ static void dz_set_termios(struct uart_port *uport, struct termios *termios, spin_lock_irqsave(&dport->port.lock, flags); - dz_out(dport, DZ_LPR, cflag | dport->port.line); + dz_out(dport, DZ_LPR, cflag); dport->cflag = cflag; /* setup accept flag */ @@ -635,7 +650,7 @@ static void __init dz_init_ports(void) for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { spin_lock_init(&dport->port.lock); dport->port.membase = (char *) base; - dport->port.iotype = UPIO_MEM; + dport->port.iotype = UPIO_PORT; dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; dport->port.line = i; dport->port.fifosize = 1; @@ -647,7 +662,10 @@ static void __init dz_init_ports(void) static void dz_reset(struct dz_port *dport) { dz_out(dport, DZ_CSR, DZ_CLR); + while (dz_in(dport, DZ_CSR) & DZ_CLR); + /* FIXME: cpu_relax? */ + iob(); /* enable scanning */ @@ -655,55 +673,26 @@ static void dz_reset(struct dz_port *dport) } #ifdef CONFIG_SERIAL_DZ_CONSOLE -/* - * ------------------------------------------------------------------- - * dz_console_putchar() -- transmit a character - * - * Polled transmission. This is tricky. We need to mask transmit - * interrupts so that they do not interfere, enable the transmitter - * for the line requested and then wait till the transmit scanner - * requests data for this line. But it may request data for another - * line first, in which case we have to disable its transmitter and - * repeat waiting till our line pops up. Only then the character may - * be transmitted. Finally, the state of the transmitter mask is - * restored. Welcome to the world of PDP-11! - * ------------------------------------------------------------------- - */ static void dz_console_putchar(struct uart_port *uport, int ch) { struct dz_port *dport = (struct dz_port *)uport; unsigned long flags; - unsigned short csr, tcr, trdy, mask; - int loops = 10000; + int loops = 2500; + unsigned short tmp = (unsigned char)ch; + /* this code sends stuff out to serial device - spinning its + wheels and waiting. */ spin_lock_irqsave(&dport->port.lock, flags); - csr = dz_in(dport, DZ_CSR); - dz_out(dport, DZ_CSR, csr & ~DZ_TIE); - tcr = dz_in(dport, DZ_TCR); - tcr |= 1 << dport->port.line; - mask = tcr; - dz_out(dport, DZ_TCR, mask); - iob(); - spin_unlock_irqrestore(&dport->port.lock, flags); - while (loops--) { - trdy = dz_in(dport, DZ_CSR); - if (!(trdy & DZ_TRDY)) - continue; - trdy = (trdy & DZ_TLINE) >> 8; - if (trdy == dport->port.line) - break; - mask &= ~(1 << trdy); - dz_out(dport, DZ_TCR, mask); - iob(); - udelay(2); - } + /* spin our wheels */ + while (((dz_in(dport, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--) + /* FIXME: cpu_relax, udelay? --rmk */ + ; - if (loops) /* Cannot send otherwise. */ - dz_out(dport, DZ_TDR, ch); + /* Actually transmit the character. */ + dz_out(dport, DZ_TDR, tmp); - dz_out(dport, DZ_TCR, tcr); - dz_out(dport, DZ_CSR, csr); + spin_unlock_irqrestore(&dport->port.lock, flags); } /* @@ -714,11 +703,11 @@ static void dz_console_putchar(struct uart_port *uport, int ch) * The console must be locked when we get here. * ------------------------------------------------------------------- */ -static void dz_console_print(struct console *co, +static void dz_console_print(struct console *cons, const char *str, unsigned int count) { - struct dz_port *dport = &dz_ports[co->index]; + struct dz_port *dport = &dz_ports[CONSOLE_LINE]; #ifdef DEBUG_DZ prom_printf((char *) str); #endif @@ -727,42 +716,48 @@ static void dz_console_print(struct console *co, static int __init dz_console_setup(struct console *co, char *options) { - struct dz_port *dport = &dz_ports[co->index]; + struct dz_port *dport = &dz_ports[CONSOLE_LINE]; int baud = 9600; int bits = 8; int parity = 'n'; int flow = 'n'; + int ret; + unsigned short mask, tmp; if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); dz_reset(dport); - return uart_set_options(&dport->port, co, baud, parity, bits, flow); + ret = uart_set_options(&dport->port, co, baud, parity, bits, flow); + if (ret == 0) { + mask = 1 << dport->port.line; + tmp = dz_in(dport, DZ_TCR); /* read the TX flag */ + if (!(tmp & mask)) { + tmp |= mask; /* set the TX flag */ + dz_out(dport, DZ_TCR, tmp); + } + } + + return ret; } -static struct uart_driver dz_reg; -static struct console dz_sercons = { +static struct console dz_sercons = +{ .name = "ttyS", .write = dz_console_print, .device = uart_console_device, .setup = dz_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &dz_reg, + .flags = CON_CONSDEV | CON_PRINTBUFFER, + .index = CONSOLE_LINE, }; -static int __init dz_serial_console_init(void) +void __init dz_serial_console_init(void) { - if (!IOASIC) { - dz_init_ports(); - register_console(&dz_sercons); - return 0; - } else - return -ENXIO; -} + dz_init_ports(); -console_initcall(dz_serial_console_init); + register_console(&dz_sercons); +} #define SERIAL_DZ_CONSOLE &dz_sercons #else @@ -772,29 +767,35 @@ console_initcall(dz_serial_console_init); static struct uart_driver dz_reg = { .owner = THIS_MODULE, .driver_name = "serial", - .dev_name = "ttyS", + .dev_name = "ttyS%d", .major = TTY_MAJOR, .minor = 64, .nr = DZ_NB_PORT, .cons = SERIAL_DZ_CONSOLE, }; -static int __init dz_init(void) +int __init dz_init(void) { + unsigned long flags; int ret, i; - if (IOASIC) - return -ENXIO; - printk("%s%s\n", dz_name, dz_version); dz_init_ports(); + save_flags(flags); + cli(); + #ifndef CONFIG_SERIAL_DZ_CONSOLE /* reset the chip */ dz_reset(&dz_ports[0]); #endif + /* order matters here... the trick is that flags + is updated... in request_irq - to immediatedly obliterate + it is unwise. */ + restore_flags(flags); + if (request_irq(dz_ports[0].port.irq, dz_interrupt, IRQF_DISABLED, "DZ", &dz_ports[0])) panic("Unable to register DZ interrupt"); @@ -809,7 +810,5 @@ static int __init dz_init(void) return ret; } -module_init(dz_init); - MODULE_DESCRIPTION("DECstation DZ serial driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/serial/dz.h b/trunk/drivers/serial/dz.h index 9674d4e49872..86ef417382bb 100644 --- a/trunk/drivers/serial/dz.h +++ b/trunk/drivers/serial/dz.h @@ -1,22 +1,20 @@ /* - * dz.h: Serial port driver for DECstations equipped + * dz.h: Serial port driver for DECStations equiped * with the DZ chipset. * * Copyright (C) 1998 Olivier A. D. Lebaillif * * Email: olivier.lebaillif@ifrsys.com * - * Copyright (C) 2004, 2006 Maciej W. Rozycki */ #ifndef DZ_SERIAL_H #define DZ_SERIAL_H /* - * Definitions for the Control and Status Register. + * Definitions for the Control and Status Received. */ #define DZ_TRDY 0x8000 /* Transmitter empty */ -#define DZ_TIE 0x4000 /* Transmitter Interrupt Enbl */ -#define DZ_TLINE 0x0300 /* Transmitter Line Number */ +#define DZ_TIE 0x4000 /* Transmitter Interrupt Enable */ #define DZ_RDONE 0x0080 /* Receiver data ready */ #define DZ_RIE 0x0040 /* Receive Interrupt Enable */ #define DZ_MSE 0x0020 /* Master Scan Enable */ @@ -24,44 +22,32 @@ #define DZ_MAINT 0x0008 /* Loop Back Mode */ /* - * Definitions for the Receiver Buffer Register. + * Definitions for the Received buffer. */ -#define DZ_RBUF_MASK 0x00FF /* Data Mask */ -#define DZ_LINE_MASK 0x0300 /* Line Mask */ +#define DZ_RBUF_MASK 0x00FF /* Data Mask in the Receive Buffer */ +#define DZ_LINE_MASK 0x0300 /* Line Mask in the Receive Buffer */ #define DZ_DVAL 0x8000 /* Valid Data indicator */ #define DZ_OERR 0x4000 /* Overrun error indicator */ #define DZ_FERR 0x2000 /* Frame error indicator */ #define DZ_PERR 0x1000 /* Parity error indicator */ -#define LINE(x) ((x & DZ_LINE_MASK) >> 8) /* Get the line number - from the input buffer */ -#define UCHAR(x) ((unsigned char)(x & DZ_RBUF_MASK)) +#define LINE(x) (x & DZ_LINE_MASK) >> 8 /* Get the line number from the input buffer */ +#define UCHAR(x) (unsigned char)(x & DZ_RBUF_MASK) /* - * Definitions for the Transmit Control Register. + * Definitions for the Transmit Register. */ #define DZ_LINE_KEYBOARD 0x0001 #define DZ_LINE_MOUSE 0x0002 #define DZ_LINE_MODEM 0x0004 #define DZ_LINE_PRINTER 0x0008 -#define DZ_MODEM_RTS 0x0800 /* RTS for the modem line (2) */ #define DZ_MODEM_DTR 0x0400 /* DTR for the modem line (2) */ -#define DZ_PRINT_RTS 0x0200 /* RTS for the prntr line (3) */ -#define DZ_PRINT_DTR 0x0100 /* DTR for the prntr line (3) */ -#define DZ_LNENB 0x000f /* Transmitter Line Enable */ /* * Definitions for the Modem Status Register. */ -#define DZ_MODEM_RI 0x0800 /* RI for the modem line (2) */ -#define DZ_MODEM_CD 0x0400 /* CD for the modem line (2) */ #define DZ_MODEM_DSR 0x0200 /* DSR for the modem line (2) */ -#define DZ_MODEM_CTS 0x0100 /* CTS for the modem line (2) */ -#define DZ_PRINT_RI 0x0008 /* RI for the printer line (3) */ -#define DZ_PRINT_CD 0x0004 /* CD for the printer line (3) */ -#define DZ_PRINT_DSR 0x0002 /* DSR for the prntr line (3) */ -#define DZ_PRINT_CTS 0x0001 /* CTS for the prntr line (3) */ /* * Definitions for the Transmit Data Register. diff --git a/trunk/drivers/serial/mpsc.c b/trunk/drivers/serial/mpsc.c index 29823bd60fb0..8eea69f29989 100644 --- a/trunk/drivers/serial/mpsc.c +++ b/trunk/drivers/serial/mpsc.c @@ -555,7 +555,7 @@ mpsc_sdma_start_tx(struct mpsc_port_info *pi) if (!mpsc_sdma_tx_active(pi)) { txre = (struct mpsc_tx_desc *)(pi->txr + (pi->txr_tail * MPSC_TXRE_SIZE)); - dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)txre, @@ -931,7 +931,7 @@ mpsc_init_rings(struct mpsc_port_info *pi) } txre->link = cpu_to_be32(pi->txr_p); /* Wrap last back to first */ - dma_cache_sync(pi->port.dev, (void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE, + dma_cache_sync((void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ @@ -1005,7 +1005,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi) rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE)); - dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, @@ -1029,7 +1029,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi) } bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE); - dma_cache_sync(pi->port.dev, (void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync((void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)bp, @@ -1098,7 +1098,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi) SDMA_DESC_CMDSTAT_F | SDMA_DESC_CMDSTAT_L); wmb(); - dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)rxre, @@ -1109,7 +1109,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi) pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1); rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn * MPSC_RXRE_SIZE)); - dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, @@ -1143,7 +1143,7 @@ mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr) SDMA_DESC_CMDSTAT_EI : 0)); wmb(); - dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)txre, @@ -1192,7 +1192,7 @@ mpsc_copy_tx_data(struct mpsc_port_info *pi) else /* All tx data copied into ring bufs */ return; - dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)bp, @@ -1217,7 +1217,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi) txre = (struct mpsc_tx_desc *)(pi->txr + (pi->txr_tail * MPSC_TXRE_SIZE)); - dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)txre, @@ -1235,7 +1235,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi) txre = (struct mpsc_tx_desc *)(pi->txr + (pi->txr_tail * MPSC_TXRE_SIZE)); - dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, + dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ @@ -1652,7 +1652,7 @@ mpsc_console_write(struct console *co, const char *s, uint count) count--; } - dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)bp, diff --git a/trunk/drivers/serial/uartlite.c b/trunk/drivers/serial/uartlite.c deleted file mode 100644 index 83690653b78b..000000000000 --- a/trunk/drivers/serial/uartlite.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * uartlite.c: Serial driver for Xilinx uartlite serial controller - * - * Peter Korsgaard - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ULITE_MAJOR 204 -#define ULITE_MINOR 187 -#define ULITE_NR_UARTS 4 - -/* For register details see datasheet: - http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf -*/ -#define ULITE_RX 0x00 -#define ULITE_TX 0x04 -#define ULITE_STATUS 0x08 -#define ULITE_CONTROL 0x0c - -#define ULITE_REGION 16 - -#define ULITE_STATUS_RXVALID 0x01 -#define ULITE_STATUS_RXFULL 0x02 -#define ULITE_STATUS_TXEMPTY 0x04 -#define ULITE_STATUS_TXFULL 0x08 -#define ULITE_STATUS_IE 0x10 -#define ULITE_STATUS_OVERRUN 0x20 -#define ULITE_STATUS_FRAME 0x40 -#define ULITE_STATUS_PARITY 0x80 - -#define ULITE_CONTROL_RST_TX 0x01 -#define ULITE_CONTROL_RST_RX 0x02 -#define ULITE_CONTROL_IE 0x10 - - -static struct uart_port ports[ULITE_NR_UARTS]; - -static int ulite_receive(struct uart_port *port, int stat) -{ - struct tty_struct *tty = port->info->tty; - unsigned char ch = 0; - char flag = TTY_NORMAL; - - if ((stat & (ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN - | ULITE_STATUS_FRAME)) == 0) - return 0; - - /* stats */ - if (stat & ULITE_STATUS_RXVALID) { - port->icount.rx++; - ch = readb(port->membase + ULITE_RX); - - if (stat & ULITE_STATUS_PARITY) - port->icount.parity++; - } - - if (stat & ULITE_STATUS_OVERRUN) - port->icount.overrun++; - - if (stat & ULITE_STATUS_FRAME) - port->icount.frame++; - - - /* drop byte with parity error if IGNPAR specificed */ - if (stat & port->ignore_status_mask & ULITE_STATUS_PARITY) - stat &= ~ULITE_STATUS_RXVALID; - - stat &= port->read_status_mask; - - if (stat & ULITE_STATUS_PARITY) - flag = TTY_PARITY; - - - stat &= ~port->ignore_status_mask; - - if (stat & ULITE_STATUS_RXVALID) - tty_insert_flip_char(tty, ch, flag); - - if (stat & ULITE_STATUS_FRAME) - tty_insert_flip_char(tty, 0, TTY_FRAME); - - if (stat & ULITE_STATUS_OVERRUN) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - - return 1; -} - -static int ulite_transmit(struct uart_port *port, int stat) -{ - struct circ_buf *xmit = &port->info->xmit; - - if (stat & ULITE_STATUS_TXFULL) - return 0; - - if (port->x_char) { - writeb(port->x_char, port->membase + ULITE_TX); - port->x_char = 0; - port->icount.tx++; - return 1; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - return 0; - - writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); - port->icount.tx++; - - /* wake up */ - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - return 1; -} - -static irqreturn_t ulite_isr(int irq, void *dev_id) -{ - struct uart_port *port = (struct uart_port *)dev_id; - int busy; - - do { - int stat = readb(port->membase + ULITE_STATUS); - busy = ulite_receive(port, stat); - busy |= ulite_transmit(port, stat); - } while (busy); - - tty_flip_buffer_push(port->info->tty); - - return IRQ_HANDLED; -} - -static unsigned int ulite_tx_empty(struct uart_port *port) -{ - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(&port->lock, flags); - ret = readb(port->membase + ULITE_STATUS); - spin_unlock_irqrestore(&port->lock, flags); - - return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; -} - -static unsigned int ulite_get_mctrl(struct uart_port *port) -{ - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; -} - -static void ulite_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - /* N/A */ -} - -static void ulite_stop_tx(struct uart_port *port) -{ - /* N/A */ -} - -static void ulite_start_tx(struct uart_port *port) -{ - ulite_transmit(port, readb(port->membase + ULITE_STATUS)); -} - -static void ulite_stop_rx(struct uart_port *port) -{ - /* don't forward any more data (like !CREAD) */ - port->ignore_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY - | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN; -} - -static void ulite_enable_ms(struct uart_port *port) -{ - /* N/A */ -} - -static void ulite_break_ctl(struct uart_port *port, int ctl) -{ - /* N/A */ -} - -static int ulite_startup(struct uart_port *port) -{ - int ret; - - ret = request_irq(port->irq, ulite_isr, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "uartlite", port); - if (ret) - return ret; - - writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, - port->membase + ULITE_CONTROL); - writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); - - return 0; -} - -static void ulite_shutdown(struct uart_port *port) -{ - writeb(0, port->membase + ULITE_CONTROL); - readb(port->membase + ULITE_CONTROL); /* dummy */ - free_irq(port->irq, port); -} - -static void ulite_set_termios(struct uart_port *port, struct termios *termios, - struct termios *old) -{ - unsigned long flags; - unsigned int baud; - - spin_lock_irqsave(&port->lock, flags); - - port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN - | ULITE_STATUS_TXFULL; - - if (termios->c_iflag & INPCK) - port->read_status_mask |= - ULITE_STATUS_PARITY | ULITE_STATUS_FRAME; - - port->ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= ULITE_STATUS_PARITY - | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN; - - /* ignore all characters if CREAD is not set */ - if ((termios->c_cflag & CREAD) == 0) - port->ignore_status_mask |= - ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY - | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN; - - /* update timeout */ - baud = uart_get_baud_rate(port, termios, old, 0, 460800); - uart_update_timeout(port, termios->c_cflag, baud); - - spin_unlock_irqrestore(&port->lock, flags); -} - -static const char *ulite_type(struct uart_port *port) -{ - return port->type == PORT_UARTLITE ? "uartlite" : NULL; -} - -static void ulite_release_port(struct uart_port *port) -{ - release_mem_region(port->mapbase, ULITE_REGION); - iounmap(port->membase); - port->membase = 0; -} - -static int ulite_request_port(struct uart_port *port) -{ - if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) { - dev_err(port->dev, "Memory region busy\n"); - return -EBUSY; - } - - port->membase = ioremap(port->mapbase, ULITE_REGION); - if (!port->membase) { - dev_err(port->dev, "Unable to map registers\n"); - release_mem_region(port->mapbase, ULITE_REGION); - return -EBUSY; - } - - return 0; -} - -static void ulite_config_port(struct uart_port *port, int flags) -{ - ulite_request_port(port); - port->type = PORT_UARTLITE; -} - -static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - /* we don't want the core code to modify any port params */ - return -EINVAL; -} - -static struct uart_ops ulite_ops = { - .tx_empty = ulite_tx_empty, - .set_mctrl = ulite_set_mctrl, - .get_mctrl = ulite_get_mctrl, - .stop_tx = ulite_stop_tx, - .start_tx = ulite_start_tx, - .stop_rx = ulite_stop_rx, - .enable_ms = ulite_enable_ms, - .break_ctl = ulite_break_ctl, - .startup = ulite_startup, - .shutdown = ulite_shutdown, - .set_termios = ulite_set_termios, - .type = ulite_type, - .release_port = ulite_release_port, - .request_port = ulite_request_port, - .config_port = ulite_config_port, - .verify_port = ulite_verify_port -}; - -#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE -static void ulite_console_wait_tx(struct uart_port *port) -{ - int i; - - /* wait up to 10ms for the character(s) to be sent */ - for (i = 0; i < 10000; i++) { - if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY) - break; - udelay(1); - } -} - -static void ulite_console_putchar(struct uart_port *port, int ch) -{ - ulite_console_wait_tx(port); - writeb(ch, port->membase + ULITE_TX); -} - -static void ulite_console_write(struct console *co, const char *s, - unsigned int count) -{ - struct uart_port *port = &ports[co->index]; - unsigned long flags; - unsigned int ier; - int locked = 1; - - if (oops_in_progress) { - locked = spin_trylock_irqsave(&port->lock, flags); - } else - spin_lock_irqsave(&port->lock, flags); - - /* save and disable interrupt */ - ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; - writeb(0, port->membase + ULITE_CONTROL); - - uart_console_write(port, s, count, ulite_console_putchar); - - ulite_console_wait_tx(port); - - /* restore interrupt state */ - if (ier) - writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); - - if (locked) - spin_unlock_irqrestore(&port->lock, flags); -} - -static int __init ulite_console_setup(struct console *co, char *options) -{ - struct uart_port *port; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index < 0 || co->index >= ULITE_NR_UARTS) - return -EINVAL; - - port = &ports[co->index]; - - /* not initialized yet? */ - if (!port->membase) - return -ENODEV; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(port, co, baud, parity, bits, flow); -} - -static struct uart_driver ulite_uart_driver; - -static struct console ulite_console = { - .name = "ttyUL", - .write = ulite_console_write, - .device = uart_console_device, - .setup = ulite_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, /* Specified on the cmdline (e.g. console=ttyUL0 ) */ - .data = &ulite_uart_driver, -}; - -static int __init ulite_console_init(void) -{ - register_console(&ulite_console); - return 0; -} - -console_initcall(ulite_console_init); - -#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ - -static struct uart_driver ulite_uart_driver = { - .owner = THIS_MODULE, - .driver_name = "uartlite", - .dev_name = "ttyUL", - .major = ULITE_MAJOR, - .minor = ULITE_MINOR, - .nr = ULITE_NR_UARTS, -#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE - .cons = &ulite_console, -#endif -}; - -static int __devinit ulite_probe(struct platform_device *pdev) -{ - struct resource *res, *res2; - struct uart_port *port; - - if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS) - return -EINVAL; - - if (ports[pdev->id].membase) - return -EBUSY; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res2) - return -ENODEV; - - port = &ports[pdev->id]; - - port->fifosize = 16; - port->regshift = 2; - port->iotype = UPIO_MEM; - port->iobase = 1; /* mark port in use */ - port->mapbase = res->start; - port->membase = 0; - port->ops = &ulite_ops; - port->irq = res2->start; - port->flags = UPF_BOOT_AUTOCONF; - port->dev = &pdev->dev; - port->type = PORT_UNKNOWN; - port->line = pdev->id; - - uart_add_one_port(&ulite_uart_driver, port); - platform_set_drvdata(pdev, port); - - return 0; -} - -static int ulite_remove(struct platform_device *pdev) -{ - struct uart_port *port = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - if (port) - uart_remove_one_port(&ulite_uart_driver, port); - - /* mark port as free */ - port->membase = 0; - - return 0; -} - -static struct platform_driver ulite_platform_driver = { - .probe = ulite_probe, - .remove = ulite_remove, - .driver = { - .owner = THIS_MODULE, - .name = "uartlite", - }, -}; - -int __init ulite_init(void) -{ - int ret; - - ret = uart_register_driver(&ulite_uart_driver); - if (ret) - return ret; - - ret = platform_driver_register(&ulite_platform_driver); - if (ret) - uart_unregister_driver(&ulite_uart_driver); - - return ret; -} - -void __exit ulite_exit(void) -{ - platform_driver_unregister(&ulite_platform_driver); - uart_unregister_driver(&ulite_uart_driver); -} - -module_init(ulite_init); -module_exit(ulite_exit); - -MODULE_AUTHOR("Peter Korsgaard "); -MODULE_DESCRIPTION("Xilinx uartlite serial driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 270e6211c2e3..c3c0626f550b 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -360,13 +360,12 @@ spi_alloc_master(struct device *dev, unsigned size) if (!dev) return NULL; - master = kzalloc(size + sizeof *master, GFP_KERNEL); + master = kzalloc(size + sizeof *master, SLAB_KERNEL); if (!master) return NULL; class_device_initialize(&master->cdev); master->cdev.class = &spi_master_class; - kobj_set_kset_s(&master->cdev, spi_master_class.subsys); master->cdev.dev = get_device(dev); spi_master_set_devdata(master, &master[1]); @@ -448,9 +447,7 @@ static int __unregister(struct device *dev, void *unused) */ void spi_unregister_master(struct spi_master *master) { - int dummy; - - dummy = device_for_each_child(master->cdev.dev, NULL, __unregister); + (void) device_for_each_child(master->cdev.dev, NULL, __unregister); class_device_unregister(&master->cdev); } EXPORT_SYMBOL_GPL(spi_unregister_master); @@ -466,13 +463,15 @@ EXPORT_SYMBOL_GPL(spi_unregister_master); */ struct spi_master *spi_busnum_to_master(u16 bus_num) { - char name[9]; - struct kobject *bus; - - snprintf(name, sizeof name, "spi%u", bus_num); - bus = kset_find_obj(&spi_master_class.subsys.kset, name); - if (bus) - return container_of(bus, struct spi_master, cdev.kobj); + if (bus_num) { + char name[8]; + struct kobject *bus; + + snprintf(name, sizeof name, "spi%u", bus_num); + bus = kset_find_obj(&spi_master_class.subsys.kset, name); + if (bus) + return container_of(bus, struct spi_master, cdev.kobj); + } return NULL; } EXPORT_SYMBOL_GPL(spi_busnum_to_master); @@ -608,7 +607,7 @@ static int __init spi_init(void) { int status; - buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); + buf = kmalloc(SPI_BUFSIZ, SLAB_KERNEL); if (!buf) { status = -ENOMEM; goto err0; diff --git a/trunk/drivers/spi/spi_bitbang.c b/trunk/drivers/spi/spi_bitbang.c index 57289b61d0be..08c1c57c6128 100644 --- a/trunk/drivers/spi/spi_bitbang.c +++ b/trunk/drivers/spi/spi_bitbang.c @@ -196,7 +196,7 @@ int spi_bitbang_setup(struct spi_device *spi) return -EINVAL; if (!cs) { - cs = kzalloc(sizeof *cs, GFP_KERNEL); + cs = kzalloc(sizeof *cs, SLAB_KERNEL); if (!cs) return -ENOMEM; spi->controller_state = cs; diff --git a/trunk/drivers/spi/spi_butterfly.c b/trunk/drivers/spi/spi_butterfly.c index 312987a03210..c2f601f8e4f2 100644 --- a/trunk/drivers/spi/spi_butterfly.c +++ b/trunk/drivers/spi/spi_butterfly.c @@ -251,8 +251,6 @@ static void butterfly_attach(struct parport *p) * setting up a platform device like this is an ugly kluge... */ pdev = platform_device_register_simple("butterfly", -1, NULL, 0); - if (IS_ERR(pdev)) - return; master = spi_alloc_master(&pdev->dev, sizeof *pp); if (!master) { diff --git a/trunk/drivers/usb/atm/ueagle-atm.c b/trunk/drivers/usb/atm/ueagle-atm.c index dae4ef1e8fe5..f2d196fa1e8b 100644 --- a/trunk/drivers/usb/atm/ueagle-atm.c +++ b/trunk/drivers/usb/atm/ueagle-atm.c @@ -64,8 +64,6 @@ #include #include #include -#include - #include #include "usbatm.h" diff --git a/trunk/drivers/usb/core/buffer.c b/trunk/drivers/usb/core/buffer.c index c3915dc28608..840442a25b61 100644 --- a/trunk/drivers/usb/core/buffer.c +++ b/trunk/drivers/usb/core/buffer.c @@ -93,7 +93,7 @@ void hcd_buffer_destroy (struct usb_hcd *hcd) } -/* sometimes alloc/free could use kmalloc with GFP_DMA, for +/* sometimes alloc/free could use kmalloc with SLAB_DMA, for * better sharing and to leverage mm/slab.c intelligence. */ diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 2651c2e2a89f..9be41ed1f9a6 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -461,7 +460,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) * since each TT has "at least two" buffers that can need it (and * there can be many TTs per hub). even if they're uncommon. */ - if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { + if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == NULL) { dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); /* FIXME recover somehow ... RESET_TT? */ return; @@ -2372,7 +2371,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1) struct usb_qualifier_descriptor *qual; int status; - qual = kmalloc (sizeof *qual, GFP_KERNEL); + qual = kmalloc (sizeof *qual, SLAB_KERNEL); if (qual == NULL) return; @@ -2923,7 +2922,7 @@ static int config_descriptors_changed(struct usb_device *udev) if (len < le16_to_cpu(udev->config[index].desc.wTotalLength)) len = le16_to_cpu(udev->config[index].desc.wTotalLength); } - buf = kmalloc (len, GFP_KERNEL); + buf = kmalloc (len, SLAB_KERNEL); if (buf == NULL) { dev_err(&udev->dev, "no mem to re-read configs after reset\n"); /* assume the worst */ diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 149aa8bfb1fe..7390b67c609d 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -488,7 +488,7 @@ void usb_sg_wait (struct usb_sg_request *io) int retval; io->urbs [i]->dev = io->dev; - retval = usb_submit_urb (io->urbs [i], GFP_ATOMIC); + retval = usb_submit_urb (io->urbs [i], SLAB_ATOMIC); /* after we submit, let completions or cancelations fire; * we handshake using io->status. diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index c98316ce8384..8b975d15538d 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -250,7 +250,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/usb/gadget/gmidi.c b/trunk/drivers/usb/gadget/gmidi.c index 31351826f2ba..64554acad63f 100644 --- a/trunk/drivers/usb/gadget/gmidi.c +++ b/trunk/drivers/usb/gadget/gmidi.c @@ -1236,7 +1236,7 @@ static int __devinit gmidi_bind(struct usb_gadget *gadget) /* ok, we made sense of the hardware ... */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), SLAB_KERNEL); if (!dev) { return -ENOMEM; } diff --git a/trunk/drivers/usb/gadget/goku_udc.c b/trunk/drivers/usb/gadget/goku_udc.c index 805a9826842d..a3076da3f4eb 100644 --- a/trunk/drivers/usb/gadget/goku_udc.c +++ b/trunk/drivers/usb/gadget/goku_udc.c @@ -1864,7 +1864,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* alloc, and start init */ - dev = kmalloc (sizeof *dev, GFP_KERNEL); + dev = kmalloc (sizeof *dev, SLAB_KERNEL); if (dev == NULL){ pr_debug("enomem %s\n", pci_name(pdev)); retval = -ENOMEM; diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index 3fb1044a4db0..86924f9cdd7e 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -412,7 +412,7 @@ ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) /* FIXME readahead for O_NONBLOCK and poll(); careful with ZLPs */ value = -ENOMEM; - kbuf = kmalloc (len, GFP_KERNEL); + kbuf = kmalloc (len, SLAB_KERNEL); if (unlikely (!kbuf)) goto free1; @@ -456,7 +456,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) /* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */ value = -ENOMEM; - kbuf = kmalloc (len, GFP_KERNEL); + kbuf = kmalloc (len, SLAB_KERNEL); if (!kbuf) goto free1; if (copy_from_user (kbuf, buf, len)) { @@ -1898,7 +1898,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) buf += 4; length -= 4; - kbuf = kmalloc (length, GFP_KERNEL); + kbuf = kmalloc (length, SLAB_KERNEL); if (!kbuf) return -ENOMEM; if (copy_from_user (kbuf, buf, length)) { diff --git a/trunk/drivers/usb/gadget/net2280.c b/trunk/drivers/usb/gadget/net2280.c index 3024c679e38e..0b590831582c 100644 --- a/trunk/drivers/usb/gadget/net2280.c +++ b/trunk/drivers/usb/gadget/net2280.c @@ -2861,7 +2861,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) } /* alloc, and start init */ - dev = kzalloc (sizeof *dev, GFP_KERNEL); + dev = kzalloc (sizeof *dev, SLAB_KERNEL); if (dev == NULL){ retval = -ENOMEM; goto done; diff --git a/trunk/drivers/usb/gadget/omap_udc.c b/trunk/drivers/usb/gadget/omap_udc.c index 030d87c28c2f..48a09fd89d18 100644 --- a/trunk/drivers/usb/gadget/omap_udc.c +++ b/trunk/drivers/usb/gadget/omap_udc.c @@ -2581,7 +2581,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) /* UDC_PULLUP_EN gates the chip clock */ // OTG_SYSCON_1_REG |= DEV_IDLE_EN; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); + udc = kzalloc(sizeof(*udc), SLAB_KERNEL); if (!udc) return -ENOMEM; diff --git a/trunk/drivers/usb/gadget/zero.c b/trunk/drivers/usb/gadget/zero.c index 40710ea1b490..0f809dd68492 100644 --- a/trunk/drivers/usb/gadget/zero.c +++ b/trunk/drivers/usb/gadget/zero.c @@ -1190,7 +1190,7 @@ zero_bind (struct usb_gadget *gadget) /* ok, we made sense of the hardware ... */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), SLAB_KERNEL); if (!dev) return -ENOMEM; spin_lock_init (&dev->lock); diff --git a/trunk/drivers/usb/host/ehci-dbg.c b/trunk/drivers/usb/host/ehci-dbg.c index 56349d21e6ea..34b7a31cd85b 100644 --- a/trunk/drivers/usb/host/ehci-dbg.c +++ b/trunk/drivers/usb/host/ehci-dbg.c @@ -492,7 +492,7 @@ show_periodic (struct class_device *class_dev, char *buf) unsigned i; __le32 tag; - if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC))) + if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC))) return 0; seen_count = 0; diff --git a/trunk/drivers/usb/host/hc_crisv10.c b/trunk/drivers/usb/host/hc_crisv10.c index 9325e46a68c0..87eca6aeacf2 100644 --- a/trunk/drivers/usb/host/hc_crisv10.c +++ b/trunk/drivers/usb/host/hc_crisv10.c @@ -188,7 +188,7 @@ static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0); #define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \ {panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);} -#define SLAB_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) +#define SLAB_FLAG (in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL) #define KMALLOC_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) /* Most helpful debugging aid */ @@ -275,13 +275,13 @@ static volatile USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4))); static int zout_buffer[4] __attribute__ ((aligned (4))); /* Cache for allocating new EP and SB descriptors. */ -static struct kmem_cache *usb_desc_cache; +static kmem_cache_t *usb_desc_cache; /* Cache for the registers allocated in the top half. */ -static struct kmem_cache *top_half_reg_cache; +static kmem_cache_t *top_half_reg_cache; /* Cache for the data allocated in the isoc descr top half. */ -static struct kmem_cache *isoc_compl_cache; +static kmem_cache_t *isoc_compl_cache; static struct usb_bus *etrax_usb_bus; @@ -1743,7 +1743,7 @@ static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc) *R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do); - comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, GFP_ATOMIC); + comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, SLAB_ATOMIC); assert(comp_data != NULL); INIT_WORK(&comp_data->usb_bh, etrax_usb_isoc_descr_interrupt_bottom_half, comp_data); @@ -3010,7 +3010,7 @@ static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid) if (!urb->iso_frame_desc[i].length) continue; - next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC); + next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_ATOMIC); assert(next_sb_desc != NULL); if (urb->iso_frame_desc[i].length > 0) { @@ -3063,7 +3063,7 @@ static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid) if (TxIsocEPList[epid].sub == 0) { dbg_isoc("Isoc traffic not already running, allocating SB"); - next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC); + next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_ATOMIC); assert(next_sb_desc != NULL); next_sb_desc->command = (IO_STATE(USB_SB_command, tt, in) | @@ -3317,7 +3317,7 @@ static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc) restore_flags(flags); - reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, GFP_ATOMIC); + reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, SLAB_ATOMIC); assert(reg != NULL); diff --git a/trunk/drivers/usb/host/ohci-dbg.c b/trunk/drivers/usb/host/ohci-dbg.c index 0f47a57dac28..8293c1d4be3f 100644 --- a/trunk/drivers/usb/host/ohci-dbg.c +++ b/trunk/drivers/usb/host/ohci-dbg.c @@ -505,7 +505,7 @@ show_periodic (struct class_device *class_dev, char *buf) char *next; unsigned i; - if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC))) + if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC))) return 0; seen_count = 0; diff --git a/trunk/drivers/usb/host/ohci-pnx4008.c b/trunk/drivers/usb/host/ohci-pnx4008.c index 7f26f9bdbaf1..2dbb77414905 100644 --- a/trunk/drivers/usb/host/ohci-pnx4008.c +++ b/trunk/drivers/usb/host/ohci-pnx4008.c @@ -134,7 +134,7 @@ static int isp1301_attach(struct i2c_adapter *adap, int addr, int kind) { struct i2c_client *c; - c = (struct i2c_client *)kzalloc(sizeof(*c), GFP_KERNEL); + c = (struct i2c_client *)kzalloc(sizeof(*c), SLAB_KERNEL); if (!c) return -ENOMEM; diff --git a/trunk/drivers/usb/host/uhci-hcd.c b/trunk/drivers/usb/host/uhci-hcd.c index e87692c31be4..226bf3de8edd 100644 --- a/trunk/drivers/usb/host/uhci-hcd.c +++ b/trunk/drivers/usb/host/uhci-hcd.c @@ -81,7 +81,7 @@ MODULE_PARM_DESC(debug, "Debug level"); static char *errbuf; #define ERRBUF_LEN (32 * 1024) -static struct kmem_cache *uhci_up_cachep; /* urb_priv */ +static kmem_cache_t *uhci_up_cachep; /* urb_priv */ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state); static void wakeup_rh(struct uhci_hcd *uhci); diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 30b88459ac7d..06115f22a4fa 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -498,7 +498,7 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, { struct urb_priv *urbp; - urbp = kmem_cache_alloc(uhci_up_cachep, GFP_ATOMIC); + urbp = kmem_cache_alloc(uhci_up_cachep, SLAB_ATOMIC); if (!urbp) return NULL; diff --git a/trunk/drivers/usb/input/acecad.c b/trunk/drivers/usb/input/acecad.c index 909138e5aa04..0096373b5f98 100644 --- a/trunk/drivers/usb/input/acecad.c +++ b/trunk/drivers/usb/input/acecad.c @@ -152,7 +152,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ if (!acecad || !input_dev) goto fail1; - acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma); + acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma); if (!acecad->data) goto fail1; diff --git a/trunk/drivers/usb/input/aiptek.c b/trunk/drivers/usb/input/aiptek.c index 9f52429ce654..bf428184608f 100644 --- a/trunk/drivers/usb/input/aiptek.c +++ b/trunk/drivers/usb/input/aiptek.c @@ -1988,7 +1988,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) goto fail1; aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, - GFP_ATOMIC, &aiptek->data_dma); + SLAB_ATOMIC, &aiptek->data_dma); if (!aiptek->data) goto fail1; diff --git a/trunk/drivers/usb/input/ati_remote.c b/trunk/drivers/usb/input/ati_remote.c index b724e36f7b92..ff23318dc301 100644 --- a/trunk/drivers/usb/input/ati_remote.c +++ b/trunk/drivers/usb/input/ati_remote.c @@ -592,7 +592,7 @@ static void ati_remote_irq_in(struct urb *urb) __FUNCTION__, urb->status); } - retval = usb_submit_urb(urb, GFP_ATOMIC); + retval = usb_submit_urb(urb, SLAB_ATOMIC); if (retval) dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n", __FUNCTION__, retval); @@ -604,12 +604,12 @@ static void ati_remote_irq_in(struct urb *urb) static int ati_remote_alloc_buffers(struct usb_device *udev, struct ati_remote *ati_remote) { - ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC, + ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, &ati_remote->inbuf_dma); if (!ati_remote->inbuf) return -1; - ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC, + ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, &ati_remote->outbuf_dma); if (!ati_remote->outbuf) return -1; diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index f1d0e1d69828..4295bab4f1e2 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -1079,7 +1079,7 @@ static void hid_irq_in(struct urb *urb) warn("input irq status %d received", urb->status); } - status = usb_submit_urb(urb, GFP_ATOMIC); + status = usb_submit_urb(urb, SLAB_ATOMIC); if (status) { clear_bit(HID_IN_RUNNING, &hid->iofl); if (status != -EPERM) { @@ -1864,13 +1864,13 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type, int * static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) { - if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma))) + if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma))) return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma))) + if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma))) return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma))) + if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma))) + if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma))) return -1; return 0; diff --git a/trunk/drivers/usb/input/keyspan_remote.c b/trunk/drivers/usb/input/keyspan_remote.c index 98bd323369c7..50aa8108a50b 100644 --- a/trunk/drivers/usb/input/keyspan_remote.c +++ b/trunk/drivers/usb/input/keyspan_remote.c @@ -456,7 +456,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote->in_endpoint = endpoint; remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */ - remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma); + remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma); if (!remote->in_buffer) { retval = -ENOMEM; goto fail1; diff --git a/trunk/drivers/usb/input/mtouchusb.c b/trunk/drivers/usb/input/mtouchusb.c index 92c4e07da4c8..79a85d46cb13 100644 --- a/trunk/drivers/usb/input/mtouchusb.c +++ b/trunk/drivers/usb/input/mtouchusb.c @@ -164,7 +164,7 @@ static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *m dbg("%s - called", __FUNCTION__); mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE, - GFP_ATOMIC, &mtouch->data_dma); + SLAB_ATOMIC, &mtouch->data_dma); if (!mtouch->data) return -1; diff --git a/trunk/drivers/usb/input/powermate.c b/trunk/drivers/usb/input/powermate.c index fea97e5437f8..0bf91778c40d 100644 --- a/trunk/drivers/usb/input/powermate.c +++ b/trunk/drivers/usb/input/powermate.c @@ -277,12 +277,12 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm) { pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX, - GFP_ATOMIC, &pm->data_dma); + SLAB_ATOMIC, &pm->data_dma); if (!pm->data) return -1; pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)), - GFP_ATOMIC, &pm->configcr_dma); + SLAB_ATOMIC, &pm->configcr_dma); if (!pm->configcr) return -1; diff --git a/trunk/drivers/usb/input/touchkitusb.c b/trunk/drivers/usb/input/touchkitusb.c index 2a314b065922..05c0d1ca39ab 100644 --- a/trunk/drivers/usb/input/touchkitusb.c +++ b/trunk/drivers/usb/input/touchkitusb.c @@ -248,7 +248,7 @@ static int touchkit_alloc_buffers(struct usb_device *udev, struct touchkit_usb *touchkit) { touchkit->data = usb_buffer_alloc(udev, TOUCHKIT_REPORT_DATA_SIZE, - GFP_ATOMIC, &touchkit->data_dma); + SLAB_ATOMIC, &touchkit->data_dma); if (!touchkit->data) return -1; diff --git a/trunk/drivers/usb/input/usbkbd.c b/trunk/drivers/usb/input/usbkbd.c index 8505824848f6..dac88640eab6 100644 --- a/trunk/drivers/usb/input/usbkbd.c +++ b/trunk/drivers/usb/input/usbkbd.c @@ -122,7 +122,7 @@ static void usb_kbd_irq(struct urb *urb) memcpy(kbd->old, kbd->new, 8); resubmit: - i = usb_submit_urb (urb, GFP_ATOMIC); + i = usb_submit_urb (urb, SLAB_ATOMIC); if (i) err ("can't resubmit intr, %s-%s/input0, status %d", kbd->usbdev->bus->bus_name, @@ -196,11 +196,11 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd) return -1; if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL))) return -1; - if (!(kbd->new = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &kbd->new_dma))) + if (!(kbd->new = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kbd->new_dma))) return -1; - if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma))) + if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), SLAB_ATOMIC, &kbd->cr_dma))) return -1; - if (!(kbd->leds = usb_buffer_alloc(dev, 1, GFP_ATOMIC, &kbd->leds_dma))) + if (!(kbd->leds = usb_buffer_alloc(dev, 1, SLAB_ATOMIC, &kbd->leds_dma))) return -1; return 0; diff --git a/trunk/drivers/usb/input/usbmouse.c b/trunk/drivers/usb/input/usbmouse.c index 64a33e420cfb..68a55642c082 100644 --- a/trunk/drivers/usb/input/usbmouse.c +++ b/trunk/drivers/usb/input/usbmouse.c @@ -86,7 +86,7 @@ static void usb_mouse_irq(struct urb *urb) input_sync(dev); resubmit: - status = usb_submit_urb (urb, GFP_ATOMIC); + status = usb_submit_urb (urb, SLAB_ATOMIC); if (status) err ("can't resubmit intr, %s-%s/input0, status %d", mouse->usbdev->bus->bus_name, @@ -137,7 +137,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i if (!mouse || !input_dev) goto fail1; - mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma); + mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma); if (!mouse->data) goto fail1; diff --git a/trunk/drivers/usb/input/usbtouchscreen.c b/trunk/drivers/usb/input/usbtouchscreen.c index 7f3c57da9bc0..49704d4ed0e2 100644 --- a/trunk/drivers/usb/input/usbtouchscreen.c +++ b/trunk/drivers/usb/input/usbtouchscreen.c @@ -680,7 +680,7 @@ static int usbtouch_probe(struct usb_interface *intf, type->process_pkt = usbtouch_process_pkt; usbtouch->data = usb_buffer_alloc(udev, type->rept_size, - GFP_KERNEL, &usbtouch->data_dma); + SLAB_KERNEL, &usbtouch->data_dma); if (!usbtouch->data) goto out_free; diff --git a/trunk/drivers/usb/input/xpad.c b/trunk/drivers/usb/input/xpad.c index e4bc76ebc835..df97e5c803f9 100644 --- a/trunk/drivers/usb/input/xpad.c +++ b/trunk/drivers/usb/input/xpad.c @@ -325,7 +325,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id goto fail1; xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, - GFP_ATOMIC, &xpad->idata_dma); + SLAB_ATOMIC, &xpad->idata_dma); if (!xpad->idata) goto fail1; diff --git a/trunk/drivers/usb/input/yealink.c b/trunk/drivers/usb/input/yealink.c index caff8e6d7448..2268ca311ade 100644 --- a/trunk/drivers/usb/input/yealink.c +++ b/trunk/drivers/usb/input/yealink.c @@ -874,17 +874,17 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* allocate usb buffers */ yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, - GFP_ATOMIC, &yld->irq_dma); + SLAB_ATOMIC, &yld->irq_dma); if (yld->irq_data == NULL) return usb_cleanup(yld, -ENOMEM); yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN, - GFP_ATOMIC, &yld->ctl_dma); + SLAB_ATOMIC, &yld->ctl_dma); if (!yld->ctl_data) return usb_cleanup(yld, -ENOMEM); yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)), - GFP_ATOMIC, &yld->ctl_req_dma); + SLAB_ATOMIC, &yld->ctl_req_dma); if (yld->ctl_req == NULL) return usb_cleanup(yld, -ENOMEM); diff --git a/trunk/drivers/usb/misc/phidgetkit.c b/trunk/drivers/usb/misc/phidgetkit.c index 371bf2b1197d..9659c79e187e 100644 --- a/trunk/drivers/usb/misc/phidgetkit.c +++ b/trunk/drivers/usb/misc/phidgetkit.c @@ -377,7 +377,7 @@ static void interfacekit_irq(struct urb *urb) schedule_delayed_work(&kit->do_notify, 0); resubmit: - status = usb_submit_urb(urb, GFP_ATOMIC); + status = usb_submit_urb(urb, SLAB_ATOMIC); if (status) err("can't resubmit intr, %s-%s/interfacekit0, status %d", kit->udev->bus->bus_name, @@ -568,7 +568,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic kit->dev_no = -1; kit->ifkit = ifkit; - kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma); + kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma); if (!kit->data) goto out; diff --git a/trunk/drivers/usb/misc/phidgetmotorcontrol.c b/trunk/drivers/usb/misc/phidgetmotorcontrol.c index 5727e1ea2f91..2bb4fa572bb7 100644 --- a/trunk/drivers/usb/misc/phidgetmotorcontrol.c +++ b/trunk/drivers/usb/misc/phidgetmotorcontrol.c @@ -151,7 +151,7 @@ static void motorcontrol_irq(struct urb *urb) schedule_delayed_work(&mc->do_notify, 0); resubmit: - status = usb_submit_urb(urb, GFP_ATOMIC); + status = usb_submit_urb(urb, SLAB_ATOMIC); if (status) dev_err(&mc->intf->dev, "can't resubmit intr, %s-%s/motorcontrol0, status %d", @@ -338,7 +338,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic goto out; mc->dev_no = -1; - mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma); + mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &mc->data_dma); if (!mc->data) goto out; diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index fb321864a92d..194065dbb51f 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -213,7 +213,7 @@ static struct urb *simple_alloc_urb ( if (bytes < 0) return NULL; - urb = usb_alloc_urb (0, GFP_KERNEL); + urb = usb_alloc_urb (0, SLAB_KERNEL); if (!urb) return urb; usb_fill_bulk_urb (urb, udev, pipe, NULL, bytes, simple_callback, NULL); @@ -223,7 +223,7 @@ static struct urb *simple_alloc_urb ( urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; if (usb_pipein (pipe)) urb->transfer_flags |= URB_SHORT_NOT_OK; - urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL, + urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL, &urb->transfer_dma); if (!urb->transfer_buffer) { usb_free_urb (urb); @@ -315,7 +315,7 @@ static int simple_io ( init_completion (&completion); if (usb_pipeout (urb->pipe)) simple_fill_buf (urb); - if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) + if ((retval = usb_submit_urb (urb, SLAB_KERNEL)) != 0) break; /* NOTE: no timeouts; can't be broken out of by interrupt */ @@ -374,7 +374,7 @@ alloc_sglist (int nents, int max, int vary) unsigned i; unsigned size = max; - sg = kmalloc (nents * sizeof *sg, GFP_KERNEL); + sg = kmalloc (nents * sizeof *sg, SLAB_KERNEL); if (!sg) return NULL; @@ -382,7 +382,7 @@ alloc_sglist (int nents, int max, int vary) char *buf; unsigned j; - buf = kzalloc (size, GFP_KERNEL); + buf = kzalloc (size, SLAB_KERNEL); if (!buf) { free_sglist (sg, i); return NULL; @@ -428,7 +428,7 @@ static int perform_sglist ( (udev->speed == USB_SPEED_HIGH) ? (INTERRUPT_RATE << 3) : INTERRUPT_RATE, - sg, nents, 0, GFP_KERNEL); + sg, nents, 0, SLAB_KERNEL); if (retval) break; @@ -819,7 +819,7 @@ static void ctrl_complete (struct urb *urb) /* resubmit if we need to, else mark this as done */ if ((status == 0) && (ctx->pending < ctx->count)) { - if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) { + if ((status = usb_submit_urb (urb, SLAB_ATOMIC)) != 0) { dbg ("can't resubmit ctrl %02x.%02x, err %d", reqp->bRequestType, reqp->bRequest, status); urb->dev = NULL; @@ -855,7 +855,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) * as with bulk/intr sglists, sglen is the queue depth; it also * controls which subtests run (more tests than sglen) or rerun. */ - urb = kcalloc(param->sglen, sizeof(struct urb *), GFP_KERNEL); + urb = kcalloc(param->sglen, sizeof(struct urb *), SLAB_KERNEL); if (!urb) return -ENOMEM; for (i = 0; i < param->sglen; i++) { @@ -981,7 +981,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) if (!u) goto cleanup; - reqp = usb_buffer_alloc (udev, sizeof *reqp, GFP_KERNEL, + reqp = usb_buffer_alloc (udev, sizeof *reqp, SLAB_KERNEL, &u->setup_dma); if (!reqp) goto cleanup; @@ -999,7 +999,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) context.urb = urb; spin_lock_irq (&context.lock); for (i = 0; i < param->sglen; i++) { - context.status = usb_submit_urb (urb [i], GFP_ATOMIC); + context.status = usb_submit_urb (urb [i], SLAB_ATOMIC); if (context.status != 0) { dbg ("can't submit urb[%d], status %d", i, context.status); @@ -1041,7 +1041,7 @@ static void unlink1_callback (struct urb *urb) // we "know" -EPIPE (stall) never happens if (!status) - status = usb_submit_urb (urb, GFP_ATOMIC); + status = usb_submit_urb (urb, SLAB_ATOMIC); if (status) { urb->status = status; complete ((struct completion *) urb->context); @@ -1067,7 +1067,7 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) * FIXME want additional tests for when endpoint is STALLing * due to errors, or is just NAKing requests. */ - if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) { + if ((retval = usb_submit_urb (urb, SLAB_KERNEL)) != 0) { dev_dbg (&dev->intf->dev, "submit fail %d\n", retval); return retval; } @@ -1251,7 +1251,7 @@ static int ctrl_out (struct usbtest_dev *dev, if (length < 1 || length > 0xffff || vary >= length) return -EINVAL; - buf = kmalloc(length, GFP_KERNEL); + buf = kmalloc(length, SLAB_KERNEL); if (!buf) return -ENOMEM; @@ -1403,7 +1403,7 @@ static struct urb *iso_alloc_urb ( maxp *= 1 + (0x3 & (le16_to_cpu(desc->wMaxPacketSize) >> 11)); packets = (bytes + maxp - 1) / maxp; - urb = usb_alloc_urb (packets, GFP_KERNEL); + urb = usb_alloc_urb (packets, SLAB_KERNEL); if (!urb) return urb; urb->dev = udev; @@ -1411,7 +1411,7 @@ static struct urb *iso_alloc_urb ( urb->number_of_packets = packets; urb->transfer_buffer_length = bytes; - urb->transfer_buffer = usb_buffer_alloc (udev, bytes, GFP_KERNEL, + urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL, &urb->transfer_dma); if (!urb->transfer_buffer) { usb_free_urb (urb); @@ -1481,7 +1481,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, spin_lock_irq (&context.lock); for (i = 0; i < param->sglen; i++) { ++context.pending; - status = usb_submit_urb (urbs [i], GFP_ATOMIC); + status = usb_submit_urb (urbs [i], SLAB_ATOMIC); if (status < 0) { ERROR (dev, "submit iso[%d], error %d\n", i, status); if (i == 0) { @@ -1900,7 +1900,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) } #endif - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), SLAB_KERNEL); if (!dev) return -ENOMEM; info = (struct usbtest_info *) id->driver_info; @@ -1910,7 +1910,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) dev->intf = intf; /* cacheline-aligned scratch for i/o */ - if ((dev->buf = kmalloc (TBUF_SIZE, GFP_KERNEL)) == NULL) { + if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == NULL) { kfree (dev); return -ENOMEM; } diff --git a/trunk/drivers/usb/mon/mon_text.c b/trunk/drivers/usb/mon/mon_text.c index 05cf2c9a8f84..7a2346c53284 100644 --- a/trunk/drivers/usb/mon/mon_text.c +++ b/trunk/drivers/usb/mon/mon_text.c @@ -50,7 +50,7 @@ struct mon_event_text { #define SLAB_NAME_SZ 30 struct mon_reader_text { - struct kmem_cache *e_slab; + kmem_cache_t *e_slab; int nevents; struct list_head e_list; struct mon_reader r; /* In C, parent class can be placed anywhere */ @@ -63,7 +63,7 @@ struct mon_reader_text { char slab_name[SLAB_NAME_SZ]; }; -static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); +static void mon_text_ctor(void *, kmem_cache_t *, unsigned long); /* * mon_text_submit @@ -147,7 +147,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, stamp = mon_get_timestamp(); if (rp->nevents >= EVENT_MAX || - (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) { + (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) { rp->r.m_bus->cnt_text_lost++; return; } @@ -188,7 +188,7 @@ static void mon_text_error(void *data, struct urb *urb, int error) struct mon_event_text *ep; if (rp->nevents >= EVENT_MAX || - (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) { + (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) { rp->r.m_bus->cnt_text_lost++; return; } @@ -450,7 +450,7 @@ const struct file_operations mon_fops_text = { /* * Slab interface: constructor. */ -static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sflags) +static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags) { /* * Nothing to initialize. No, really! diff --git a/trunk/drivers/usb/net/catc.c b/trunk/drivers/usb/net/catc.c index 4852012735f6..907b820a5faf 100644 --- a/trunk/drivers/usb/net/catc.c +++ b/trunk/drivers/usb/net/catc.c @@ -345,7 +345,7 @@ static void catc_irq_done(struct urb *urb) } } resubmit: - status = usb_submit_urb (urb, GFP_ATOMIC); + status = usb_submit_urb (urb, SLAB_ATOMIC); if (status) err ("can't resubmit intr, %s-%s, status %d", catc->usbdev->bus->bus_name, diff --git a/trunk/drivers/usb/net/net1080.c b/trunk/drivers/usb/net/net1080.c index 493635954513..a77410562e12 100644 --- a/trunk/drivers/usb/net/net1080.c +++ b/trunk/drivers/usb/net/net1080.c @@ -383,7 +383,7 @@ static void nc_ensure_sync(struct usbnet *dev) int status; /* Send a flush */ - urb = usb_alloc_urb(0, GFP_ATOMIC); + urb = usb_alloc_urb(0, SLAB_ATOMIC); if (!urb) return; diff --git a/trunk/drivers/usb/net/pegasus.c b/trunk/drivers/usb/net/pegasus.c index d48c024cff59..b5690b3834e3 100644 --- a/trunk/drivers/usb/net/pegasus.c +++ b/trunk/drivers/usb/net/pegasus.c @@ -856,7 +856,7 @@ static void intr_callback(struct urb *urb) pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4]; } - status = usb_submit_urb(urb, GFP_ATOMIC); + status = usb_submit_urb(urb, SLAB_ATOMIC); if (status == -ENODEV) netif_device_detach(pegasus->net); if (status && netif_msg_timer(pegasus)) diff --git a/trunk/drivers/usb/net/rndis_host.c b/trunk/drivers/usb/net/rndis_host.c index 99f26b3e502f..c2a28d88ef3c 100644 --- a/trunk/drivers/usb/net/rndis_host.c +++ b/trunk/drivers/usb/net/rndis_host.c @@ -469,7 +469,7 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) struct rndis_halt *halt; /* try to clear any rndis state/activity (no i/o from stack!) */ - halt = kcalloc(1, sizeof *halt, GFP_KERNEL); + halt = kcalloc(1, sizeof *halt, SLAB_KERNEL); if (halt) { halt->msg_type = RNDIS_MSG_HALT; halt->msg_len = ccpu2(sizeof *halt); diff --git a/trunk/drivers/usb/net/rtl8150.c b/trunk/drivers/usb/net/rtl8150.c index c54235f73cb6..72171f94ded4 100644 --- a/trunk/drivers/usb/net/rtl8150.c +++ b/trunk/drivers/usb/net/rtl8150.c @@ -587,7 +587,7 @@ static void intr_callback(struct urb *urb) } resubmit: - status = usb_submit_urb (urb, GFP_ATOMIC); + status = usb_submit_urb (urb, SLAB_ATOMIC); if (status == -ENODEV) netif_device_detach(dev->netdev); else if (status) diff --git a/trunk/drivers/usb/net/usbnet.c b/trunk/drivers/usb/net/usbnet.c index 6e39e9988259..327f97555679 100644 --- a/trunk/drivers/usb/net/usbnet.c +++ b/trunk/drivers/usb/net/usbnet.c @@ -179,9 +179,9 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf) period = max ((int) dev->status->desc.bInterval, (dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3); - buf = kmalloc (maxp, GFP_KERNEL); + buf = kmalloc (maxp, SLAB_KERNEL); if (buf) { - dev->interrupt = usb_alloc_urb (0, GFP_KERNEL); + dev->interrupt = usb_alloc_urb (0, SLAB_KERNEL); if (!dev->interrupt) { kfree (buf); return -ENOMEM; diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index 70f93b18292f..82cd15b894b0 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/drivers/usb/serial/mos7720.c @@ -363,7 +363,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) /* Initialising the write urb pool */ for (j = 0; j < NUM_URBS; ++j) { - urb = usb_alloc_urb(0,GFP_ATOMIC); + urb = usb_alloc_urb(0,SLAB_ATOMIC); mos7720_port->write_urb_pool[j] = urb; if (urb == NULL) { diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 5432c6340086..02c89e10b2cf 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -826,7 +826,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) /* Initialising the write urb pool */ for (j = 0; j < NUM_URBS; ++j) { - urb = usb_alloc_urb(0, GFP_ATOMIC); + urb = usb_alloc_urb(0, SLAB_ATOMIC); mos7840_port->write_urb_pool[j] = urb; if (urb == NULL) { @@ -2786,7 +2786,7 @@ static int mos7840_startup(struct usb_serial *serial) i + 1, status); } - mos7840_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC); + mos7840_port->control_urb = usb_alloc_urb(0, SLAB_ATOMIC); mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); } diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index e565d3d2ab29..3a158d58441f 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -76,7 +76,7 @@ static void usb_onetouch_irq(struct urb *urb) input_sync(dev); resubmit: - status = usb_submit_urb (urb, GFP_ATOMIC); + status = usb_submit_urb (urb, SLAB_ATOMIC); if (status) err ("can't resubmit intr, %s-%s/input0, status %d", onetouch->udev->bus->bus_name, @@ -154,7 +154,7 @@ int onetouch_connect_input(struct us_data *ss) goto fail1; onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN, - GFP_ATOMIC, &onetouch->data_dma); + SLAB_ATOMIC, &onetouch->data_dma); if (!onetouch->data) goto fail1; diff --git a/trunk/drivers/usb/storage/transport.c b/trunk/drivers/usb/storage/transport.c index 323293a3e61f..47644b5b6155 100644 --- a/trunk/drivers/usb/storage/transport.c +++ b/trunk/drivers/usb/storage/transport.c @@ -427,7 +427,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__, length, num_sg); result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0, - sg, num_sg, length, GFP_NOIO); + sg, num_sg, length, SLAB_NOIO); if (result) { US_DEBUGP("usb_sg_init returned %d\n", result); return USB_STOR_XFER_ERROR; diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index 70644506651f..b401084b3d22 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/video/geode/gxfb_core.c b/trunk/drivers/video/geode/gxfb_core.c index a454dcb8e215..0d3643fc6293 100644 --- a/trunk/drivers/video/geode/gxfb_core.c +++ b/trunk/drivers/video/geode/gxfb_core.c @@ -380,7 +380,7 @@ static void gxfb_remove(struct pci_dev *pdev) } static struct pci_device_id gxfb_id_table[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_GX_VIDEO, + { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_VIDEO, PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0 }, { 0, } diff --git a/trunk/drivers/w1/Makefile b/trunk/drivers/w1/Makefile index 6bb0b54965f2..93845a2c7c21 100644 --- a/trunk/drivers/w1/Makefile +++ b/trunk/drivers/w1/Makefile @@ -2,6 +2,10 @@ # Makefile for the Dallas's 1-wire bus. # +ifeq ($(CONFIG_W1_DS2433_CRC), y) +EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC +endif + obj-$(CONFIG_W1) += wire.o wire-objs := w1.o w1_int.o w1_family.o w1_netlink.o w1_io.o diff --git a/trunk/drivers/w1/slaves/Makefile b/trunk/drivers/w1/slaves/Makefile index 725dcfdfddb4..70e21e2d70c3 100644 --- a/trunk/drivers/w1/slaves/Makefile +++ b/trunk/drivers/w1/slaves/Makefile @@ -2,6 +2,10 @@ # Makefile for the Dallas's 1-wire slaves. # +ifeq ($(CONFIG_W1_SLAVE_DS2433_CRC), y) +EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC +endif + obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o diff --git a/trunk/drivers/w1/slaves/w1_ds2433.c b/trunk/drivers/w1/slaves/w1_ds2433.c index 8ea17a53eed8..2ac238f1480e 100644 --- a/trunk/drivers/w1/slaves/w1_ds2433.c +++ b/trunk/drivers/w1/slaves/w1_ds2433.c @@ -13,7 +13,7 @@ #include #include #include -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC #include #define CRC16_INIT 0 @@ -62,7 +62,7 @@ static inline size_t w1_f23_fix_count(loff_t off, size_t count, size_t size) return count; } -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, int block) { @@ -89,13 +89,13 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, return 0; } -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ +#endif /* CONFIG_W1_F23_CRC */ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC struct w1_f23_data *data = sl->family_data; int i, min_page, max_page; #else @@ -107,7 +107,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off, mutex_lock(&sl->master->mutex); -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC min_page = (off >> W1_PAGE_BITS); max_page = (off + count - 1) >> W1_PAGE_BITS; @@ -119,7 +119,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off, } memcpy(buf, &data->memory[off], count); -#else /* CONFIG_W1_SLAVE_DS2433_CRC */ +#else /* CONFIG_W1_F23_CRC */ /* read directly from the EEPROM */ if (w1_reset_select_slave(sl)) { @@ -133,7 +133,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off, w1_write_block(sl->master, wrbuf, 3); w1_read_block(sl->master, buf, count); -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ +#endif /* CONFIG_W1_F23_CRC */ out_up: mutex_unlock(&sl->master->mutex); @@ -208,7 +208,7 @@ static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off, if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0) return 0; -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC /* can only write full blocks in cached mode */ if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) { dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n", @@ -223,7 +223,7 @@ static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off, return -EINVAL; } } -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ +#endif /* CONFIG_W1_F23_CRC */ mutex_lock(&sl->master->mutex); @@ -262,7 +262,7 @@ static struct bin_attribute w1_f23_bin_attr = { static int w1_f23_add_slave(struct w1_slave *sl) { int err; -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC struct w1_f23_data *data; data = kmalloc(sizeof(struct w1_f23_data), GFP_KERNEL); @@ -271,24 +271,24 @@ static int w1_f23_add_slave(struct w1_slave *sl) memset(data, 0, sizeof(struct w1_f23_data)); sl->family_data = data; -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ +#endif /* CONFIG_W1_F23_CRC */ err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC if (err) kfree(data); -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ +#endif /* CONFIG_W1_F23_CRC */ return err; } static void w1_f23_remove_slave(struct w1_slave *sl) { -#ifdef CONFIG_W1_SLAVE_DS2433_CRC +#ifdef CONFIG_W1_F23_CRC kfree(sl->family_data); sl->family_data = NULL; -#endif /* CONFIG_W1_SLAVE_DS2433_CRC */ +#endif /* CONFIG_W1_F23_CRC */ sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); } diff --git a/trunk/drivers/w1/w1.c b/trunk/drivers/w1/w1.c index 63c07243993c..de3e9791f80d 100644 --- a/trunk/drivers/w1/w1.c +++ b/trunk/drivers/w1/w1.c @@ -31,7 +31,6 @@ #include #include #include -#include #include diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index 18f26cdfd882..5241c600ce28 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -256,7 +256,7 @@ static int v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) { - int fid; + u32 fid; int err; struct v9fs_fcall *fcall; @@ -310,7 +310,7 @@ static struct v9fs_fid* v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) { int err; - int nfid; + u32 nfid; struct v9fs_fid *ret; struct v9fs_fcall *fcall; diff --git a/trunk/fs/adfs/super.c b/trunk/fs/adfs/super.c index 5023351a7afe..9ade139086fc 100644 --- a/trunk/fs/adfs/super.c +++ b/trunk/fs/adfs/super.c @@ -36,7 +36,7 @@ void __adfs_error(struct super_block *sb, const char *function, const char *fmt, va_list args; va_start(args, fmt); - vsnprintf(error_buf, sizeof(error_buf), fmt, args); + vsprintf(error_buf, fmt, args); va_end(args); printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %s\n", @@ -212,12 +212,12 @@ static int adfs_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -static struct kmem_cache *adfs_inode_cachep; +static kmem_cache_t *adfs_inode_cachep; static struct inode *adfs_alloc_inode(struct super_block *sb) { struct adfs_inode_info *ei; - ei = (struct adfs_inode_info *)kmem_cache_alloc(adfs_inode_cachep, GFP_KERNEL); + ei = (struct adfs_inode_info *)kmem_cache_alloc(adfs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -228,7 +228,7 @@ static void adfs_destroy_inode(struct inode *inode) kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; diff --git a/trunk/fs/affs/amigaffs.c b/trunk/fs/affs/amigaffs.c index f4de4b98004f..ccd624ef4272 100644 --- a/trunk/fs/affs/amigaffs.c +++ b/trunk/fs/affs/amigaffs.c @@ -445,7 +445,7 @@ affs_error(struct super_block *sb, const char *function, const char *fmt, ...) va_list args; va_start(args,fmt); - vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); + vsprintf(ErrorBuffer,fmt,args); va_end(args); printk(KERN_CRIT "AFFS error (device %s): %s(): %s\n", sb->s_id, @@ -461,7 +461,7 @@ affs_warning(struct super_block *sb, const char *function, const char *fmt, ...) va_list args; va_start(args,fmt); - vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); + vsprintf(ErrorBuffer,fmt,args); va_end(args); printk(KERN_WARNING "AFFS warning (device %s): %s(): %s\n", sb->s_id, diff --git a/trunk/fs/affs/bitmap.c b/trunk/fs/affs/bitmap.c index b330009fe42d..b0b953683c1a 100644 --- a/trunk/fs/affs/bitmap.c +++ b/trunk/fs/affs/bitmap.c @@ -289,11 +289,12 @@ int affs_init_bitmap(struct super_block *sb, int *flags) sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved + sbi->s_bmap_bits - 1) / sbi->s_bmap_bits; size = sbi->s_bmap_count * sizeof(*bm); - bm = sbi->s_bitmap = kzalloc(size, GFP_KERNEL); + bm = sbi->s_bitmap = kmalloc(size, GFP_KERNEL); if (!sbi->s_bitmap) { printk(KERN_ERR "AFFS: Bitmap allocation failed\n"); return -ENOMEM; } + memset(sbi->s_bitmap, 0, size); bmap_blk = (__be32 *)sbi->s_root_bh->b_data; blk = sb->s_blocksize / 4 - 49; diff --git a/trunk/fs/affs/super.c b/trunk/fs/affs/super.c index 3de93e799949..5ea72c3a16c3 100644 --- a/trunk/fs/affs/super.c +++ b/trunk/fs/affs/super.c @@ -66,12 +66,12 @@ affs_write_super(struct super_block *sb) pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); } -static struct kmem_cache * affs_inode_cachep; +static kmem_cache_t * affs_inode_cachep; static struct inode *affs_alloc_inode(struct super_block *sb) { struct affs_inode_info *ei; - ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); + ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; ei->vfs_inode.i_version = 1; @@ -83,7 +83,7 @@ static void affs_destroy_inode(struct inode *inode) kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct affs_inode_info *ei = (struct affs_inode_info *) foo; diff --git a/trunk/fs/afs/kafsasyncd.c b/trunk/fs/afs/kafsasyncd.c index 615df2407cb2..f09a794f248e 100644 --- a/trunk/fs/afs/kafsasyncd.c +++ b/trunk/fs/afs/kafsasyncd.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "cell.h" #include "server.h" #include "volume.h" diff --git a/trunk/fs/afs/kafstimod.c b/trunk/fs/afs/kafstimod.c index 694344e4d3c7..65bc05ab8182 100644 --- a/trunk/fs/afs/kafstimod.c +++ b/trunk/fs/afs/kafstimod.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "cell.h" #include "volume.h" #include "kafstimod.h" diff --git a/trunk/fs/afs/server.c b/trunk/fs/afs/server.c index 44aff81dc6a7..22afaae1a4ce 100644 --- a/trunk/fs/afs/server.c +++ b/trunk/fs/afs/server.c @@ -55,12 +55,13 @@ int afs_server_lookup(struct afs_cell *cell, const struct in_addr *addr, _enter("%p,%08x,", cell, ntohl(addr->s_addr)); /* allocate and initialise a server record */ - server = kzalloc(sizeof(struct afs_server), GFP_KERNEL); + server = kmalloc(sizeof(struct afs_server), GFP_KERNEL); if (!server) { _leave(" = -ENOMEM"); return -ENOMEM; } + memset(server, 0, sizeof(struct afs_server)); atomic_set(&server->usage, 1); INIT_LIST_HEAD(&server->link); diff --git a/trunk/fs/afs/super.c b/trunk/fs/afs/super.c index 18d9b77ba40f..67d1f5c819ec 100644 --- a/trunk/fs/afs/super.c +++ b/trunk/fs/afs/super.c @@ -35,7 +35,7 @@ struct afs_mount_params { struct afs_volume *volume; }; -static void afs_i_init_once(void *foo, struct kmem_cache *cachep, +static void afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags); static int afs_get_sb(struct file_system_type *fs_type, @@ -65,7 +65,7 @@ static struct super_operations afs_super_ops = { .put_super = afs_put_super, }; -static struct kmem_cache *afs_inode_cachep; +static kmem_cache_t *afs_inode_cachep; static atomic_t afs_count_active_inodes; /*****************************************************************************/ @@ -242,12 +242,14 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent) kenter(""); /* allocate a superblock info record */ - as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); + as = kmalloc(sizeof(struct afs_super_info), GFP_KERNEL); if (!as) { _leave(" = -ENOMEM"); return -ENOMEM; } + memset(as, 0, sizeof(struct afs_super_info)); + afs_get_volume(params->volume); as->volume = params->volume; @@ -382,7 +384,7 @@ static void afs_put_super(struct super_block *sb) /* * initialise an inode cache slab element prior to any use */ -static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep, +static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags) { struct afs_vnode *vnode = (struct afs_vnode *) _vnode; @@ -410,7 +412,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb) struct afs_vnode *vnode; vnode = (struct afs_vnode *) - kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL); + kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL); if (!vnode) return NULL; diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index d3a6ec2c9627..287a1bc7a182 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -47,8 +47,8 @@ unsigned long aio_nr; /* current system wide number of aio requests */ unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */ /*----end sysctl variables---*/ -static struct kmem_cache *kiocb_cachep; -static struct kmem_cache *kioctx_cachep; +static kmem_cache_t *kiocb_cachep; +static kmem_cache_t *kioctx_cachep; static struct workqueue_struct *aio_wq; @@ -666,6 +666,17 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) ssize_t (*retry)(struct kiocb *); ssize_t ret; + if (iocb->ki_retried++ > 1024*1024) { + printk("Maximal retry count. Bytes done %Zd\n", + iocb->ki_nbytes - iocb->ki_left); + return -EAGAIN; + } + + if (!(iocb->ki_retried & 0xff)) { + pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried, + iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); + } + if (!(retry = iocb->ki_retry)) { printk("aio_run_iocb: iocb->ki_retry = NULL\n"); return 0; @@ -994,6 +1005,9 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2) kunmap_atomic(ring, KM_IRQ1); pr_debug("added to ring %p at [%lu]\n", iocb, tail); + + pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried, + iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); put_rq: /* everything turned out well, dispose of the aiocb. */ ret = __aio_put_req(ctx, iocb); @@ -1399,6 +1413,7 @@ static ssize_t aio_setup_single_vector(struct kiocb *kiocb) kiocb->ki_iovec->iov_len = kiocb->ki_left; kiocb->ki_nr_segs = 1; kiocb->ki_cur_seg = 0; + kiocb->ki_nbytes = kiocb->ki_left; return 0; } @@ -1576,6 +1591,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, req->ki_opcode = iocb->aio_lio_opcode; init_waitqueue_func_entry(&req->ki_wait, aio_wake_function); INIT_LIST_HEAD(&req->ki_wait.task_list); + req->ki_retried = 0; ret = aio_setup_iocb(req); diff --git a/trunk/fs/autofs/inode.c b/trunk/fs/autofs/inode.c index f968d1342808..38ede5c9d6fd 100644 --- a/trunk/fs/autofs/inode.c +++ b/trunk/fs/autofs/inode.c @@ -28,11 +28,10 @@ void autofs_kill_sb(struct super_block *sb) /* * In the event of a failure in get_sb_nodev the superblock * info is not present so nothing else has been setup, so - * just call kill_anon_super when we are called from - * deactivate_super. + * just exit when we are called from deactivate_super. */ if (!sbi) - goto out_kill_sb; + return; if ( !sbi->catatonic ) autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ @@ -45,7 +44,6 @@ void autofs_kill_sb(struct super_block *sb) kfree(sb->s_fs_info); -out_kill_sb: DPRINTK(("autofs: shutting down\n")); kill_anon_super(sb); } @@ -211,6 +209,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) fail_free: kfree(sbi); s->s_fs_info = NULL; + kill_anon_super(s); fail_unlock: return -EINVAL; } diff --git a/trunk/fs/autofs4/inode.c b/trunk/fs/autofs4/inode.c index 9c48250fd726..ce7c0f1dd529 100644 --- a/trunk/fs/autofs4/inode.c +++ b/trunk/fs/autofs4/inode.c @@ -152,11 +152,10 @@ void autofs4_kill_sb(struct super_block *sb) /* * In the event of a failure in get_sb_nodev the superblock * info is not present so nothing else has been setup, so - * just call kill_anon_super when we are called from - * deactivate_super. + * just exit when we are called from deactivate_super. */ if (!sbi) - goto out_kill_sb; + return; sb->s_fs_info = NULL; @@ -168,7 +167,6 @@ void autofs4_kill_sb(struct super_block *sb) kfree(sbi); -out_kill_sb: DPRINTK("shutting down"); kill_anon_super(sb); } @@ -428,6 +426,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) fail_free: kfree(sbi); s->s_fs_info = NULL; + kill_anon_super(s); fail_unlock: return -EINVAL; } diff --git a/trunk/fs/befs/linuxvfs.c b/trunk/fs/befs/linuxvfs.c index bce402eee554..07f7144f0e2e 100644 --- a/trunk/fs/befs/linuxvfs.c +++ b/trunk/fs/befs/linuxvfs.c @@ -61,7 +61,7 @@ static const struct super_operations befs_sops = { }; /* slab cache for befs_inode_info objects */ -static struct kmem_cache *befs_inode_cachep; +static kmem_cache_t *befs_inode_cachep; static const struct file_operations befs_dir_operations = { .read = generic_read_dir, @@ -277,7 +277,7 @@ befs_alloc_inode(struct super_block *sb) { struct befs_inode_info *bi; bi = (struct befs_inode_info *)kmem_cache_alloc(befs_inode_cachep, - GFP_KERNEL); + SLAB_KERNEL); if (!bi) return NULL; return &bi->vfs_inode; @@ -289,7 +289,7 @@ befs_destroy_inode(struct inode *inode) kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct befs_inode_info *bi = (struct befs_inode_info *) foo; diff --git a/trunk/fs/bfs/inode.c b/trunk/fs/bfs/inode.c index eac175ed9f44..ed27ffb3459e 100644 --- a/trunk/fs/bfs/inode.c +++ b/trunk/fs/bfs/inode.c @@ -228,12 +228,12 @@ static void bfs_write_super(struct super_block *s) unlock_kernel(); } -static struct kmem_cache * bfs_inode_cachep; +static kmem_cache_t * bfs_inode_cachep; static struct inode *bfs_alloc_inode(struct super_block *sb) { struct bfs_inode_info *bi; - bi = kmem_cache_alloc(bfs_inode_cachep, GFP_KERNEL); + bi = kmem_cache_alloc(bfs_inode_cachep, SLAB_KERNEL); if (!bi) return NULL; return &bi->vfs_inode; @@ -244,7 +244,7 @@ static void bfs_destroy_inode(struct inode *inode) kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct bfs_inode_info *bi = foo; diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index be5869d34999..cc72bb43061d 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -47,6 +47,10 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); +#ifndef elf_addr_t +#define elf_addr_t unsigned long +#endif + /* * If we don't support core dumping, then supply a NULL so we * don't even try. @@ -239,9 +243,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, if (interp_aout) { argv = sp + 2; envp = argv + argc + 1; - if (__put_user((elf_addr_t)(unsigned long)argv, sp++) || - __put_user((elf_addr_t)(unsigned long)envp, sp++)) - return -EFAULT; + __put_user((elf_addr_t)(unsigned long)argv, sp++); + __put_user((elf_addr_t)(unsigned long)envp, sp++); } else { argv = sp; envp = argv + argc + 1; @@ -251,8 +254,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, p = current->mm->arg_end = current->mm->arg_start; while (argc-- > 0) { size_t len; - if (__put_user((elf_addr_t)p, argv++)) - return -EFAULT; + __put_user((elf_addr_t)p, argv++); len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) return 0; @@ -263,8 +265,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, current->mm->arg_end = current->mm->env_start = p; while (envc-- > 0) { size_t len; - if (__put_user((elf_addr_t)p, envp++)) - return -EFAULT; + __put_user((elf_addr_t)p, envp++); len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) return 0; @@ -544,7 +545,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned long reloc_func_desc = 0; char passed_fileno[6]; struct files_struct *files; - int executable_stack = EXSTACK_DEFAULT; + int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT; unsigned long def_flags = 0; struct { struct elfhdr elf_ex; @@ -707,6 +708,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) executable_stack = EXSTACK_DISABLE_X; break; } + have_pt_gnu_stack = (i < loc->elf_ex.e_phnum); /* Some simple consistency checks for the interpreter */ if (elf_interpreter) { @@ -854,13 +856,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) * default mmap base, as well as whatever program they * might try to exec. This is because the brk will * follow the loader, and is not movable. */ - if (current->flags & PF_RANDOMIZE) - load_bias = randomize_range(0x10000, - ELF_ET_DYN_BASE, - 0); - else - load_bias = ELF_ET_DYN_BASE; - load_bias = ELF_PAGESTART(load_bias - vaddr); + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index ed9a61c6beb3..f86d5c9ce5eb 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -40,6 +40,9 @@ #include typedef char *elf_caddr_t; +#ifndef elf_addr_t +#define elf_addr_t unsigned long +#endif #if 0 #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ ) diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 7ec737eda72b..50c40ce2cead 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -30,7 +30,7 @@ #define BIO_POOL_SIZE 256 -static struct kmem_cache *bio_slab __read_mostly; +static kmem_cache_t *bio_slab __read_mostly; #define BIOVEC_NR_POOLS 6 @@ -44,7 +44,7 @@ mempool_t *bio_split_pool __read_mostly; struct biovec_slab { int nr_vecs; char *name; - struct kmem_cache *slab; + kmem_cache_t *slab; }; /* diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 13816b4d76f6..36c0e7af9d0f 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -235,11 +235,11 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) */ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock); -static struct kmem_cache * bdev_cachep __read_mostly; +static kmem_cache_t * bdev_cachep __read_mostly; static struct inode *bdev_alloc_inode(struct super_block *sb) { - struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); + struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -253,7 +253,7 @@ static void bdev_destroy_inode(struct inode *inode) kmem_cache_free(bdev_cachep, bdi); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct bdev_inode *ei = (struct bdev_inode *) foo; struct block_device *bdev = &ei->bdev; diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 517860f2d75b..35527dca1dbc 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -2908,7 +2908,7 @@ asmlinkage long sys_bdflush(int func, long data) /* * Buffer-head allocation */ -static struct kmem_cache *bh_cachep; +static kmem_cache_t *bh_cachep; /* * Once the number of bh's in the machine exceeds this level, we start @@ -2961,7 +2961,7 @@ void free_buffer_head(struct buffer_head *bh) EXPORT_SYMBOL(free_buffer_head); static void -init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) +init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) { if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { @@ -2972,6 +2972,7 @@ init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) } } +#ifdef CONFIG_HOTPLUG_CPU static void buffer_exit_cpu(int cpu) { int i; @@ -2993,6 +2994,7 @@ static int buffer_cpu_notify(struct notifier_block *self, buffer_exit_cpu((unsigned long)hcpu); return NOTIFY_OK; } +#endif /* CONFIG_HOTPLUG_CPU */ void __init buffer_init(void) { diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 71bc87a37fc1..84976cdbe713 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -34,7 +34,6 @@ #include #include #include -#include #include "cifsfs.h" #include "cifspdu.h" #define DECLARE_GLOBALS_HERE @@ -82,7 +81,7 @@ extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; extern mempool_t *cifs_mid_poolp; -extern struct kmem_cache *cifs_oplock_cachep; +extern kmem_cache_t *cifs_oplock_cachep; static int cifs_read_super(struct super_block *sb, void *data, @@ -233,11 +232,11 @@ static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) return generic_permission(inode, mask, NULL); } -static struct kmem_cache *cifs_inode_cachep; -static struct kmem_cache *cifs_req_cachep; -static struct kmem_cache *cifs_mid_cachep; -struct kmem_cache *cifs_oplock_cachep; -static struct kmem_cache *cifs_sm_req_cachep; +static kmem_cache_t *cifs_inode_cachep; +static kmem_cache_t *cifs_req_cachep; +static kmem_cache_t *cifs_mid_cachep; +kmem_cache_t *cifs_oplock_cachep; +static kmem_cache_t *cifs_sm_req_cachep; mempool_t *cifs_sm_req_poolp; mempool_t *cifs_req_poolp; mempool_t *cifs_mid_poolp; @@ -246,7 +245,7 @@ static struct inode * cifs_alloc_inode(struct super_block *sb) { struct cifsInodeInfo *cifs_inode; - cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL); + cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL); if (!cifs_inode) return NULL; cifs_inode->cifsAttrs = 0x20; /* default */ @@ -669,7 +668,7 @@ const struct file_operations cifs_dir_ops = { }; static void -cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) +cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags) { struct cifsInodeInfo *cifsi = inode; diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 2caca06b4bae..71f77914ce93 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include "cifspdu.h" diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index aedf683f011f..bbc9cd34b6ea 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -153,7 +153,7 @@ cifs_buf_get(void) albeit slightly larger than necessary and maxbuffersize defaults to this and can not be bigger */ ret_buf = - (struct smb_hdr *) mempool_alloc(cifs_req_poolp, GFP_KERNEL | GFP_NOFS); + (struct smb_hdr *) mempool_alloc(cifs_req_poolp, SLAB_KERNEL | SLAB_NOFS); /* clear the first few header bytes */ /* for most paths, more is cleared in header_assemble */ @@ -192,7 +192,7 @@ cifs_small_buf_get(void) albeit slightly larger than necessary and maxbuffersize defaults to this and can not be bigger */ ret_buf = - (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, GFP_KERNEL | GFP_NOFS); + (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, SLAB_KERNEL | SLAB_NOFS); if (ret_buf) { /* No need to clear memory here, cleared in header assemble */ /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index f80007eaebf4..48d47b46b1fb 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -34,7 +34,7 @@ #include "cifs_debug.h" extern mempool_t *cifs_mid_poolp; -extern struct kmem_cache *cifs_oplock_cachep; +extern kmem_cache_t *cifs_oplock_cachep; static struct mid_q_entry * AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) @@ -51,7 +51,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) } temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, - GFP_KERNEL | GFP_NOFS); + SLAB_KERNEL | SLAB_NOFS); if (temp == NULL) return temp; else { @@ -118,7 +118,7 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) return NULL; } temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep, - GFP_KERNEL); + SLAB_KERNEL); if (temp == NULL) return temp; else { diff --git a/trunk/fs/coda/inode.c b/trunk/fs/coda/inode.c index b64659fa82d0..88d123321164 100644 --- a/trunk/fs/coda/inode.c +++ b/trunk/fs/coda/inode.c @@ -38,12 +38,12 @@ static void coda_clear_inode(struct inode *); static void coda_put_super(struct super_block *); static int coda_statfs(struct dentry *dentry, struct kstatfs *buf); -static struct kmem_cache * coda_inode_cachep; +static kmem_cache_t * coda_inode_cachep; static struct inode *coda_alloc_inode(struct super_block *sb) { struct coda_inode_info *ei; - ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); + ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; memset(&ei->c_fid, 0, sizeof(struct CodaFid)); @@ -58,7 +58,7 @@ static void coda_destroy_inode(struct inode *inode) kmem_cache_free(coda_inode_cachep, ITOC(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct coda_inode_info *ei = (struct coda_inode_info *) foo; diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index a7e3f162fb15..06dad665b88f 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -871,7 +871,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, retval = -EINVAL; - if (type_page && data_page) { + if (type_page) { if (!strcmp((char *)type_page, SMBFS_NAME)) { do_smb_super_data_conv((void *)data_page); } else if (!strcmp((char *)type_page, NCPFS_NAME)) { @@ -1144,9 +1144,7 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, lastdirent = buf.previous; if (lastdirent) { typeof(lastdirent->d_off) d_off = file->f_pos; - error = -EFAULT; - if (__put_user_unaligned(d_off, &lastdirent->d_off)) - goto out_putf; + __put_user_unaligned(d_off, &lastdirent->d_off); error = count - buf.count; } @@ -1613,14 +1611,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, nr &= ~1UL; while (nr) { unsigned long h, l; - if (__get_user(l, ufdset) || __get_user(h, ufdset+1)) - return -EFAULT; + __get_user(l, ufdset); + __get_user(h, ufdset+1); ufdset += 2; *fdset++ = h << 32 | l; nr -= 2; } - if (odd && __get_user(*fdset, ufdset)) - return -EFAULT; + if (odd) + __get_user(*fdset, ufdset); } else { /* Tricky, must clear full unsigned long in the * kernel fdset at the end, this makes sure that @@ -1632,14 +1630,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, } static -int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, - unsigned long *fdset) +void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, + unsigned long *fdset) { unsigned long odd; nr = ROUND_UP(nr, __COMPAT_NFDBITS); if (!ufdset) - return 0; + return; odd = nr & 1UL; nr &= ~1UL; @@ -1647,14 +1645,13 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, unsigned long h, l; l = *fdset++; h = l >> 32; - if (__put_user(l, ufdset) || __put_user(h, ufdset+1)) - return -EFAULT; + __put_user(l, ufdset); + __put_user(h, ufdset+1); ufdset += 2; nr -= 2; } - if (odd && __put_user(*fdset, ufdset)) - return -EFAULT; - return 0; + if (odd) + __put_user(*fdset, ufdset); } @@ -1729,10 +1726,10 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, ret = 0; } - if (compat_set_fd_set(n, inp, fds.res_in) || - compat_set_fd_set(n, outp, fds.res_out) || - compat_set_fd_set(n, exp, fds.res_ex)) - ret = -EFAULT; + compat_set_fd_set(n, inp, fds.res_in); + compat_set_fd_set(n, outp, fds.res_out); + compat_set_fd_set(n, exp, fds.res_ex); + out: kfree(bits); out_nofds: diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index bcc3caf5d820..a91f2628c981 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -211,10 +211,8 @@ static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned lon up_native = compat_alloc_user_space(sizeof(struct video_still_picture)); - err = put_user(compat_ptr(fp), &up_native->iFrame); - err |= put_user(size, &up_native->size); - if (err) - return -EFAULT; + put_user(compat_ptr(fp), &up_native->iFrame); + put_user(size, &up_native->size); err = sys_ioctl(fd, cmd, (unsigned long) up_native); @@ -238,10 +236,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned err |= get_user(length, &up->length); up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); - err = put_user(compat_ptr(palp), &up_native->palette); - err |= put_user(length, &up_native->length); - if (err) - return -EFAULT; + put_user(compat_ptr(palp), &up_native->palette); + put_user(length, &up_native->length); err = sys_ioctl(fd, cmd, (unsigned long) up_native); @@ -2047,19 +2043,16 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) struct serial_struct ss; mm_segment_t oldseg = get_fs(); __u32 udata; - unsigned int base; if (cmd == TIOCSSERIAL) { if (!access_ok(VERIFY_READ, ss32, sizeof(SS32))) return -EFAULT; if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base))) return -EFAULT; - if (__get_user(udata, &ss32->iomem_base)) - return -EFAULT; + __get_user(udata, &ss32->iomem_base); ss.iomem_base = compat_ptr(udata); - if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || - __get_user(ss.port_high, &ss32->port_high)) - return -EFAULT; + __get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift); + __get_user(ss.port_high, &ss32->port_high); ss.iomap_base = 0UL; } set_fs(KERNEL_DS); @@ -2070,12 +2063,12 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) return -EFAULT; if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base))) return -EFAULT; - base = (unsigned long)ss.iomem_base >> 32 ? - 0xffffffff : (unsigned)(unsigned long)ss.iomem_base; - if (__put_user(base, &ss32->iomem_base) || - __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || - __put_user(ss.port_high, &ss32->port_high)) - return -EFAULT; + __put_user((unsigned long)ss.iomem_base >> 32 ? + 0xffffffff : (unsigned)(unsigned long)ss.iomem_base, + &ss32->iomem_base); + __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift); + __put_user(ss.port_high, &ss32->port_high); + } return err; } @@ -2404,7 +2397,6 @@ HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFHWBROADCAST, dev_ifsioc) /* ioctls used by appletalk ddp.c */ HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) diff --git a/trunk/fs/configfs/configfs_internal.h b/trunk/fs/configfs/configfs_internal.h index f92cd303d2c9..3f4ff7a242b9 100644 --- a/trunk/fs/configfs/configfs_internal.h +++ b/trunk/fs/configfs/configfs_internal.h @@ -49,7 +49,7 @@ struct configfs_dirent { #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) extern struct vfsmount * configfs_mount; -extern struct kmem_cache *configfs_dir_cachep; +extern kmem_cache_t *configfs_dir_cachep; extern int configfs_is_root(struct config_item *item); diff --git a/trunk/fs/configfs/mount.c b/trunk/fs/configfs/mount.c index ed678529ebb2..68bd5c93ca52 100644 --- a/trunk/fs/configfs/mount.c +++ b/trunk/fs/configfs/mount.c @@ -38,7 +38,7 @@ struct vfsmount * configfs_mount = NULL; struct super_block * configfs_sb = NULL; -struct kmem_cache *configfs_dir_cachep; +kmem_cache_t *configfs_dir_cachep; static int configfs_mnt_count = 0; static struct super_operations configfs_ops = { diff --git a/trunk/fs/cramfs/inode.c b/trunk/fs/cramfs/inode.c index 0509cedd415c..a624c3ec8189 100644 --- a/trunk/fs/cramfs/inode.c +++ b/trunk/fs/cramfs/inode.c @@ -481,8 +481,6 @@ static int cramfs_readpage(struct file *file, struct page * page) pgdata = kmap(page); if (compr_len == 0) ; /* hole */ - else if (compr_len > (PAGE_CACHE_SIZE << 1)) - printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len); else { mutex_lock(&read_mutex); bytes_filled = cramfs_uncompress_block(pgdata, diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index d68631f18df1..fd4a428998ef 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -43,7 +43,7 @@ static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); EXPORT_SYMBOL(dcache_lock); -static struct kmem_cache *dentry_cache __read_mostly; +static kmem_cache_t *dentry_cache __read_mostly; #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) @@ -68,19 +68,15 @@ struct dentry_stat_t dentry_stat = { .age_limit = 45, }; -static void __d_free(struct dentry *dentry) +static void d_callback(struct rcu_head *head) { + struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); + if (dname_external(dentry)) kfree(dentry->d_name.name); kmem_cache_free(dentry_cache, dentry); } -static void d_callback(struct rcu_head *head) -{ - struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); - __d_free(dentry); -} - /* * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry * inside dcache_lock. @@ -89,11 +85,7 @@ static void d_free(struct dentry *dentry) { if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); - /* if dentry was never inserted into hash, immediate free is OK */ - if (dentry->d_hash.pprev == NULL) - __d_free(dentry); - else - call_rcu(&dentry->d_u.d_rcu, d_callback); + call_rcu(&dentry->d_u.d_rcu, d_callback); } /* @@ -2080,10 +2072,10 @@ static void __init dcache_init(unsigned long mempages) } /* SLAB cache for __getname() consumers */ -struct kmem_cache *names_cachep __read_mostly; +kmem_cache_t *names_cachep __read_mostly; /* SLAB cache for file structures */ -struct kmem_cache *filp_cachep __read_mostly; +kmem_cache_t *filp_cachep __read_mostly; EXPORT_SYMBOL(d_genocide); diff --git a/trunk/fs/dcookies.c b/trunk/fs/dcookies.c index 21af1629f9bc..0c4b0674854b 100644 --- a/trunk/fs/dcookies.c +++ b/trunk/fs/dcookies.c @@ -37,7 +37,7 @@ struct dcookie_struct { static LIST_HEAD(dcookie_users); static DEFINE_MUTEX(dcookie_mutex); -static struct kmem_cache *dcookie_cache __read_mostly; +static kmem_cache_t *dcookie_cache __read_mostly; static struct list_head *dcookie_hashtable __read_mostly; static size_t hash_size __read_mostly; diff --git a/trunk/fs/dlm/memory.c b/trunk/fs/dlm/memory.c index 5352b03ff5aa..989b608fd836 100644 --- a/trunk/fs/dlm/memory.c +++ b/trunk/fs/dlm/memory.c @@ -15,7 +15,7 @@ #include "config.h" #include "memory.h" -static struct kmem_cache *lkb_cache; +static kmem_cache_t *lkb_cache; int dlm_memory_init(void) diff --git a/trunk/fs/dnotify.c b/trunk/fs/dnotify.c index 1f26a2b9eee1..2b0442db67e0 100644 --- a/trunk/fs/dnotify.c +++ b/trunk/fs/dnotify.c @@ -23,7 +23,7 @@ int dir_notify_enable __read_mostly = 1; -static struct kmem_cache *dn_cache __read_mostly; +static kmem_cache_t *dn_cache __read_mostly; static void redo_inode_mask(struct inode *inode) { @@ -77,7 +77,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) inode = filp->f_dentry->d_inode; if (!S_ISDIR(inode->i_mode)) return -ENOTDIR; - dn = kmem_cache_alloc(dn_cache, GFP_KERNEL); + dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL); if (dn == NULL) return -ENOMEM; spin_lock(&inode->i_lock); diff --git a/trunk/fs/dquot.c b/trunk/fs/dquot.c index f9cd5e23ebdf..9af789567e51 100644 --- a/trunk/fs/dquot.c +++ b/trunk/fs/dquot.c @@ -131,7 +131,7 @@ static struct quota_format_type *quota_formats; /* List of registered formats */ static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES; /* SLAB cache for dquot structures */ -static struct kmem_cache *dquot_cachep; +static kmem_cache_t *dquot_cachep; int register_quota_format(struct quota_format_type *fmt) { @@ -600,7 +600,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) { struct dquot *dquot; - dquot = kmem_cache_alloc(dquot_cachep, GFP_NOFS); + dquot = kmem_cache_alloc(dquot_cachep, SLAB_NOFS); if(!dquot) return NODQUOT; diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index 7196f50fe152..f63a7755fe86 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -628,7 +628,7 @@ int ecryptfs_decrypt_page(struct file *file, struct page *page) num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; base_extent = (page->index * num_extents_per_page); lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache, - GFP_KERNEL); + SLAB_KERNEL); if (!lower_page_virt) { rc = -ENOMEM; ecryptfs_printk(KERN_ERR, "Error getting page for encrypted " @@ -1334,7 +1334,7 @@ int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, goto out; } /* Released in this function */ - page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, GFP_USER); + page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, SLAB_USER); if (!page_virt) { ecryptfs_printk(KERN_ERR, "Out of memory\n"); rc = -ENOMEM; @@ -1493,7 +1493,7 @@ int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; /* Read the first page from the underlying file */ - page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); + page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, SLAB_USER); if (!page_virt) { rc = -ENOMEM; ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); diff --git a/trunk/fs/ecryptfs/file.c b/trunk/fs/ecryptfs/file.c index 42099e779a56..a92ef05eff8f 100644 --- a/trunk/fs/ecryptfs/file.c +++ b/trunk/fs/ecryptfs/file.c @@ -250,7 +250,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) int lower_flags; /* Released in ecryptfs_release or end of function if failure */ - file_info = kmem_cache_alloc(ecryptfs_file_info_cache, GFP_KERNEL); + file_info = kmem_cache_alloc(ecryptfs_file_info_cache, SLAB_KERNEL); ecryptfs_set_file_private(file, file_info); if (!file_info) { ecryptfs_printk(KERN_ERR, diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 8a1945a84c36..dfcc68484f47 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -369,7 +369,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, BUG_ON(!atomic_read(&lower_dentry->d_count)); ecryptfs_set_dentry_private(dentry, kmem_cache_alloc(ecryptfs_dentry_info_cache, - GFP_KERNEL)); + SLAB_KERNEL)); if (!ecryptfs_dentry_to_private(dentry)) { rc = -ENOMEM; ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " @@ -404,7 +404,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, /* Released in this function */ page_virt = (char *)kmem_cache_alloc(ecryptfs_header_cache_2, - GFP_USER); + SLAB_USER); if (!page_virt) { rc = -ENOMEM; ecryptfs_printk(KERN_ERR, @@ -795,7 +795,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) /* Released at out_free: label */ ecryptfs_set_file_private(&fake_ecryptfs_file, kmem_cache_alloc(ecryptfs_file_info_cache, - GFP_KERNEL)); + SLAB_KERNEL)); if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { rc = -ENOMEM; goto out; diff --git a/trunk/fs/ecryptfs/keystore.c b/trunk/fs/ecryptfs/keystore.c index 745c0f1bfbbd..c3746f56d162 100644 --- a/trunk/fs/ecryptfs/keystore.c +++ b/trunk/fs/ecryptfs/keystore.c @@ -207,7 +207,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or * at end of function upon failure */ auth_tok_list_item = - kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); + kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, SLAB_KERNEL); if (!auth_tok_list_item) { ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); rc = -ENOMEM; diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index 3ede12b25933..a78d87d14baf 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -378,7 +378,7 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) /* Released in ecryptfs_put_super() */ ecryptfs_set_superblock_private(sb, kmem_cache_alloc(ecryptfs_sb_info_cache, - GFP_KERNEL)); + SLAB_KERNEL)); if (!ecryptfs_superblock_to_private(sb)) { ecryptfs_printk(KERN_WARNING, "Out of memory\n"); rc = -ENOMEM; @@ -402,7 +402,7 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) /* through deactivate_super(sb) from get_sb_nodev() */ ecryptfs_set_dentry_private(sb->s_root, kmem_cache_alloc(ecryptfs_dentry_info_cache, - GFP_KERNEL)); + SLAB_KERNEL)); if (!ecryptfs_dentry_to_private(sb->s_root)) { ecryptfs_printk(KERN_ERR, "dentry_info_cache alloc failed\n"); @@ -546,7 +546,7 @@ inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags) } static struct ecryptfs_cache_info { - struct kmem_cache **cache; + kmem_cache_t **cache; const char *name; size_t size; void (*ctor)(void*, struct kmem_cache *, unsigned long); @@ -691,7 +691,7 @@ static ssize_t version_show(struct ecryptfs_obj *obj, char *buff) static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); -static struct ecryptfs_version_str_map_elem { +struct ecryptfs_version_str_map_elem { u32 flag; char *str; } ecryptfs_version_str_map[] = { diff --git a/trunk/fs/ecryptfs/super.c b/trunk/fs/ecryptfs/super.c index eaa5daaf106e..825757ae4867 100644 --- a/trunk/fs/ecryptfs/super.c +++ b/trunk/fs/ecryptfs/super.c @@ -50,7 +50,7 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb) struct inode *inode = NULL; ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache, - GFP_KERNEL); + SLAB_KERNEL); if (unlikely(!ecryptfs_inode)) goto out; ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat); diff --git a/trunk/fs/efs/super.c b/trunk/fs/efs/super.c index dfebf21289f4..b3f50651eb6b 100644 --- a/trunk/fs/efs/super.c +++ b/trunk/fs/efs/super.c @@ -52,12 +52,12 @@ static struct pt_types sgi_pt_types[] = { }; -static struct kmem_cache * efs_inode_cachep; +static kmem_cache_t * efs_inode_cachep; static struct inode *efs_alloc_inode(struct super_block *sb) { struct efs_inode_info *ei; - ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, GFP_KERNEL); + ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -68,7 +68,7 @@ static void efs_destroy_inode(struct inode *inode) kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct efs_inode_info *ei = (struct efs_inode_info *) foo; diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index 88a6f8d0b88e..ae228ec54e94 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -283,10 +283,10 @@ static struct mutex epmutex; static struct poll_safewake psw; /* Slab cache used to allocate "struct epitem" */ -static struct kmem_cache *epi_cache __read_mostly; +static kmem_cache_t *epi_cache __read_mostly; /* Slab cache used to allocate "struct eppoll_entry" */ -static struct kmem_cache *pwq_cache __read_mostly; +static kmem_cache_t *pwq_cache __read_mostly; /* Virtual fs used to allocate inodes for eventpoll files */ static struct vfsmount *eventpoll_mnt __read_mostly; @@ -961,7 +961,7 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, struct epitem *epi = ep_item_from_epqueue(pt); struct eppoll_entry *pwq; - if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, GFP_KERNEL))) { + if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, SLAB_KERNEL))) { init_waitqueue_func_entry(&pwq->wait, ep_poll_callback); pwq->whead = whead; pwq->base = epi; @@ -1004,7 +1004,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct ep_pqueue epq; error = -ENOMEM; - if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL))) + if (!(epi = kmem_cache_alloc(epi_cache, SLAB_KERNEL))) goto eexit_1; /* Item initialization follow here ... */ diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index add0e03c3ea9..d993ea1a81ae 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -404,7 +404,7 @@ int setup_arg_pages(struct linux_binprm *bprm, bprm->loader += stack_base; bprm->exec += stack_base; - mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!mpnt) return -ENOMEM; @@ -1515,8 +1515,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) ispipe = 1; } else file = filp_open(corename, - O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, - 0600); + O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); if (IS_ERR(file)) goto fail_unlock; inode = file->f_dentry->d_inode; diff --git a/trunk/fs/ext2/ioctl.c b/trunk/fs/ext2/ioctl.c index e3cf8c81507f..1dfba77eab10 100644 --- a/trunk/fs/ext2/ioctl.c +++ b/trunk/fs/ext2/ioctl.c @@ -44,7 +44,6 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, if (!S_ISDIR(inode->i_mode)) flags &= ~EXT2_DIRSYNC_FL; - mutex_lock(&inode->i_mutex); oldflags = ei->i_flags; /* @@ -54,16 +53,13 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, * This test looks nicer. Thanks to Pauline Middelink */ if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { - if (!capable(CAP_LINUX_IMMUTABLE)) { - mutex_unlock(&inode->i_mutex); + if (!capable(CAP_LINUX_IMMUTABLE)) return -EPERM; - } } flags = flags & EXT2_FL_USER_MODIFIABLE; flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; ei->i_flags = flags; - mutex_unlock(&inode->i_mutex); ext2_set_inode_flags(inode); inode->i_ctime = CURRENT_TIME_SEC; diff --git a/trunk/fs/ext2/super.c b/trunk/fs/ext2/super.c index 255cef5f7420..d8b9abd95d07 100644 --- a/trunk/fs/ext2/super.c +++ b/trunk/fs/ext2/super.c @@ -135,12 +135,12 @@ static void ext2_put_super (struct super_block * sb) return; } -static struct kmem_cache * ext2_inode_cachep; +static kmem_cache_t * ext2_inode_cachep; static struct inode *ext2_alloc_inode(struct super_block *sb) { struct ext2_inode_info *ei; - ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL); + ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; #ifdef CONFIG_EXT2_FS_POSIX_ACL @@ -156,7 +156,7 @@ static void ext2_destroy_inode(struct inode *inode) kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; @@ -1090,10 +1090,8 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) { struct super_block *sb = dentry->d_sb; struct ext2_sb_info *sbi = EXT2_SB(sb); - struct ext2_super_block *es = sbi->s_es; unsigned long overhead; int i; - u64 fsid; if (test_opt (sb, MINIX_DF)) overhead = 0; @@ -1106,7 +1104,7 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) * All of the blocks before first_data_block are * overhead */ - overhead = le32_to_cpu(es->s_first_data_block); + overhead = le32_to_cpu(sbi->s_es->s_first_data_block); /* * Add the overhead attributed to the superblock and @@ -1127,18 +1125,14 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) buf->f_type = EXT2_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; - buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; + buf->f_blocks = le32_to_cpu(sbi->s_es->s_blocks_count) - overhead; buf->f_bfree = ext2_count_free_blocks(sb); - buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); - if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) + buf->f_bavail = buf->f_bfree - le32_to_cpu(sbi->s_es->s_r_blocks_count); + if (buf->f_bfree < le32_to_cpu(sbi->s_es->s_r_blocks_count)) buf->f_bavail = 0; - buf->f_files = le32_to_cpu(es->s_inodes_count); - buf->f_ffree = ext2_count_free_inodes(sb); + buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count); + buf->f_ffree = ext2_count_free_inodes (sb); buf->f_namelen = EXT2_NAME_LEN; - fsid = le64_to_cpup((void *)es->s_uuid) ^ - le64_to_cpup((void *)es->s_uuid + sizeof(u64)); - buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; - buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; return 0; } diff --git a/trunk/fs/ext2/xattr.c b/trunk/fs/ext2/xattr.c index 247efd0b51d6..af52a7f8b291 100644 --- a/trunk/fs/ext2/xattr.c +++ b/trunk/fs/ext2/xattr.c @@ -342,9 +342,12 @@ static void ext2_xattr_update_super_block(struct super_block *sb) if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR)) return; - EXT2_SET_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR); + lock_super(sb); + EXT2_SB(sb)->s_es->s_feature_compat |= + cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR); sb->s_dirt = 1; mark_buffer_dirty(EXT2_SB(sb)->s_sbh); + unlock_super(sb); } /* diff --git a/trunk/fs/ext3/Makefile b/trunk/fs/ext3/Makefile index e77766a8b3f0..704cd44a40c2 100644 --- a/trunk/fs/ext3/Makefile +++ b/trunk/fs/ext3/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o hash.o resize.o ext3_jbd.o + ioctl.o namei.o super.o symlink.o hash.o resize.o ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o diff --git a/trunk/fs/ext3/balloc.c b/trunk/fs/ext3/balloc.c index 22161740ba29..b41a7d7e20f0 100644 --- a/trunk/fs/ext3/balloc.c +++ b/trunk/fs/ext3/balloc.c @@ -144,7 +144,7 @@ static void __rsv_window_dump(struct rb_root *root, int verbose, printk("Block Allocation Reservation Windows Map (%s):\n", fn); while (n) { - rsv = rb_entry(n, struct ext3_reserve_window_node, rsv_node); + rsv = list_entry(n, struct ext3_reserve_window_node, rsv_node); if (verbose) printk("reservation window 0x%p " "start: %lu, end: %lu\n", @@ -730,7 +730,7 @@ find_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh, here = 0; p = ((char *)bh->b_data) + (here >> 3); - r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); + r = memscan(p, 0, (maxblocks - here + 7) >> 3); next = (r - ((char *)bh->b_data)) << 3; if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh)) @@ -949,7 +949,7 @@ static int find_next_reservable_window( prev = rsv; next = rb_next(&rsv->rsv_node); - rsv = rb_entry(next,struct ext3_reserve_window_node,rsv_node); + rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node); /* * Reached the last reservation, we can just append to the @@ -1148,7 +1148,7 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, * check if the first free block is within the * free space we just reserved */ - if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) + if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) return 0; /* success */ /* * if the first free bit we found is out of the reservable space @@ -1193,7 +1193,7 @@ static void try_to_extend_reservation(struct ext3_reserve_window_node *my_rsv, if (!next) my_rsv->rsv_end += size; else { - next_rsv = rb_entry(next, struct ext3_reserve_window_node, rsv_node); + next_rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) my_rsv->rsv_end += size; @@ -1271,7 +1271,7 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, } /* * grp_goal is a group relative block number (if there is a goal) - * 0 <= grp_goal < EXT3_BLOCKS_PER_GROUP(sb) + * 0 < grp_goal < EXT3_BLOCKS_PER_GROUP(sb) * first block is a filesystem wide block number * first block is the block number of the first block in this group */ @@ -1307,14 +1307,10 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, if (!goal_in_my_reservation(&my_rsv->rsv_window, grp_goal, group, sb)) grp_goal = -1; - } else if (grp_goal >= 0) { - int curr = my_rsv->rsv_end - - (grp_goal + group_first_block) + 1; - - if (curr < *count) - try_to_extend_reservation(my_rsv, sb, - *count - curr); - } + } else if (grp_goal > 0 && + (my_rsv->rsv_end-grp_goal+1) < *count) + try_to_extend_reservation(my_rsv, sb, + *count-my_rsv->rsv_end + grp_goal - 1); if ((my_rsv->rsv_start > group_last_block) || (my_rsv->rsv_end < group_first_block)) { @@ -1515,8 +1511,10 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, if (group_no >= ngroups) group_no = 0; gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); - if (!gdp) - goto io_error; + if (!gdp) { + *errp = -EIO; + goto out; + } free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); /* * skip this group if the number of @@ -1550,7 +1548,6 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, */ if (my_rsv) { my_rsv = NULL; - windowsz = 0; group_no = goal_group; goto retry_alloc; } diff --git a/trunk/fs/ext3/dir.c b/trunk/fs/ext3/dir.c index 5a9313ecd4ef..d0b54f30b914 100644 --- a/trunk/fs/ext3/dir.c +++ b/trunk/fs/ext3/dir.c @@ -154,9 +154,6 @@ static int ext3_readdir(struct file * filp, ext3_error (sb, "ext3_readdir", "directory #%lu contains a hole at offset %lu", inode->i_ino, (unsigned long)filp->f_pos); - /* corrupt size? Maybe no more blocks to read */ - if (filp->f_pos > inode->i_blocks << 9) - break; filp->f_pos += sb->s_blocksize - offset; continue; } diff --git a/trunk/fs/ext3/ext3_jbd.c b/trunk/fs/ext3/ext3_jbd.c deleted file mode 100644 index e1f91fd26a93..000000000000 --- a/trunk/fs/ext3/ext3_jbd.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Interface between ext3 and JBD - */ - -#include - -int __ext3_journal_get_undo_access(const char *where, handle_t *handle, - struct buffer_head *bh) -{ - int err = journal_get_undo_access(handle, bh); - if (err) - ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext3_journal_get_write_access(const char *where, handle_t *handle, - struct buffer_head *bh) -{ - int err = journal_get_write_access(handle, bh); - if (err) - ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext3_journal_forget(const char *where, handle_t *handle, - struct buffer_head *bh) -{ - int err = journal_forget(handle, bh); - if (err) - ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext3_journal_revoke(const char *where, handle_t *handle, - unsigned long blocknr, struct buffer_head *bh) -{ - int err = journal_revoke(handle, blocknr, bh); - if (err) - ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext3_journal_get_create_access(const char *where, - handle_t *handle, struct buffer_head *bh) -{ - int err = journal_get_create_access(handle, bh); - if (err) - ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext3_journal_dirty_metadata(const char *where, - handle_t *handle, struct buffer_head *bh) -{ - int err = journal_dirty_metadata(handle, bh); - if (err) - ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} diff --git a/trunk/fs/ext3/inode.c b/trunk/fs/ext3/inode.c index beaf25f5112f..03ba5bcab186 100644 --- a/trunk/fs/ext3/inode.c +++ b/trunk/fs/ext3/inode.c @@ -1148,102 +1148,37 @@ static int do_journal_get_write_access(handle_t *handle, return ext3_journal_get_write_access(handle, bh); } -/* - * The idea of this helper function is following: - * if prepare_write has allocated some blocks, but not all of them, the - * transaction must include the content of the newly allocated blocks. - * This content is expected to be set to zeroes by block_prepare_write(). - * 2006/10/14 SAW - */ -static int ext3_prepare_failure(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct address_space *mapping; - struct buffer_head *bh, *head, *next; - unsigned block_start, block_end; - unsigned blocksize; - int ret; - handle_t *handle = ext3_journal_current_handle(); - - mapping = page->mapping; - if (ext3_should_writeback_data(mapping->host)) { - /* optimization: no constraints about data */ -skip: - return ext3_journal_stop(handle); - } - - head = page_buffers(page); - blocksize = head->b_size; - for ( bh = head, block_start = 0; - bh != head || !block_start; - block_start = block_end, bh = next) - { - next = bh->b_this_page; - block_end = block_start + blocksize; - if (block_end <= from) - continue; - if (block_start >= to) { - block_start = to; - break; - } - if (!buffer_mapped(bh)) - /* prepare_write failed on this bh */ - break; - if (ext3_should_journal_data(mapping->host)) { - ret = do_journal_get_write_access(handle, bh); - if (ret) { - ext3_journal_stop(handle); - return ret; - } - } - /* - * block_start here becomes the first block where the current iteration - * of prepare_write failed. - */ - } - if (block_start <= from) - goto skip; - - /* commit allocated and zeroed buffers */ - return mapping->a_ops->commit_write(file, page, from, block_start); -} - static int ext3_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { struct inode *inode = page->mapping->host; - int ret, ret2; - int needed_blocks = ext3_writepage_trans_blocks(inode); + int ret, needed_blocks = ext3_writepage_trans_blocks(inode); handle_t *handle; int retries = 0; retry: handle = ext3_journal_start(inode, needed_blocks); - if (IS_ERR(handle)) - return PTR_ERR(handle); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out; + } if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) ret = nobh_prepare_write(page, from, to, ext3_get_block); else ret = block_prepare_write(page, from, to, ext3_get_block); if (ret) - goto failure; + goto prepare_write_failed; if (ext3_should_journal_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), from, to, NULL, do_journal_get_write_access); - if (ret) - /* fatal error, just put the handle and return */ - journal_stop(handle); } - return ret; - -failure: - ret2 = ext3_prepare_failure(file, page, from, to); - if (ret2 < 0) - return ret2; +prepare_write_failed: + if (ret) + ext3_journal_stop(handle); if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) goto retry; - /* retry number exceeded, or other error like -EDQUOT */ +out: return ret; } diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index 60d2f9dbdb00..906731a20f1a 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -552,15 +552,6 @@ static int htree_dirblock_to_tree(struct file *dir_file, dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0)); for (; de < top; de = ext3_next_entry(de)) { - if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, - (block<i_sb)) - +((char *)de - bh->b_data))) { - /* On error, skip the f_pos to the next block. */ - dir_file->f_pos = (dir_file->f_pos | - (dir->i_sb->s_blocksize - 1)) + 1; - brelse (bh); - return count; - } ext3fs_dirhash(de->name, de->name_len, hinfo); if ((hinfo->hash < start_hash) || ((hinfo->hash == start_hash) && diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 580b8a6ca979..afc2d4f42d77 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -436,7 +436,7 @@ static void ext3_put_super (struct super_block * sb) return; } -static struct kmem_cache *ext3_inode_cachep; +static kmem_cache_t *ext3_inode_cachep; /* * Called inside transaction, so use GFP_NOFS @@ -445,7 +445,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb) { struct ext3_inode_info *ei; - ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS); + ei = kmem_cache_alloc(ext3_inode_cachep, SLAB_NOFS); if (!ei) return NULL; #ifdef CONFIG_EXT3_FS_POSIX_ACL @@ -462,7 +462,7 @@ static void ext3_destroy_inode(struct inode *inode) kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; @@ -1264,12 +1264,6 @@ static void ext3_orphan_cleanup (struct super_block * sb, return; } - if (bdev_read_only(sb->s_bdev)) { - printk(KERN_ERR "EXT3-fs: write access " - "unavailable, skipping orphan cleanup.\n"); - return; - } - if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { if (es->s_last_orphan) jbd_debug(1, "Errors on filesystem, " @@ -2393,7 +2387,6 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) struct ext3_super_block *es = sbi->s_es; ext3_fsblk_t overhead; int i; - u64 fsid; if (test_opt (sb, MINIX_DF)) overhead = 0; @@ -2440,10 +2433,6 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) buf->f_files = le32_to_cpu(es->s_inodes_count); buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); buf->f_namelen = EXT3_NAME_LEN; - fsid = le64_to_cpup((void *)es->s_uuid) ^ - le64_to_cpup((void *)es->s_uuid + sizeof(u64)); - buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; - buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; return 0; } diff --git a/trunk/fs/ext3/xattr.c b/trunk/fs/ext3/xattr.c index 99857a400f4b..f86f2482f01d 100644 --- a/trunk/fs/ext3/xattr.c +++ b/trunk/fs/ext3/xattr.c @@ -459,11 +459,14 @@ static void ext3_xattr_update_super_block(handle_t *handle, if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) return; + lock_super(sb); if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { - EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR); + EXT3_SB(sb)->s_es->s_feature_compat |= + cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); sb->s_dirt = 1; ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); } + unlock_super(sb); } /* diff --git a/trunk/fs/ext4/Makefile b/trunk/fs/ext4/Makefile index ae6e7e502ac9..a6acb96ebeb9 100644 --- a/trunk/fs/ext4/Makefile +++ b/trunk/fs/ext4/Makefile @@ -5,8 +5,7 @@ obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ - ext4_jbd2.o + ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index c4dd1103ccf1..5d45582f9517 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -165,7 +165,7 @@ static void __rsv_window_dump(struct rb_root *root, int verbose, printk("Block Allocation Reservation Windows Map (%s):\n", fn); while (n) { - rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node); + rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); if (verbose) printk("reservation window 0x%p " "start: %llu, end: %llu\n", @@ -747,7 +747,7 @@ find_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh, here = 0; p = ((char *)bh->b_data) + (here >> 3); - r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); + r = memscan(p, 0, (maxblocks - here + 7) >> 3); next = (r - ((char *)bh->b_data)) << 3; if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh)) @@ -966,7 +966,7 @@ static int find_next_reservable_window( prev = rsv; next = rb_next(&rsv->rsv_node); - rsv = rb_entry(next,struct ext4_reserve_window_node,rsv_node); + rsv = list_entry(next,struct ext4_reserve_window_node,rsv_node); /* * Reached the last reservation, we can just append to the @@ -1165,7 +1165,7 @@ static int alloc_new_reservation(struct ext4_reserve_window_node *my_rsv, * check if the first free block is within the * free space we just reserved */ - if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) + if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) return 0; /* success */ /* * if the first free bit we found is out of the reservable space @@ -1210,7 +1210,7 @@ static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv, if (!next) my_rsv->rsv_end += size; else { - next_rsv = rb_entry(next, struct ext4_reserve_window_node, rsv_node); + next_rsv = list_entry(next, struct ext4_reserve_window_node, rsv_node); if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) my_rsv->rsv_end += size; @@ -1288,7 +1288,7 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, } /* * grp_goal is a group relative block number (if there is a goal) - * 0 <= grp_goal < EXT4_BLOCKS_PER_GROUP(sb) + * 0 < grp_goal < EXT4_BLOCKS_PER_GROUP(sb) * first block is a filesystem wide block number * first block is the block number of the first block in this group */ @@ -1324,14 +1324,10 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, if (!goal_in_my_reservation(&my_rsv->rsv_window, grp_goal, group, sb)) grp_goal = -1; - } else if (grp_goal >= 0) { - int curr = my_rsv->rsv_end - - (grp_goal + group_first_block) + 1; - - if (curr < *count) - try_to_extend_reservation(my_rsv, sb, - *count - curr); - } + } else if (grp_goal > 0 && + (my_rsv->rsv_end-grp_goal+1) < *count) + try_to_extend_reservation(my_rsv, sb, + *count-my_rsv->rsv_end + grp_goal - 1); if ((my_rsv->rsv_start > group_last_block) || (my_rsv->rsv_end < group_first_block)) { @@ -1529,8 +1525,10 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, if (group_no >= ngroups) group_no = 0; gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); - if (!gdp) - goto io_error; + if (!gdp) { + *errp = -EIO; + goto out; + } free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); /* * skip this group if the number of @@ -1564,7 +1562,6 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, */ if (my_rsv) { my_rsv = NULL; - windowsz = 0; group_no = goal_group; goto retry_alloc; } diff --git a/trunk/fs/ext4/dir.c b/trunk/fs/ext4/dir.c index f2ed3e7fb9f5..f8595787a70e 100644 --- a/trunk/fs/ext4/dir.c +++ b/trunk/fs/ext4/dir.c @@ -153,9 +153,6 @@ static int ext4_readdir(struct file * filp, ext4_error (sb, "ext4_readdir", "directory #%lu contains a hole at offset %lu", inode->i_ino, (unsigned long)filp->f_pos); - /* corrupt size? Maybe no more blocks to read */ - if (filp->f_pos > inode->i_blocks << 9) - break; filp->f_pos += sb->s_blocksize - offset; continue; } diff --git a/trunk/fs/ext4/ext4_jbd2.c b/trunk/fs/ext4/ext4_jbd2.c deleted file mode 100644 index d6afe4e27340..000000000000 --- a/trunk/fs/ext4/ext4_jbd2.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Interface between ext4 and JBD - */ - -#include - -int __ext4_journal_get_undo_access(const char *where, handle_t *handle, - struct buffer_head *bh) -{ - int err = jbd2_journal_get_undo_access(handle, bh); - if (err) - ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext4_journal_get_write_access(const char *where, handle_t *handle, - struct buffer_head *bh) -{ - int err = jbd2_journal_get_write_access(handle, bh); - if (err) - ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext4_journal_forget(const char *where, handle_t *handle, - struct buffer_head *bh) -{ - int err = jbd2_journal_forget(handle, bh); - if (err) - ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext4_journal_revoke(const char *where, handle_t *handle, - ext4_fsblk_t blocknr, struct buffer_head *bh) -{ - int err = jbd2_journal_revoke(handle, blocknr, bh); - if (err) - ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext4_journal_get_create_access(const char *where, - handle_t *handle, struct buffer_head *bh) -{ - int err = jbd2_journal_get_create_access(handle, bh); - if (err) - ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} - -int __ext4_journal_dirty_metadata(const char *where, - handle_t *handle, struct buffer_head *bh) -{ - int err = jbd2_journal_dirty_metadata(handle, bh); - if (err) - ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return err; -} diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index dc2724fa7622..2608dce18f3e 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -48,7 +48,7 @@ * ext_pblock: * combine low and high parts of physical block number into ext4_fsblk_t */ -static ext4_fsblk_t ext_pblock(struct ext4_extent *ex) +static inline ext4_fsblk_t ext_pblock(struct ext4_extent *ex) { ext4_fsblk_t block; @@ -61,7 +61,7 @@ static ext4_fsblk_t ext_pblock(struct ext4_extent *ex) * idx_pblock: * combine low and high parts of a leaf physical block number into ext4_fsblk_t */ -static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) +static inline ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) { ext4_fsblk_t block; @@ -75,7 +75,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) * stores a large physical block number into an extent struct, * breaking it into parts */ -static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) +static inline void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) { ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff)); ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); @@ -86,7 +86,7 @@ static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) * stores a large physical block number into an index struct, * breaking it into parts */ -static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) +static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) { ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff)); ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); @@ -186,8 +186,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, depth = path->p_depth; /* try to predict block placement */ - ex = path[depth].p_ext; - if (ex) + if ((ex = path[depth].p_ext)) return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block)); /* it looks like index is empty; @@ -216,7 +215,7 @@ ext4_ext_new_block(handle_t *handle, struct inode *inode, return newblock; } -static int ext4_ext_space_block(struct inode *inode) +static inline int ext4_ext_space_block(struct inode *inode) { int size; @@ -229,7 +228,7 @@ static int ext4_ext_space_block(struct inode *inode) return size; } -static int ext4_ext_space_block_idx(struct inode *inode) +static inline int ext4_ext_space_block_idx(struct inode *inode) { int size; @@ -242,7 +241,7 @@ static int ext4_ext_space_block_idx(struct inode *inode) return size; } -static int ext4_ext_space_root(struct inode *inode) +static inline int ext4_ext_space_root(struct inode *inode) { int size; @@ -256,7 +255,7 @@ static int ext4_ext_space_root(struct inode *inode) return size; } -static int ext4_ext_space_root_idx(struct inode *inode) +static inline int ext4_ext_space_root_idx(struct inode *inode) { int size; @@ -477,12 +476,13 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) /* account possible depth increase */ if (!path) { - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2), + path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 2), GFP_NOFS); if (!path) return ERR_PTR(-ENOMEM); alloc = 1; } + memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1)); path[0].p_hdr = eh; /* walk through the tree */ @@ -543,8 +543,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, struct ext4_extent_idx *ix; int len, err; - err = ext4_ext_get_access(handle, inode, curp); - if (err) + if ((err = ext4_ext_get_access(handle, inode, curp))) return err; BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block)); @@ -642,9 +641,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, * We need this to handle errors and free blocks * upon them. */ - ablocks = kzalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); + ablocks = kmalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); if (!ablocks) return -ENOMEM; + memset(ablocks, 0, sizeof(ext4_fsblk_t) * depth); /* allocate all needed blocks */ ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); @@ -665,8 +665,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, } lock_buffer(bh); - err = ext4_journal_get_create_access(handle, bh); - if (err) + if ((err = ext4_journal_get_create_access(handle, bh))) goto cleanup; neh = ext_block_hdr(bh); @@ -703,21 +702,18 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, set_buffer_uptodate(bh); unlock_buffer(bh); - err = ext4_journal_dirty_metadata(handle, bh); - if (err) + if ((err = ext4_journal_dirty_metadata(handle, bh))) goto cleanup; brelse(bh); bh = NULL; /* correct old leaf */ if (m) { - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) + if ((err = ext4_ext_get_access(handle, inode, path + depth))) goto cleanup; path[depth].p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m); - err = ext4_ext_dirty(handle, inode, path + depth); - if (err) + if ((err = ext4_ext_dirty(handle, inode, path + depth))) goto cleanup; } @@ -740,8 +736,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, } lock_buffer(bh); - err = ext4_journal_get_create_access(handle, bh); - if (err) + if ((err = ext4_journal_get_create_access(handle, bh))) goto cleanup; neh = ext_block_hdr(bh); @@ -785,8 +780,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, set_buffer_uptodate(bh); unlock_buffer(bh); - err = ext4_journal_dirty_metadata(handle, bh); - if (err) + if ((err = ext4_journal_dirty_metadata(handle, bh))) goto cleanup; brelse(bh); bh = NULL; @@ -806,6 +800,9 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, } /* insert new index */ + if (err) + goto cleanup; + err = ext4_ext_insert_index(handle, inode, path + at, le32_to_cpu(border), newblock); @@ -860,8 +857,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, } lock_buffer(bh); - err = ext4_journal_get_create_access(handle, bh); - if (err) { + if ((err = ext4_journal_get_create_access(handle, bh))) { unlock_buffer(bh); goto out; } @@ -881,13 +877,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, set_buffer_uptodate(bh); unlock_buffer(bh); - err = ext4_journal_dirty_metadata(handle, bh); - if (err) + if ((err = ext4_journal_dirty_metadata(handle, bh))) goto out; /* create index in new top-level index: num,max,pointer */ - err = ext4_ext_get_access(handle, inode, curp); - if (err) + if ((err = ext4_ext_get_access(handle, inode, curp))) goto out; curp->p_hdr->eh_magic = EXT4_EXT_MAGIC; @@ -1079,31 +1073,27 @@ int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode, */ k = depth - 1; border = path[depth].p_ext->ee_block; - err = ext4_ext_get_access(handle, inode, path + k); - if (err) + if ((err = ext4_ext_get_access(handle, inode, path + k))) return err; path[k].p_idx->ei_block = border; - err = ext4_ext_dirty(handle, inode, path + k); - if (err) + if ((err = ext4_ext_dirty(handle, inode, path + k))) return err; while (k--) { /* change all left-side indexes */ if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr)) break; - err = ext4_ext_get_access(handle, inode, path + k); - if (err) + if ((err = ext4_ext_get_access(handle, inode, path + k))) break; path[k].p_idx->ei_block = border; - err = ext4_ext_dirty(handle, inode, path + k); - if (err) + if ((err = ext4_ext_dirty(handle, inode, path + k))) break; } return err; } -static int +static int inline ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, struct ext4_extent *ex2) { @@ -1155,8 +1145,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, le16_to_cpu(newext->ee_len), le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len), ext_pblock(ex)); - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) + if ((err = ext4_ext_get_access(handle, inode, path + depth))) return err; ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len) + le16_to_cpu(newext->ee_len)); @@ -1206,8 +1195,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, has_space: nearex = path[depth].p_ext; - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) + if ((err = ext4_ext_get_access(handle, inode, path + depth))) goto cleanup; if (!nearex) { @@ -1395,7 +1383,7 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, return err; } -static void +static inline void ext4_ext_put_in_cache(struct inode *inode, __u32 block, __u32 len, __u32 start, int type) { @@ -1413,7 +1401,7 @@ ext4_ext_put_in_cache(struct inode *inode, __u32 block, * calculate boundaries of the gap that the requested block fits into * and cache this gap */ -static void +static inline void ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, unsigned long block) { @@ -1454,7 +1442,7 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP); } -static int +static inline int ext4_ext_in_cache(struct inode *inode, unsigned long block, struct ext4_extent *ex) { @@ -1501,12 +1489,10 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, path--; leaf = idx_pblock(path->p_idx); BUG_ON(path->p_hdr->eh_entries == 0); - err = ext4_ext_get_access(handle, inode, path); - if (err) + if ((err = ext4_ext_get_access(handle, inode, path))) return err; path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1); - err = ext4_ext_dirty(handle, inode, path); - if (err) + if ((err = ext4_ext_dirty(handle, inode, path))) return err; ext_debug("index is empty, remove it, free block %llu\n", leaf); bh = sb_find_get_block(inode->i_sb, leaf); @@ -1523,7 +1509,7 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, * the caller should calculate credits under truncate_mutex and * pass the actual path. */ -int ext4_ext_calc_credits_for_insert(struct inode *inode, +int inline ext4_ext_calc_credits_for_insert(struct inode *inode, struct ext4_ext_path *path) { int depth, needed; @@ -1548,17 +1534,16 @@ int ext4_ext_calc_credits_for_insert(struct inode *inode, /* * tree can be full, so it would need to grow in depth: - * we need one credit to modify old root, credits for - * new root will be added in split accounting + * allocation + old root + new root */ - needed += 1; + needed += 2 + 1 + 1; /* * Index split can happen, we would need: * allocate intermediate indexes (bitmap + group) * + change two blocks at each level, but root (already included) */ - needed += (depth * 2) + (depth * 2); + needed = (depth * 2) + (depth * 2); /* any allocation modifies superblock */ needed += 1; @@ -1733,7 +1718,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, * ext4_ext_more_to_rm: * returns 1 if current index has to be freed (even partial) */ -static int +static int inline ext4_ext_more_to_rm(struct ext4_ext_path *path) { BUG_ON(path->p_idx == NULL); @@ -1771,11 +1756,12 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) * We start scanning from right side, freeing all the blocks * after i_size and walking into the tree depth-wise. */ - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL); + path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL); if (path == NULL) { ext4_journal_stop(handle); return -ENOMEM; } + memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1)); path[0].p_hdr = ext_inode_hdr(inode); if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) { err = -EIO; @@ -1946,8 +1932,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, mutex_lock(&EXT4_I(inode)->truncate_mutex); /* check in cache */ - goal = ext4_ext_in_cache(inode, iblock, &newex); - if (goal) { + if ((goal = ext4_ext_in_cache(inode, iblock, &newex))) { if (goal == EXT4_EXT_CACHE_GAP) { if (!create) { /* block isn't allocated yet and @@ -1986,8 +1971,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, */ BUG_ON(path[depth].p_ext == NULL && depth != 0); - ex = path[depth].p_ext; - if (ex) { + if ((ex = path[depth].p_ext)) { unsigned long ee_block = le32_to_cpu(ex->ee_block); ext4_fsblk_t ee_start = ext_pblock(ex); unsigned short ee_len = le16_to_cpu(ex->ee_len); diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index 1d85d4ec9598..0a60ec5a16db 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -1147,102 +1147,37 @@ static int do_journal_get_write_access(handle_t *handle, return ext4_journal_get_write_access(handle, bh); } -/* - * The idea of this helper function is following: - * if prepare_write has allocated some blocks, but not all of them, the - * transaction must include the content of the newly allocated blocks. - * This content is expected to be set to zeroes by block_prepare_write(). - * 2006/10/14 SAW - */ -static int ext4_prepare_failure(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct address_space *mapping; - struct buffer_head *bh, *head, *next; - unsigned block_start, block_end; - unsigned blocksize; - int ret; - handle_t *handle = ext4_journal_current_handle(); - - mapping = page->mapping; - if (ext4_should_writeback_data(mapping->host)) { - /* optimization: no constraints about data */ -skip: - return ext4_journal_stop(handle); - } - - head = page_buffers(page); - blocksize = head->b_size; - for ( bh = head, block_start = 0; - bh != head || !block_start; - block_start = block_end, bh = next) - { - next = bh->b_this_page; - block_end = block_start + blocksize; - if (block_end <= from) - continue; - if (block_start >= to) { - block_start = to; - break; - } - if (!buffer_mapped(bh)) - /* prepare_write failed on this bh */ - break; - if (ext4_should_journal_data(mapping->host)) { - ret = do_journal_get_write_access(handle, bh); - if (ret) { - ext4_journal_stop(handle); - return ret; - } - } - /* - * block_start here becomes the first block where the current iteration - * of prepare_write failed. - */ - } - if (block_start <= from) - goto skip; - - /* commit allocated and zeroed buffers */ - return mapping->a_ops->commit_write(file, page, from, block_start); -} - static int ext4_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { struct inode *inode = page->mapping->host; - int ret, ret2; - int needed_blocks = ext4_writepage_trans_blocks(inode); + int ret, needed_blocks = ext4_writepage_trans_blocks(inode); handle_t *handle; int retries = 0; retry: handle = ext4_journal_start(inode, needed_blocks); - if (IS_ERR(handle)) - return PTR_ERR(handle); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out; + } if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) ret = nobh_prepare_write(page, from, to, ext4_get_block); else ret = block_prepare_write(page, from, to, ext4_get_block); if (ret) - goto failure; + goto prepare_write_failed; if (ext4_should_journal_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), from, to, NULL, do_journal_get_write_access); - if (ret) - /* fatal error, just put the handle and return */ - journal_stop(handle); } - return ret; - -failure: - ret2 = ext4_prepare_failure(file, page, from, to); - if (ret2 < 0) - return ret2; +prepare_write_failed: + if (ret) + ext4_journal_stop(handle); if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; - /* retry number exceeded, or other error like -EDQUOT */ +out: return ret; } diff --git a/trunk/fs/ext4/namei.c b/trunk/fs/ext4/namei.c index 859990eac504..8b1bd03d20f5 100644 --- a/trunk/fs/ext4/namei.c +++ b/trunk/fs/ext4/namei.c @@ -552,15 +552,6 @@ static int htree_dirblock_to_tree(struct file *dir_file, dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0)); for (; de < top; de = ext4_next_entry(de)) { - if (!ext4_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, - (block<i_sb)) - +((char *)de - bh->b_data))) { - /* On error, skip the f_pos to the next block. */ - dir_file->f_pos = (dir_file->f_pos | - (dir->i_sb->s_blocksize - 1)) + 1; - brelse (bh); - return count; - } ext4fs_dirhash(de->name, de->name_len, hinfo); if ((hinfo->hash < start_hash) || ((hinfo->hash == start_hash) && diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 486a641ca71b..b4b022aa2bc2 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -486,7 +486,7 @@ static void ext4_put_super (struct super_block * sb) return; } -static struct kmem_cache *ext4_inode_cachep; +static kmem_cache_t *ext4_inode_cachep; /* * Called inside transaction, so use GFP_NOFS @@ -495,7 +495,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) { struct ext4_inode_info *ei; - ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); + ei = kmem_cache_alloc(ext4_inode_cachep, SLAB_NOFS); if (!ei) return NULL; #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL @@ -513,7 +513,7 @@ static void ext4_destroy_inode(struct inode *inode) kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; @@ -1321,12 +1321,6 @@ static void ext4_orphan_cleanup (struct super_block * sb, return; } - if (bdev_read_only(sb->s_bdev)) { - printk(KERN_ERR "EXT4-fs: write access " - "unavailable, skipping orphan cleanup.\n"); - return; - } - if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { if (es->s_last_orphan) jbd_debug(1, "Errors on filesystem, " @@ -2466,7 +2460,6 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) struct ext4_super_block *es = sbi->s_es; ext4_fsblk_t overhead; int i; - u64 fsid; if (test_opt (sb, MINIX_DF)) overhead = 0; @@ -2513,10 +2506,6 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) buf->f_files = le32_to_cpu(es->s_inodes_count); buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); buf->f_namelen = EXT4_NAME_LEN; - fsid = le64_to_cpup((void *)es->s_uuid) ^ - le64_to_cpup((void *)es->s_uuid + sizeof(u64)); - buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; - buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; return 0; } diff --git a/trunk/fs/ext4/xattr.c b/trunk/fs/ext4/xattr.c index dc969c357aa1..63233cd946a7 100644 --- a/trunk/fs/ext4/xattr.c +++ b/trunk/fs/ext4/xattr.c @@ -459,11 +459,14 @@ static void ext4_xattr_update_super_block(handle_t *handle, if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR)) return; + lock_super(sb); if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { - EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR); + EXT4_SB(sb)->s_es->s_feature_compat |= + cpu_to_le32(EXT4_FEATURE_COMPAT_EXT_ATTR); sb->s_dirt = 1; ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); } + unlock_super(sb); } /* diff --git a/trunk/fs/fat/cache.c b/trunk/fs/fat/cache.c index 05c2941c74f2..82cc4f59e3ba 100644 --- a/trunk/fs/fat/cache.c +++ b/trunk/fs/fat/cache.c @@ -34,9 +34,9 @@ static inline int fat_max_cache(struct inode *inode) return FAT_MAX_CACHE; } -static struct kmem_cache *fat_cache_cachep; +static kmem_cache_t *fat_cache_cachep; -static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct fat_cache *cache = (struct fat_cache *)foo; @@ -63,7 +63,7 @@ void fat_cache_destroy(void) static inline struct fat_cache *fat_cache_alloc(struct inode *inode) { - return kmem_cache_alloc(fat_cache_cachep, GFP_KERNEL); + return kmem_cache_alloc(fat_cache_cachep, SLAB_KERNEL); } static inline void fat_cache_free(struct fat_cache *cache) diff --git a/trunk/fs/fat/inode.c b/trunk/fs/fat/inode.c index a9e4688582a2..78945b53b0f8 100644 --- a/trunk/fs/fat/inode.c +++ b/trunk/fs/fat/inode.c @@ -477,12 +477,12 @@ static void fat_put_super(struct super_block *sb) kfree(sbi); } -static struct kmem_cache *fat_inode_cachep; +static kmem_cache_t *fat_inode_cachep; static struct inode *fat_alloc_inode(struct super_block *sb) { struct msdos_inode_info *ei; - ei = kmem_cache_alloc(fat_inode_cachep, GFP_KERNEL); + ei = kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -493,7 +493,7 @@ static void fat_destroy_inode(struct inode *inode) kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index 4740d35e52cd..e4f26165f12a 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -553,7 +553,7 @@ int send_sigurg(struct fown_struct *fown) } static DEFINE_RWLOCK(fasync_lock); -static struct kmem_cache *fasync_cache __read_mostly; +static kmem_cache_t *fasync_cache __read_mostly; /* * fasync_helper() is used by some character device drivers (mainly mice) @@ -567,7 +567,7 @@ int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fap int result = 0; if (on) { - new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); + new = kmem_cache_alloc(fasync_cache, SLAB_KERNEL); if (!new) return -ENOMEM; } diff --git a/trunk/fs/file.c b/trunk/fs/file.c index 51aef675470f..3787e82f54c1 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -21,6 +21,7 @@ struct fdtable_defer { spinlock_t lock; struct work_struct wq; + struct timer_list timer; struct fdtable *next; }; @@ -74,6 +75,22 @@ static void __free_fdtable(struct fdtable *fdt) kfree(fdt); } +static void fdtable_timer(unsigned long data) +{ + struct fdtable_defer *fddef = (struct fdtable_defer *)data; + + spin_lock(&fddef->lock); + /* + * If someone already emptied the queue return. + */ + if (!fddef->next) + goto out; + if (!schedule_work(&fddef->wq)) + mod_timer(&fddef->timer, 5); +out: + spin_unlock(&fddef->lock); +} + static void free_fdtable_work(struct work_struct *work) { struct fdtable_defer *f = @@ -127,8 +144,13 @@ static void free_fdtable_rcu(struct rcu_head *rcu) spin_lock(&fddef->lock); fdt->next = fddef->next; fddef->next = fdt; - /* vmallocs are handled from the workqueue context */ - schedule_work(&fddef->wq); + /* + * vmallocs are handled from the workqueue context. + * If the per-cpu workqueue is running, then we + * defer work scheduling through a timer. + */ + if (!schedule_work(&fddef->wq)) + mod_timer(&fddef->timer, 5); spin_unlock(&fddef->lock); put_cpu_var(fdtable_defer_list); } @@ -332,6 +354,9 @@ static void __devinit fdtable_defer_list_init(int cpu) struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); spin_lock_init(&fddef->lock); INIT_WORK(&fddef->wq, free_fdtable_work); + init_timer(&fddef->timer); + fddef->timer.data = (unsigned long)fddef; + fddef->timer.function = fdtable_timer; fddef->next = NULL; } diff --git a/trunk/fs/freevxfs/vxfs_inode.c b/trunk/fs/freevxfs/vxfs_inode.c index 0b7ae897cb78..4786d51ad3bd 100644 --- a/trunk/fs/freevxfs/vxfs_inode.c +++ b/trunk/fs/freevxfs/vxfs_inode.c @@ -46,7 +46,7 @@ extern const struct address_space_operations vxfs_immed_aops; extern struct inode_operations vxfs_immed_symlink_iops; -struct kmem_cache *vxfs_inode_cachep; +kmem_cache_t *vxfs_inode_cachep; #ifdef DIAGNOSTIC @@ -103,7 +103,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) struct vxfs_inode_info *vip; struct vxfs_dinode *dip; - if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) + if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) goto fail; dip = (struct vxfs_dinode *)(bp->b_data + offset); memcpy(vip, dip, sizeof(*vip)); @@ -145,7 +145,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp) struct vxfs_dinode *dip; caddr_t kaddr = (char *)page_address(pp); - if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) + if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) goto fail; dip = (struct vxfs_dinode *)(kaddr + offset); memcpy(vip, dip, sizeof(*vip)); diff --git a/trunk/fs/fuse/dev.c b/trunk/fs/fuse/dev.c index 357764d85ff1..66571eafbb1e 100644 --- a/trunk/fs/fuse/dev.c +++ b/trunk/fs/fuse/dev.c @@ -19,7 +19,7 @@ MODULE_ALIAS_MISCDEV(FUSE_MINOR); -static struct kmem_cache *fuse_req_cachep; +static kmem_cache_t *fuse_req_cachep; static struct fuse_conn *fuse_get_conn(struct file *file) { @@ -41,7 +41,7 @@ static void fuse_request_init(struct fuse_req *req) struct fuse_req *fuse_request_alloc(void) { - struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL); + struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL); if (req) fuse_request_init(req); return req; diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index 1cabdb229adb..c71a6c092ad9 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -141,6 +141,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) struct fuse_req *forget_req; struct dentry *parent; + /* Doesn't hurt to "reset" the validity timeout */ + fuse_invalidate_entry_cache(entry); + /* For negative dentries, always do a fresh lookup */ if (!inode) return 0; @@ -1024,8 +1027,6 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) if (attr->ia_valid & ATTR_SIZE) { unsigned long limit; is_truncate = 1; - if (IS_SWAPFILE(inode)) - return -ETXTBSY; limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { send_sig(SIGXFSZ, current, 0); diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 128f79c40803..763a50daf1c0 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -754,42 +754,6 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) return err; } -static sector_t fuse_bmap(struct address_space *mapping, sector_t block) -{ - struct inode *inode = mapping->host; - struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_req *req; - struct fuse_bmap_in inarg; - struct fuse_bmap_out outarg; - int err; - - if (!inode->i_sb->s_bdev || fc->no_bmap) - return 0; - - req = fuse_get_req(fc); - if (IS_ERR(req)) - return 0; - - memset(&inarg, 0, sizeof(inarg)); - inarg.block = block; - inarg.blocksize = inode->i_sb->s_blocksize; - req->in.h.opcode = FUSE_BMAP; - req->in.h.nodeid = get_node_id(inode); - req->in.numargs = 1; - req->in.args[0].size = sizeof(inarg); - req->in.args[0].value = &inarg; - req->out.numargs = 1; - req->out.args[0].size = sizeof(outarg); - req->out.args[0].value = &outarg; - request_send(fc, req); - err = req->out.h.error; - fuse_put_request(fc, req); - if (err == -ENOSYS) - fc->no_bmap = 1; - - return err ? 0 : outarg.block; -} - static const struct file_operations fuse_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, @@ -823,7 +787,6 @@ static const struct address_space_operations fuse_file_aops = { .commit_write = fuse_commit_write, .readpages = fuse_readpages, .set_page_dirty = fuse_set_page_dirty, - .bmap = fuse_bmap, }; void fuse_init_file_inode(struct inode *inode) diff --git a/trunk/fs/fuse/fuse_i.h b/trunk/fs/fuse/fuse_i.h index b98b20de7405..91edb8932d90 100644 --- a/trunk/fs/fuse/fuse_i.h +++ b/trunk/fs/fuse/fuse_i.h @@ -298,9 +298,6 @@ struct fuse_conn { reply, before any other request, and never cleared */ unsigned conn_error : 1; - /** Connection successful. Only set in INIT */ - unsigned conn_init : 1; - /** Do readpages asynchronously? Only set in INIT */ unsigned async_read : 1; @@ -342,9 +339,6 @@ struct fuse_conn { /** Is interrupt not implemented by fs? */ unsigned no_interrupt : 1; - /** Is bmap not implemented by fs? */ - unsigned no_bmap : 1; - /** The number of requests waiting for completion */ atomic_t num_waiting; @@ -371,9 +365,6 @@ struct fuse_conn { /** Key for lock owner ID scrambling */ u32 scramble_key[4]; - - /** Reserved request for the DESTROY message */ - struct fuse_req *destroy_req; }; static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index 12450d2b320e..fc4203570370 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -22,7 +22,7 @@ MODULE_AUTHOR("Miklos Szeredi "); MODULE_DESCRIPTION("Filesystem in Userspace"); MODULE_LICENSE("GPL"); -static struct kmem_cache *fuse_inode_cachep; +static kmem_cache_t *fuse_inode_cachep; struct list_head fuse_conn_list; DEFINE_MUTEX(fuse_mutex); @@ -39,7 +39,6 @@ struct fuse_mount_data { unsigned group_id_present : 1; unsigned flags; unsigned max_read; - unsigned blksize; }; static struct inode *fuse_alloc_inode(struct super_block *sb) @@ -47,7 +46,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) struct inode *inode; struct fuse_inode *fi; - inode = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL); + inode = kmem_cache_alloc(fuse_inode_cachep, SLAB_KERNEL); if (!inode) return NULL; @@ -206,23 +205,10 @@ static void fuse_umount_begin(struct vfsmount *vfsmnt, int flags) fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb)); } -static void fuse_send_destroy(struct fuse_conn *fc) -{ - struct fuse_req *req = fc->destroy_req; - if (req && fc->conn_init) { - fc->destroy_req = NULL; - req->in.h.opcode = FUSE_DESTROY; - req->force = 1; - request_send(fc, req); - fuse_put_request(fc, req); - } -} - static void fuse_put_super(struct super_block *sb) { struct fuse_conn *fc = get_fuse_conn_super(sb); - fuse_send_destroy(fc); spin_lock(&fc->lock); fc->connected = 0; fc->blocked = 0; @@ -288,7 +274,6 @@ enum { OPT_DEFAULT_PERMISSIONS, OPT_ALLOW_OTHER, OPT_MAX_READ, - OPT_BLKSIZE, OPT_ERR }; @@ -300,16 +285,14 @@ static match_table_t tokens = { {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, {OPT_ALLOW_OTHER, "allow_other"}, {OPT_MAX_READ, "max_read=%u"}, - {OPT_BLKSIZE, "blksize=%u"}, {OPT_ERR, NULL} }; -static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) +static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) { char *p; memset(d, 0, sizeof(struct fuse_mount_data)); d->max_read = ~0; - d->blksize = 512; while ((p = strsep(&opt, ",")) != NULL) { int token; @@ -362,12 +345,6 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) d->max_read = value; break; - case OPT_BLKSIZE: - if (!is_bdev || match_int(&args[0], &value)) - return 0; - d->blksize = value; - break; - default: return 0; } @@ -423,8 +400,6 @@ static struct fuse_conn *new_conn(void) void fuse_conn_put(struct fuse_conn *fc) { if (atomic_dec_and_test(&fc->count)) { - if (fc->destroy_req) - fuse_request_free(fc->destroy_req); mutex_destroy(&fc->inst_mutex); kfree(fc); } @@ -481,7 +456,6 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); fc->minor = arg->minor; fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; - fc->conn_init = 1; } fuse_put_request(fc, req); fc->blocked = 0; @@ -526,23 +500,15 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) struct dentry *root_dentry; struct fuse_req *init_req; int err; - int is_bdev = sb->s_bdev != NULL; if (sb->s_flags & MS_MANDLOCK) return -EINVAL; - if (!parse_fuse_opt((char *) data, &d, is_bdev)) + if (!parse_fuse_opt((char *) data, &d)) return -EINVAL; - if (is_bdev) { -#ifdef CONFIG_BLOCK - if (!sb_set_blocksize(sb, d.blksize)) - return -EINVAL; -#endif - } else { - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; - } + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = FUSE_SUPER_MAGIC; sb->s_op = &fuse_super_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; @@ -581,12 +547,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) if (!init_req) goto err_put_root; - if (is_bdev) { - fc->destroy_req = fuse_request_alloc(); - if (!fc->destroy_req) - goto err_put_root; - } - mutex_lock(&fuse_mutex); err = -EINVAL; if (file->private_data) @@ -638,47 +598,10 @@ static struct file_system_type fuse_fs_type = { .kill_sb = kill_anon_super, }; -#ifdef CONFIG_BLOCK -static int fuse_get_sb_blk(struct file_system_type *fs_type, - int flags, const char *dev_name, - void *raw_data, struct vfsmount *mnt) -{ - return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super, - mnt); -} - -static struct file_system_type fuseblk_fs_type = { - .owner = THIS_MODULE, - .name = "fuseblk", - .get_sb = fuse_get_sb_blk, - .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, -}; - -static inline int register_fuseblk(void) -{ - return register_filesystem(&fuseblk_fs_type); -} - -static inline void unregister_fuseblk(void) -{ - unregister_filesystem(&fuseblk_fs_type); -} -#else -static inline int register_fuseblk(void) -{ - return 0; -} - -static inline void unregister_fuseblk(void) -{ -} -#endif - static decl_subsys(fuse, NULL, NULL); static decl_subsys(connections, NULL, NULL); -static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep, +static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct inode * inode = foo; @@ -694,34 +617,24 @@ static int __init fuse_fs_init(void) err = register_filesystem(&fuse_fs_type); if (err) - goto out; - - err = register_fuseblk(); - if (err) - goto out_unreg; - - fuse_inode_cachep = kmem_cache_create("fuse_inode", - sizeof(struct fuse_inode), - 0, SLAB_HWCACHE_ALIGN, - fuse_inode_init_once, NULL); - err = -ENOMEM; - if (!fuse_inode_cachep) - goto out_unreg2; - - return 0; + printk("fuse: failed to register filesystem\n"); + else { + fuse_inode_cachep = kmem_cache_create("fuse_inode", + sizeof(struct fuse_inode), + 0, SLAB_HWCACHE_ALIGN, + fuse_inode_init_once, NULL); + if (!fuse_inode_cachep) { + unregister_filesystem(&fuse_fs_type); + err = -ENOMEM; + } + } - out_unreg2: - unregister_fuseblk(); - out_unreg: - unregister_filesystem(&fuse_fs_type); - out: return err; } static void fuse_fs_cleanup(void) { unregister_filesystem(&fuse_fs_type); - unregister_fuseblk(); kmem_cache_destroy(fuse_inode_cachep); } diff --git a/trunk/fs/gfs2/main.c b/trunk/fs/gfs2/main.c index 7c1a9e22a526..9889c1eacec1 100644 --- a/trunk/fs/gfs2/main.c +++ b/trunk/fs/gfs2/main.c @@ -25,7 +25,7 @@ #include "util.h" #include "glock.h" -static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags) +static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct gfs2_inode *ip = foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == @@ -37,7 +37,7 @@ static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned } } -static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags) +static void gfs2_init_glock_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct gfs2_glock *gl = foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == diff --git a/trunk/fs/gfs2/util.c b/trunk/fs/gfs2/util.c index e5707a9f78c2..196c604faadc 100644 --- a/trunk/fs/gfs2/util.c +++ b/trunk/fs/gfs2/util.c @@ -23,9 +23,9 @@ #include "lm.h" #include "util.h" -struct kmem_cache *gfs2_glock_cachep __read_mostly; -struct kmem_cache *gfs2_inode_cachep __read_mostly; -struct kmem_cache *gfs2_bufdata_cachep __read_mostly; +kmem_cache_t *gfs2_glock_cachep __read_mostly; +kmem_cache_t *gfs2_inode_cachep __read_mostly; +kmem_cache_t *gfs2_bufdata_cachep __read_mostly; void gfs2_assert_i(struct gfs2_sbd *sdp) { diff --git a/trunk/fs/gfs2/util.h b/trunk/fs/gfs2/util.h index 7984dcf89ad0..76a50899fe9e 100644 --- a/trunk/fs/gfs2/util.h +++ b/trunk/fs/gfs2/util.h @@ -146,9 +146,9 @@ int gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, gfs2_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); -extern struct kmem_cache *gfs2_glock_cachep; -extern struct kmem_cache *gfs2_inode_cachep; -extern struct kmem_cache *gfs2_bufdata_cachep; +extern kmem_cache_t *gfs2_glock_cachep; +extern kmem_cache_t *gfs2_inode_cachep; +extern kmem_cache_t *gfs2_bufdata_cachep; static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, unsigned int *p) diff --git a/trunk/fs/hfs/super.c b/trunk/fs/hfs/super.c index a36987966004..85b17b3fa4a0 100644 --- a/trunk/fs/hfs/super.c +++ b/trunk/fs/hfs/super.c @@ -24,7 +24,7 @@ #include "hfs_fs.h" #include "btree.h" -static struct kmem_cache *hfs_inode_cachep; +static kmem_cache_t *hfs_inode_cachep; MODULE_LICENSE("GPL"); @@ -145,7 +145,7 @@ static struct inode *hfs_alloc_inode(struct super_block *sb) { struct hfs_inode_info *i; - i = kmem_cache_alloc(hfs_inode_cachep, GFP_KERNEL); + i = kmem_cache_alloc(hfs_inode_cachep, SLAB_KERNEL); return i ? &i->vfs_inode : NULL; } @@ -430,7 +430,7 @@ static struct file_system_type hfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flags) +static void hfs_init_once(void *p, kmem_cache_t *cachep, unsigned long flags) { struct hfs_inode_info *i = p; diff --git a/trunk/fs/hfsplus/super.c b/trunk/fs/hfsplus/super.c index 0f513c6bf843..194eede52fa4 100644 --- a/trunk/fs/hfsplus/super.c +++ b/trunk/fs/hfsplus/super.c @@ -434,13 +434,13 @@ MODULE_AUTHOR("Brad Boyer"); MODULE_DESCRIPTION("Extended Macintosh Filesystem"); MODULE_LICENSE("GPL"); -static struct kmem_cache *hfsplus_inode_cachep; +static kmem_cache_t *hfsplus_inode_cachep; static struct inode *hfsplus_alloc_inode(struct super_block *sb) { struct hfsplus_inode_info *i; - i = kmem_cache_alloc(hfsplus_inode_cachep, GFP_KERNEL); + i = kmem_cache_alloc(hfsplus_inode_cachep, SLAB_KERNEL); return i ? &i->vfs_inode : NULL; } @@ -467,7 +467,7 @@ static struct file_system_type hfsplus_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long flags) +static void hfsplus_init_once(void *p, kmem_cache_t *cachep, unsigned long flags) { struct hfsplus_inode_info *i = p; diff --git a/trunk/fs/hpfs/dir.c b/trunk/fs/hpfs/dir.c index 594f9c428fc2..ecc9180645ae 100644 --- a/trunk/fs/hpfs/dir.c +++ b/trunk/fs/hpfs/dir.c @@ -84,8 +84,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) } if (!fno->dirflag) { e = 1; - hpfs_error(inode->i_sb, "not a directory, fnode %08lx", - (unsigned long)inode->i_ino); + hpfs_error(inode->i_sb, "not a directory, fnode %08x",inode->i_ino); } if (hpfs_inode->i_dno != fno->u.external[0].disk_secno) { e = 1; @@ -145,11 +144,8 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) } if (de->first || de->last) { if (hpfs_sb(inode->i_sb)->sb_chk) { - if (de->first && !de->last && (de->namelen != 2 - || de ->name[0] != 1 || de->name[1] != 1)) - hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08lx", old_pos); - if (de->last && (de->namelen != 1 || de ->name[0] != 255)) - hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08lx", old_pos); + if (de->first && !de->last && (de->namelen != 2 || de ->name[0] != 1 || de->name[1] != 1)) hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08x", old_pos); + if (de->last && (de->namelen != 1 || de ->name[0] != 255)) hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08x", old_pos); } hpfs_brelse4(&qbh); goto again; diff --git a/trunk/fs/hpfs/dnode.c b/trunk/fs/hpfs/dnode.c index fe83c2b7d2d8..229ff2fb1809 100644 --- a/trunk/fs/hpfs/dnode.c +++ b/trunk/fs/hpfs/dnode.c @@ -533,13 +533,10 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) struct buffer_head *bh; struct dnode *d1; struct quad_buffer_head qbh1; - if (hpfs_sb(i->i_sb)->sb_chk) - if (up != i->i_ino) { - hpfs_error(i->i_sb, - "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08lx", - dno, up, (unsigned long)i->i_ino); + if (hpfs_sb(i->i_sb)->sb_chk) if (up != i->i_ino) { + hpfs_error(i->i_sb, "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08x", dno, up, i->i_ino); return; - } + } if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { d1->up = up; d1->root_dnode = 1; @@ -854,9 +851,7 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp, /* Going to the next dirent */ if ((d = de_next_de(de)) < dnode_end_de(dnode)) { if (!(++*posp & 077)) { - hpfs_error(inode->i_sb, - "map_pos_dirent: pos crossed dnode boundary; pos = %08llx", - (unsigned long long)*posp); + hpfs_error(inode->i_sb, "map_pos_dirent: pos crossed dnode boundary; pos = %08x", *posp); goto bail; } /* We're going down the tree */ diff --git a/trunk/fs/hpfs/ea.c b/trunk/fs/hpfs/ea.c index 547a8384571f..66339dc030e4 100644 --- a/trunk/fs/hpfs/ea.c +++ b/trunk/fs/hpfs/ea.c @@ -243,9 +243,8 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, char *key, char *data fnode->ea_offs = 0xc4; } if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) { - hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x", - (unsigned long)inode->i_ino, - fnode->ea_offs, fnode->ea_size_s); + hpfs_error(s, "fnode %08x: ea_offs == %03x, ea_size_s == %03x", + inode->i_ino, fnode->ea_offs, fnode->ea_size_s); return; } if ((fnode->ea_size_s || !fnode->ea_size_l) && diff --git a/trunk/fs/hpfs/hpfs_fn.h b/trunk/fs/hpfs/hpfs_fn.h index 1c07aa82d327..32ab51e42b96 100644 --- a/trunk/fs/hpfs/hpfs_fn.h +++ b/trunk/fs/hpfs/hpfs_fn.h @@ -317,8 +317,7 @@ static inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb) /* super.c */ -void hpfs_error(struct super_block *, const char *, ...) - __attribute__((format (printf, 2, 3))); +void hpfs_error(struct super_block *, char *, ...); int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); unsigned hpfs_count_one_bitmap(struct super_block *, secno); diff --git a/trunk/fs/hpfs/inode.c b/trunk/fs/hpfs/inode.c index 85d3e1d9ac00..7faef8544f32 100644 --- a/trunk/fs/hpfs/inode.c +++ b/trunk/fs/hpfs/inode.c @@ -251,10 +251,7 @@ void hpfs_write_inode_nolock(struct inode *i) de->file_size = 0; hpfs_mark_4buffers_dirty(&qbh); hpfs_brelse4(&qbh); - } else - hpfs_error(i->i_sb, - "directory %08lx doesn't have '.' entry", - (unsigned long)i->i_ino); + } else hpfs_error(i->i_sb, "directory %08x doesn't have '.' entry", i->i_ino); } mark_buffer_dirty(bh); brelse(bh); diff --git a/trunk/fs/hpfs/map.c b/trunk/fs/hpfs/map.c index c4724589b2eb..0fecdac22e4e 100644 --- a/trunk/fs/hpfs/map.c +++ b/trunk/fs/hpfs/map.c @@ -126,40 +126,32 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea struct extended_attribute *ea; struct extended_attribute *ea_end; if (fnode->magic != FNODE_MAGIC) { - hpfs_error(s, "bad magic on fnode %08lx", - (unsigned long)ino); + hpfs_error(s, "bad magic on fnode %08x", ino); goto bail; } if (!fnode->dirflag) { if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != (fnode->btree.internal ? 12 : 8)) { - hpfs_error(s, - "bad number of nodes in fnode %08lx", - (unsigned long)ino); + hpfs_error(s, "bad number of nodes in fnode %08x", ino); goto bail; } if (fnode->btree.first_free != 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) { - hpfs_error(s, - "bad first_free pointer in fnode %08lx", - (unsigned long)ino); + hpfs_error(s, "bad first_free pointer in fnode %08x", ino); goto bail; } } if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 || (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) { - hpfs_error(s, - "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x", - (unsigned long)ino, - fnode->ea_offs, fnode->ea_size_s); + hpfs_error(s, "bad EA info in fnode %08x: ea_offs == %04x ea_size_s == %04x", + ino, fnode->ea_offs, fnode->ea_size_s); goto bail; } ea = fnode_ea(fnode); ea_end = fnode_end_ea(fnode); while (ea != ea_end) { if (ea > ea_end) { - hpfs_error(s, "bad EA in fnode %08lx", - (unsigned long)ino); + hpfs_error(s, "bad EA in fnode %08x", ino); goto bail; } ea = next_ea(ea); diff --git a/trunk/fs/hpfs/super.c b/trunk/fs/hpfs/super.c index d4abc1a1d566..450b5e0b4785 100644 --- a/trunk/fs/hpfs/super.c +++ b/trunk/fs/hpfs/super.c @@ -46,17 +46,21 @@ static void unmark_dirty(struct super_block *s) } /* Filesystem error... */ -static char err_buf[1024]; -void hpfs_error(struct super_block *s, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vsnprintf(err_buf, sizeof(err_buf), fmt, args); - va_end(args); +#define ERR_BUF_SIZE 1024 - printk("HPFS: filesystem error: %s", err_buf); +void hpfs_error(struct super_block *s, char *m,...) +{ + char *buf; + va_list l; + va_start(l, m); + if (!(buf = kmalloc(ERR_BUF_SIZE, GFP_KERNEL))) + printk("HPFS: No memory for error message '%s'\n",m); + else if (vsprintf(buf, m, l) >= ERR_BUF_SIZE) + printk("HPFS: Grrrr... Kernel memory corrupted ... going on, but it'll crash very soon :-(\n"); + printk("HPFS: filesystem error: "); + if (buf) printk("%s", buf); + else printk("%s\n",m); if (!hpfs_sb(s)->sb_was_error) { if (hpfs_sb(s)->sb_err == 2) { printk("; crashing the system because you wanted it\n"); @@ -72,6 +76,7 @@ void hpfs_error(struct super_block *s, const char *fmt, ...) } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n"); else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n"); } else printk("\n"); + kfree(buf); hpfs_sb(s)->sb_was_error = 1; } @@ -155,12 +160,12 @@ static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -static struct kmem_cache * hpfs_inode_cachep; +static kmem_cache_t * hpfs_inode_cachep; static struct inode *hpfs_alloc_inode(struct super_block *sb) { struct hpfs_inode_info *ei; - ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, GFP_NOFS); + ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, SLAB_NOFS); if (!ei) return NULL; ei->vfs_inode.i_version = 1; @@ -172,7 +177,7 @@ static void hpfs_destroy_inode(struct inode *inode) kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 0706f5aac6a2..7f4756963d05 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -513,7 +513,7 @@ static void hugetlbfs_inc_free_inodes(struct hugetlbfs_sb_info *sbinfo) } -static struct kmem_cache *hugetlbfs_inode_cachep; +static kmem_cache_t *hugetlbfs_inode_cachep; static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) { @@ -522,7 +522,7 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo))) return NULL; - p = kmem_cache_alloc(hugetlbfs_inode_cachep, GFP_KERNEL); + p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL); if (unlikely(!p)) { hugetlbfs_inc_free_inodes(sbinfo); return NULL; @@ -545,7 +545,7 @@ static const struct address_space_operations hugetlbfs_aops = { }; -static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 9ecccab7326d..26cdb115ce67 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -97,7 +97,7 @@ static DEFINE_MUTEX(iprune_mutex); */ struct inodes_stat_t inodes_stat; -static struct kmem_cache * inode_cachep __read_mostly; +static kmem_cache_t * inode_cachep __read_mostly; static struct inode *alloc_inode(struct super_block *sb) { @@ -109,7 +109,7 @@ static struct inode *alloc_inode(struct super_block *sb) if (sb->s_op->alloc_inode) inode = sb->s_op->alloc_inode(sb); else - inode = (struct inode *) kmem_cache_alloc(inode_cachep, GFP_KERNEL); + inode = (struct inode *) kmem_cache_alloc(inode_cachep, SLAB_KERNEL); if (inode) { struct address_space * const mapping = &inode->i_data; @@ -209,7 +209,7 @@ void inode_init_once(struct inode *inode) EXPORT_SYMBOL(inode_init_once); -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct inode * inode = (struct inode *) foo; @@ -1242,6 +1242,9 @@ EXPORT_SYMBOL(inode_needs_sync); */ #ifdef CONFIG_QUOTA +/* Function back in dquot.c */ +int remove_inode_dquot_ref(struct inode *, int, struct list_head *); + void remove_dquot_ref(struct super_block *sb, int type, struct list_head *tofree_head) { diff --git a/trunk/fs/inotify_user.c b/trunk/fs/inotify_user.c index e1956e6f116c..017cb0f134d6 100644 --- a/trunk/fs/inotify_user.c +++ b/trunk/fs/inotify_user.c @@ -34,8 +34,8 @@ #include -static struct kmem_cache *watch_cachep __read_mostly; -static struct kmem_cache *event_cachep __read_mostly; +static kmem_cache_t *watch_cachep __read_mostly; +static kmem_cache_t *event_cachep __read_mostly; static struct vfsmount *inotify_mnt __read_mostly; diff --git a/trunk/fs/isofs/inode.c b/trunk/fs/isofs/inode.c index ea55b6c469ec..c34b862cdbf2 100644 --- a/trunk/fs/isofs/inode.c +++ b/trunk/fs/isofs/inode.c @@ -57,12 +57,12 @@ static void isofs_put_super(struct super_block *sb) static void isofs_read_inode(struct inode *); static int isofs_statfs (struct dentry *, struct kstatfs *); -static struct kmem_cache *isofs_inode_cachep; +static kmem_cache_t *isofs_inode_cachep; static struct inode *isofs_alloc_inode(struct super_block *sb) { struct iso_inode_info *ei; - ei = kmem_cache_alloc(isofs_inode_cachep, GFP_KERNEL); + ei = kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -73,7 +73,7 @@ static void isofs_destroy_inode(struct inode *inode) kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); } -static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct iso_inode_info *ei = foo; diff --git a/trunk/fs/jbd/journal.c b/trunk/fs/jbd/journal.c index 10fff9443938..b85c686b60db 100644 --- a/trunk/fs/jbd/journal.c +++ b/trunk/fs/jbd/journal.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -1630,7 +1630,7 @@ void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) #define JBD_MAX_SLABS 5 #define JBD_SLAB_INDEX(size) (size >> 11) -static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; +static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; static const char *jbd_slab_names[JBD_MAX_SLABS] = { "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" }; @@ -1693,7 +1693,7 @@ void jbd_slab_free(void *ptr, size_t size) /* * Journal_head storage management */ -static struct kmem_cache *journal_head_cache; +static kmem_cache_t *journal_head_cache; #ifdef CONFIG_JBD_DEBUG static atomic_t nr_journal_heads = ATOMIC_INIT(0); #endif @@ -1996,7 +1996,7 @@ static void __exit remove_jbd_proc_entry(void) #endif -struct kmem_cache *jbd_handle_cache; +kmem_cache_t *jbd_handle_cache; static int __init journal_init_handle_cache(void) { diff --git a/trunk/fs/jbd/revoke.c b/trunk/fs/jbd/revoke.c index d204ab394f36..c532429d8d9b 100644 --- a/trunk/fs/jbd/revoke.c +++ b/trunk/fs/jbd/revoke.c @@ -70,8 +70,8 @@ #include #endif -static struct kmem_cache *revoke_record_cache; -static struct kmem_cache *revoke_table_cache; +static kmem_cache_t *revoke_record_cache; +static kmem_cache_t *revoke_table_cache; /* Each revoke record represents one single revoked block. During journal replay, this involves recording the transaction ID of the diff --git a/trunk/fs/jbd/transaction.c b/trunk/fs/jbd/transaction.c index d38e0d575e48..4f82bcd63e48 100644 --- a/trunk/fs/jbd/transaction.c +++ b/trunk/fs/jbd/transaction.c @@ -27,8 +27,6 @@ #include #include -static void __journal_temp_unlink_buffer(struct journal_head *jh); - /* * get_transaction: obtain a new transaction_t object. * @@ -1501,7 +1499,7 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh) * * Called under j_list_lock. The journal may not be locked. */ -static void __journal_temp_unlink_buffer(struct journal_head *jh) +void __journal_temp_unlink_buffer(struct journal_head *jh) { struct journal_head **list = NULL; transaction_t *transaction; diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c index 6bd8005e3d34..70b2ae1ef281 100644 --- a/trunk/fs/jbd2/commit.c +++ b/trunk/fs/jbd2/commit.c @@ -248,12 +248,8 @@ static void journal_submit_data_buffers(journal_t *journal, bufs = 0; goto write_out_data; } - } else if (!locked && buffer_locked(bh)) { - __jbd2_journal_file_buffer(jh, commit_transaction, - BJ_Locked); - jbd_unlock_bh_state(bh); - put_bh(bh); - } else { + } + else { BUFFER_TRACE(bh, "writeout complete: unfile"); __jbd2_journal_unfile_buffer(jh); jbd_unlock_bh_state(bh); diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index 44fc32bfd7f1..c60f378b0f76 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -1641,7 +1641,7 @@ void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry) #define JBD_MAX_SLABS 5 #define JBD_SLAB_INDEX(size) (size >> 11) -static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; +static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; static const char *jbd_slab_names[JBD_MAX_SLABS] = { "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k" }; @@ -1704,7 +1704,7 @@ void jbd2_slab_free(void *ptr, size_t size) /* * Journal_head storage management */ -static struct kmem_cache *jbd2_journal_head_cache; +static kmem_cache_t *jbd2_journal_head_cache; #ifdef CONFIG_JBD_DEBUG static atomic_t nr_journal_heads = ATOMIC_INIT(0); #endif @@ -2007,7 +2007,7 @@ static void __exit jbd2_remove_jbd_proc_entry(void) #endif -struct kmem_cache *jbd2_handle_cache; +kmem_cache_t *jbd2_handle_cache; static int __init journal_init_handle_cache(void) { diff --git a/trunk/fs/jbd2/revoke.c b/trunk/fs/jbd2/revoke.c index f506646ad0ff..380d19917f37 100644 --- a/trunk/fs/jbd2/revoke.c +++ b/trunk/fs/jbd2/revoke.c @@ -70,8 +70,8 @@ #include #endif -static struct kmem_cache *jbd2_revoke_record_cache; -static struct kmem_cache *jbd2_revoke_table_cache; +static kmem_cache_t *jbd2_revoke_record_cache; +static kmem_cache_t *jbd2_revoke_table_cache; /* Each revoke record represents one single revoked block. During journal replay, this involves recording the transaction ID of the diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c index 3a8700153cb0..c051a94c8a97 100644 --- a/trunk/fs/jbd2/transaction.c +++ b/trunk/fs/jbd2/transaction.c @@ -27,8 +27,6 @@ #include #include -static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); - /* * jbd2_get_transaction: obtain a new transaction_t object. * diff --git a/trunk/fs/jffs/inode-v23.c b/trunk/fs/jffs/inode-v23.c index 9f15bce92022..3f7899ea4cba 100644 --- a/trunk/fs/jffs/inode-v23.c +++ b/trunk/fs/jffs/inode-v23.c @@ -61,8 +61,8 @@ static const struct file_operations jffs_dir_operations; static struct inode_operations jffs_dir_inode_operations; static const struct address_space_operations jffs_address_operations; -struct kmem_cache *node_cache = NULL; -struct kmem_cache *fm_cache = NULL; +kmem_cache_t *node_cache = NULL; +kmem_cache_t *fm_cache = NULL; /* Called by the VFS at mount time to initialize the whole file system. */ static int jffs_fill_super(struct super_block *sb, void *data, int silent) diff --git a/trunk/fs/jffs/intrep.c b/trunk/fs/jffs/intrep.c index d0e783f199ea..4a543e114970 100644 --- a/trunk/fs/jffs/intrep.c +++ b/trunk/fs/jffs/intrep.c @@ -66,7 +66,6 @@ #include #include #include -#include #include "intrep.h" #include "jffs_fm.h" @@ -592,7 +591,7 @@ jffs_add_virtual_root(struct jffs_control *c) D2(printk("jffs_add_virtual_root(): " "Creating a virtual root directory.\n")); - if (!(root = kzalloc(sizeof(struct jffs_file), GFP_KERNEL))) { + if (!(root = kmalloc(sizeof(struct jffs_file), GFP_KERNEL))) { return -ENOMEM; } no_jffs_file++; @@ -604,6 +603,7 @@ jffs_add_virtual_root(struct jffs_control *c) DJM(no_jffs_node++); memset(node, 0, sizeof(struct jffs_node)); node->ino = JFFS_MIN_INO; + memset(root, 0, sizeof(struct jffs_file)); root->ino = JFFS_MIN_INO; root->mode = S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; diff --git a/trunk/fs/jffs/jffs_fm.c b/trunk/fs/jffs/jffs_fm.c index 077258b2103e..29b68d939bd9 100644 --- a/trunk/fs/jffs/jffs_fm.c +++ b/trunk/fs/jffs/jffs_fm.c @@ -29,8 +29,8 @@ static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset); static struct jffs_fm *jffs_alloc_fm(void); static void jffs_free_fm(struct jffs_fm *n); -extern struct kmem_cache *fm_cache; -extern struct kmem_cache *node_cache; +extern kmem_cache_t *fm_cache; +extern kmem_cache_t *node_cache; #if CONFIG_JFFS_FS_VERBOSE > 0 void diff --git a/trunk/fs/jffs2/background.c b/trunk/fs/jffs2/background.c index 6eb3daebd563..ff2a872e80e7 100644 --- a/trunk/fs/jffs2/background.c +++ b/trunk/fs/jffs2/background.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "nodelist.h" diff --git a/trunk/fs/jffs2/malloc.c b/trunk/fs/jffs2/malloc.c index 83f9881ec4cc..33f291005012 100644 --- a/trunk/fs/jffs2/malloc.c +++ b/trunk/fs/jffs2/malloc.c @@ -19,16 +19,16 @@ /* These are initialised to NULL in the kernel startup code. If you're porting to other operating systems, beware */ -static struct kmem_cache *full_dnode_slab; -static struct kmem_cache *raw_dirent_slab; -static struct kmem_cache *raw_inode_slab; -static struct kmem_cache *tmp_dnode_info_slab; -static struct kmem_cache *raw_node_ref_slab; -static struct kmem_cache *node_frag_slab; -static struct kmem_cache *inode_cache_slab; +static kmem_cache_t *full_dnode_slab; +static kmem_cache_t *raw_dirent_slab; +static kmem_cache_t *raw_inode_slab; +static kmem_cache_t *tmp_dnode_info_slab; +static kmem_cache_t *raw_node_ref_slab; +static kmem_cache_t *node_frag_slab; +static kmem_cache_t *inode_cache_slab; #ifdef CONFIG_JFFS2_FS_XATTR -static struct kmem_cache *xattr_datum_cache; -static struct kmem_cache *xattr_ref_cache; +static kmem_cache_t *xattr_datum_cache; +static kmem_cache_t *xattr_ref_cache; #endif int __init jffs2_create_slab_caches(void) diff --git a/trunk/fs/jffs2/super.c b/trunk/fs/jffs2/super.c index 7deb78254021..bc4b8106a490 100644 --- a/trunk/fs/jffs2/super.c +++ b/trunk/fs/jffs2/super.c @@ -28,12 +28,12 @@ static void jffs2_put_super(struct super_block *); -static struct kmem_cache *jffs2_inode_cachep; +static kmem_cache_t *jffs2_inode_cachep; static struct inode *jffs2_alloc_inode(struct super_block *sb) { struct jffs2_inode_info *ei; - ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); + ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -44,7 +44,7 @@ static void jffs2_destroy_inode(struct inode *inode) kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); } -static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; diff --git a/trunk/fs/jfs/jfs_logmgr.c b/trunk/fs/jfs/jfs_logmgr.c index 5065baa530b6..b89c9aba0466 100644 --- a/trunk/fs/jfs/jfs_logmgr.c +++ b/trunk/fs/jfs/jfs_logmgr.c @@ -67,7 +67,7 @@ #include #include /* for sync_blockdev() */ #include -#include +#include #include #include #include "jfs_incore.h" diff --git a/trunk/fs/jfs/jfs_metapage.c b/trunk/fs/jfs/jfs_metapage.c index b1a1c7296014..0cccd1c39d75 100644 --- a/trunk/fs/jfs/jfs_metapage.c +++ b/trunk/fs/jfs/jfs_metapage.c @@ -74,7 +74,7 @@ static inline void lock_metapage(struct metapage *mp) } #define METAPOOL_MIN_PAGES 32 -static struct kmem_cache *metapage_cache; +static kmem_cache_t *metapage_cache; static mempool_t *metapage_mempool; #define MPS_PER_PAGE (PAGE_CACHE_SIZE >> L2PSIZE) @@ -180,7 +180,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp) #endif -static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct metapage *mp = (struct metapage *)foo; diff --git a/trunk/fs/jfs/jfs_txnmgr.c b/trunk/fs/jfs/jfs_txnmgr.c index d558e51b0df8..81f6f04af192 100644 --- a/trunk/fs/jfs/jfs_txnmgr.c +++ b/trunk/fs/jfs/jfs_txnmgr.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/fs/jfs/super.c b/trunk/fs/jfs/super.c index 846ac8f34513..9c1c6e0e633d 100644 --- a/trunk/fs/jfs/super.c +++ b/trunk/fs/jfs/super.c @@ -44,7 +44,7 @@ MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); MODULE_LICENSE("GPL"); -static struct kmem_cache * jfs_inode_cachep; +static kmem_cache_t * jfs_inode_cachep; static struct super_operations jfs_super_operations; static struct export_operations jfs_export_operations; @@ -93,7 +93,7 @@ void jfs_error(struct super_block *sb, const char * function, ...) va_list args; va_start(args, function); - vsnprintf(error_buf, sizeof(error_buf), function, args); + vsprintf(error_buf, function, args); va_end(args); printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf); @@ -748,7 +748,7 @@ static struct file_system_type jfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; diff --git a/trunk/fs/lockd/clntproc.c b/trunk/fs/lockd/clntproc.c index 50643b6a5556..3d84f600b633 100644 --- a/trunk/fs/lockd/clntproc.c +++ b/trunk/fs/lockd/clntproc.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/lockd/host.c b/trunk/fs/lockd/host.c index 3d4610c2a266..fb24a9730345 100644 --- a/trunk/fs/lockd/host.c +++ b/trunk/fs/lockd/host.c @@ -36,14 +36,34 @@ static DEFINE_MUTEX(nlm_host_mutex); static void nlm_gc_hosts(void); static struct nsm_handle * __nsm_find(const struct sockaddr_in *, const char *, int, int); -static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, - const char *hostname, - int hostname_len); + +/* + * Find an NLM server handle in the cache. If there is none, create it. + */ +struct nlm_host * +nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, + const char *hostname, int hostname_len) +{ + return nlm_lookup_host(0, sin, proto, version, + hostname, hostname_len); +} + +/* + * Find an NLM client handle in the cache. If there is none, create it. + */ +struct nlm_host * +nlmsvc_lookup_host(struct svc_rqst *rqstp, + const char *hostname, int hostname_len) +{ + return nlm_lookup_host(1, &rqstp->rq_addr, + rqstp->rq_prot, rqstp->rq_vers, + hostname, hostname_len); +} /* * Common host lookup routine for server & client */ -static struct nlm_host * +struct nlm_host * nlm_lookup_host(int server, const struct sockaddr_in *sin, int proto, int version, const char *hostname, @@ -174,29 +194,6 @@ nlm_destroy_host(struct nlm_host *host) kfree(host); } -/* - * Find an NLM server handle in the cache. If there is none, create it. - */ -struct nlm_host * -nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, - const char *hostname, int hostname_len) -{ - return nlm_lookup_host(0, sin, proto, version, - hostname, hostname_len); -} - -/* - * Find an NLM client handle in the cache. If there is none, create it. - */ -struct nlm_host * -nlmsvc_lookup_host(struct svc_rqst *rqstp, - const char *hostname, int hostname_len) -{ - return nlm_lookup_host(1, &rqstp->rq_addr, - rqstp->rq_prot, rqstp->rq_vers, - hostname, hostname_len); -} - /* * Create the NLM RPC client for an NLM peer */ @@ -498,7 +495,7 @@ __nsm_find(const struct sockaddr_in *sin, return nsm; } -static struct nsm_handle * +struct nsm_handle * nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len) { return __nsm_find(sin, hostname, hostname_len, 1); diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 1cb0c57fedbd..e0b6a80649a0 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -142,12 +142,12 @@ int lease_break_time = 45; static LIST_HEAD(file_lock_list); static LIST_HEAD(blocked_list); -static struct kmem_cache *filelock_cache __read_mostly; +static kmem_cache_t *filelock_cache __read_mostly; /* Allocate an empty lock structure. */ static struct file_lock *locks_alloc_lock(void) { - return kmem_cache_alloc(filelock_cache, GFP_KERNEL); + return kmem_cache_alloc(filelock_cache, SLAB_KERNEL); } static void locks_release_private(struct file_lock *fl) @@ -199,7 +199,7 @@ EXPORT_SYMBOL(locks_init_lock); * Initialises the fields of the file lock which are invariant for * free file_locks. */ -static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags) +static void init_once(void *foo, kmem_cache_t *cache, unsigned long flags) { struct file_lock *lock = (struct file_lock *) foo; diff --git a/trunk/fs/mbcache.c b/trunk/fs/mbcache.c index deeb9dc062d9..0ff71256e65b 100644 --- a/trunk/fs/mbcache.c +++ b/trunk/fs/mbcache.c @@ -85,7 +85,7 @@ struct mb_cache { #ifndef MB_CACHE_INDEXES_COUNT int c_indexes_count; #endif - struct kmem_cache *c_entry_cache; + kmem_cache_t *c_entry_cache; struct list_head *c_block_hash; struct list_head *c_indexes_hash[0]; }; diff --git a/trunk/fs/minix/inode.c b/trunk/fs/minix/inode.c index 629e09b38c5c..1e36bae4d0eb 100644 --- a/trunk/fs/minix/inode.c +++ b/trunk/fs/minix/inode.c @@ -51,12 +51,12 @@ static void minix_put_super(struct super_block *sb) return; } -static struct kmem_cache * minix_inode_cachep; +static kmem_cache_t * minix_inode_cachep; static struct inode *minix_alloc_inode(struct super_block *sb) { struct minix_inode_info *ei; - ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL); + ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -67,7 +67,7 @@ static void minix_destroy_inode(struct inode *inode) kmem_cache_free(minix_inode_cachep, minix_i(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct minix_inode_info *ei = (struct minix_inode_info *) foo; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index db1bca26d88c..28d49b301d55 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -249,11 +249,9 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) /* * MAY_EXEC on regular files requires special handling: We override - * filesystem execute permissions if the mode bits aren't set or - * the fs is mounted with the "noexec" flag. + * filesystem execute permissions if the mode bits aren't set. */ - if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) || - (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC)))) + if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO)) return -EACCES; /* Ordinary permission routines do not understand MAY_APPEND. */ @@ -1998,7 +1996,8 @@ asmlinkage long sys_mkdir(const char __user *pathname, int mode) void dentry_unhash(struct dentry *dentry) { dget(dentry); - shrink_dcache_parent(dentry); + if (atomic_read(&dentry->d_count)) + shrink_dcache_parent(dentry); spin_lock(&dcache_lock); spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) == 2) diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index b00ac84ebbdd..55442a6cf221 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -36,7 +36,7 @@ static int event; static struct list_head *mount_hashtable __read_mostly; static int hash_mask __read_mostly, hash_bits __read_mostly; -static struct kmem_cache *mnt_cache __read_mostly; +static kmem_cache_t *mnt_cache __read_mostly; static struct rw_semaphore namespace_sem; /* /sys/fs */ diff --git a/trunk/fs/ncpfs/inode.c b/trunk/fs/ncpfs/inode.c index fae53243bb92..72dad552aa00 100644 --- a/trunk/fs/ncpfs/inode.c +++ b/trunk/fs/ncpfs/inode.c @@ -40,12 +40,12 @@ static void ncp_delete_inode(struct inode *); static void ncp_put_super(struct super_block *); static int ncp_statfs(struct dentry *, struct kstatfs *); -static struct kmem_cache * ncp_inode_cachep; +static kmem_cache_t * ncp_inode_cachep; static struct inode *ncp_alloc_inode(struct super_block *sb) { struct ncp_inode_info *ei; - ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL); + ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -56,7 +56,7 @@ static void ncp_destroy_inode(struct inode *inode) kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; diff --git a/trunk/fs/nfs/direct.c b/trunk/fs/nfs/direct.c index 2f488e1d9b6c..bdfabf854a51 100644 --- a/trunk/fs/nfs/direct.c +++ b/trunk/fs/nfs/direct.c @@ -58,7 +58,7 @@ #define NFSDBG_FACILITY NFSDBG_VFS -static struct kmem_cache *nfs_direct_cachep; +static kmem_cache_t *nfs_direct_cachep; /* * This represents a set of asynchronous requests that we're waiting on @@ -143,7 +143,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) { struct nfs_direct_req *dreq; - dreq = kmem_cache_alloc(nfs_direct_cachep, GFP_KERNEL); + dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL); if (!dreq) return NULL; diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 15afa460e629..08cc4c5919ab 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -55,7 +55,7 @@ static int nfs_update_inode(struct inode *, struct nfs_fattr *); static void nfs_zap_acl_cache(struct inode *); -static struct kmem_cache * nfs_inode_cachep; +static kmem_cache_t * nfs_inode_cachep; static inline unsigned long nfs_fattr_to_ino_t(struct nfs_fattr *fattr) @@ -1080,7 +1080,7 @@ void nfs4_clear_inode(struct inode *inode) struct inode *nfs_alloc_inode(struct super_block *sb) { struct nfs_inode *nfsi; - nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL); + nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); if (!nfsi) return NULL; nfsi->flags = 0UL; @@ -1111,7 +1111,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) #endif } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct nfs_inode *nfsi = (struct nfs_inode *) foo; diff --git a/trunk/fs/nfs/pagelist.c b/trunk/fs/nfs/pagelist.c index 3fbfc2f03307..829af323f288 100644 --- a/trunk/fs/nfs/pagelist.c +++ b/trunk/fs/nfs/pagelist.c @@ -20,13 +20,13 @@ #define NFS_PARANOIA 1 -static struct kmem_cache *nfs_page_cachep; +static kmem_cache_t *nfs_page_cachep; static inline struct nfs_page * nfs_page_alloc(void) { struct nfs_page *p; - p = kmem_cache_alloc(nfs_page_cachep, GFP_KERNEL); + p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL); if (p) { memset(p, 0, sizeof(*p)); INIT_LIST_HEAD(&p->wb_list); diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index 244a8c45b68e..c2e49c397a27 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -38,7 +38,7 @@ static int nfs_pagein_one(struct list_head *, struct inode *); static const struct rpc_call_ops nfs_read_partial_ops; static const struct rpc_call_ops nfs_read_full_ops; -static struct kmem_cache *nfs_rdata_cachep; +static kmem_cache_t *nfs_rdata_cachep; static mempool_t *nfs_rdata_mempool; #define MIN_POOL_READ (32) @@ -46,7 +46,7 @@ static mempool_t *nfs_rdata_mempool; struct nfs_read_data *nfs_readdata_alloc(size_t len) { unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; - struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_NOFS); + struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS); if (p) { memset(p, 0, sizeof(*p)); diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index 41b07288f99e..883dd4a1c157 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -85,7 +85,7 @@ static const struct rpc_call_ops nfs_write_partial_ops; static const struct rpc_call_ops nfs_write_full_ops; static const struct rpc_call_ops nfs_commit_ops; -static struct kmem_cache *nfs_wdata_cachep; +static kmem_cache_t *nfs_wdata_cachep; static mempool_t *nfs_wdata_mempool; static mempool_t *nfs_commit_mempool; @@ -93,7 +93,7 @@ static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); struct nfs_write_data *nfs_commit_alloc(void) { - struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); + struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS); if (p) { memset(p, 0, sizeof(*p)); @@ -112,7 +112,7 @@ void nfs_commit_free(struct nfs_write_data *p) struct nfs_write_data *nfs_writedata_alloc(size_t len) { unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; - struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); + struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS); if (p) { memset(p, 0, sizeof(*p)); diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index 277df40f098d..b4baca3053c3 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -24,6 +24,10 @@ #define NFSDDBG_FACILITY NFSDDBG_XDR +#ifdef NFSD_OPTIMIZE_SPACE +# define inline +#endif + /* * Mapping of S_IF* types to NFS file types @@ -38,14 +42,14 @@ static u32 nfs3_ftypes[] = { /* * XDR functions for basic NFS types */ -static __be32 * +static inline __be32 * encode_time3(__be32 *p, struct timespec *time) { *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); return p; } -static __be32 * +static inline __be32 * decode_time3(__be32 *p, struct timespec *time) { time->tv_sec = ntohl(*p++); @@ -53,7 +57,7 @@ decode_time3(__be32 *p, struct timespec *time) return p; } -static __be32 * +static inline __be32 * decode_fh(__be32 *p, struct svc_fh *fhp) { unsigned int size; @@ -73,7 +77,7 @@ __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp) return decode_fh(p, fhp); } -static __be32 * +static inline __be32 * encode_fh(__be32 *p, struct svc_fh *fhp) { unsigned int size = fhp->fh_handle.fh_size; @@ -87,7 +91,7 @@ encode_fh(__be32 *p, struct svc_fh *fhp) * Decode a file name and make sure that the path contains * no slashes or null bytes. */ -static __be32 * +static inline __be32 * decode_filename(__be32 *p, char **namp, int *lenp) { char *name; @@ -103,7 +107,7 @@ decode_filename(__be32 *p, char **namp, int *lenp) return p; } -static __be32 * +static inline __be32 * decode_sattr3(__be32 *p, struct iattr *iap) { u32 tmp; @@ -149,7 +153,7 @@ decode_sattr3(__be32 *p, struct iattr *iap) return p; } -static __be32 * +static inline __be32 * encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat) { @@ -182,7 +186,7 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, return p; } -static __be32 * +static inline __be32 * encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) { struct inode *inode = fhp->fh_dentry->d_inode; @@ -772,7 +776,7 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, return xdr_ressize_check(rqstp, p); } -static __be32 * +static inline __be32 * encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen, ino_t ino) { @@ -786,7 +790,7 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, return p; } -static __be32 * +static inline __be32 * encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, struct svc_fh *fhp) { diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 640c92b2a9f7..e431e93ab503 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -84,10 +84,10 @@ static void nfs4_set_recdir(char *recdir); */ static DEFINE_MUTEX(client_mutex); -static struct kmem_cache *stateowner_slab = NULL; -static struct kmem_cache *file_slab = NULL; -static struct kmem_cache *stateid_slab = NULL; -static struct kmem_cache *deleg_slab = NULL; +static kmem_cache_t *stateowner_slab = NULL; +static kmem_cache_t *file_slab = NULL; +static kmem_cache_t *stateid_slab = NULL; +static kmem_cache_t *deleg_slab = NULL; void nfs4_lock_state(void) @@ -1003,7 +1003,7 @@ alloc_init_file(struct inode *ino) } static void -nfsd4_free_slab(struct kmem_cache **slab) +nfsd4_free_slab(kmem_cache_t **slab) { if (*slab == NULL) return; diff --git a/trunk/fs/nfsd/nfsxdr.c b/trunk/fs/nfsd/nfsxdr.c index f5243f943996..56ebb1443e0e 100644 --- a/trunk/fs/nfsd/nfsxdr.c +++ b/trunk/fs/nfsd/nfsxdr.c @@ -18,6 +18,11 @@ #define NFSDDBG_FACILITY NFSDDBG_XDR + +#ifdef NFSD_OPTIMIZE_SPACE +# define inline +#endif + /* * Mapping of S_IF* types to NFS file types */ @@ -50,7 +55,7 @@ __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp) return decode_fh(p, fhp); } -static __be32 * +static inline __be32 * encode_fh(__be32 *p, struct svc_fh *fhp) { memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); @@ -61,7 +66,7 @@ encode_fh(__be32 *p, struct svc_fh *fhp) * Decode a file name and make sure that the path contains * no slashes or null bytes. */ -static __be32 * +static inline __be32 * decode_filename(__be32 *p, char **namp, int *lenp) { char *name; @@ -77,7 +82,7 @@ decode_filename(__be32 *p, char **namp, int *lenp) return p; } -static __be32 * +static inline __be32 * decode_pathname(__be32 *p, char **namp, int *lenp) { char *name; @@ -93,7 +98,7 @@ decode_pathname(__be32 *p, char **namp, int *lenp) return p; } -static __be32 * +static inline __be32 * decode_sattr(__be32 *p, struct iattr *iap) { u32 tmp, tmp1; diff --git a/trunk/fs/nls/nls_cp936.c b/trunk/fs/nls/nls_cp936.c index 65e640c61c8b..046fde8170ea 100644 --- a/trunk/fs/nls/nls_cp936.c +++ b/trunk/fs/nls/nls_cp936.c @@ -4421,73 +4421,6 @@ static wchar_t *page_charset2uni[256] = { c2u_F8, c2u_F9, c2u_FA, c2u_FB, c2u_FC, c2u_FD, c2u_FE, NULL, }; -static unsigned char u2c_00[512] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0C-0x0F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x13 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x14-0x17 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1C-0x1F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x23 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x24-0x27 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x33 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x34-0x37 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3C-0x3F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x43 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x44-0x47 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4C-0x4F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x53 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x54-0x57 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5C-0x5F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x63 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x64-0x67 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6C-0x6F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x73 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x74-0x77 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7C-0x7F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x83 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x84-0x87 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8C-0x8F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x93 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x94-0x97 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9B */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA0-0xA3 */ - 0xA1, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xEC, /* 0xA4-0xA7 */ - 0xA1, 0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA8-0xAB */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xAC-0xAF */ - 0xA1, 0xE3, 0xA1, 0xC0, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA4, /* 0xB4-0xB7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB8-0xBB */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xBC-0xBF */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC0-0xC3 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC4-0xC7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xCC-0xCF */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD0-0xD3 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xC1, /* 0xD4-0xD7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */ - 0xA8, 0xA4, 0xA8, 0xA2, 0x00, 0x00, 0x00, 0x00, /* 0xE0-0xE3 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */ - 0xA8, 0xA8, 0xA8, 0xA6, 0xA8, 0xBA, 0x00, 0x00, /* 0xE8-0xEB */ - 0xA8, 0xAC, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, /* 0xEC-0xEF */ - 0x00, 0x00, 0x00, 0x00, 0xA8, 0xB0, 0xA8, 0xAE, /* 0xF0-0xF3 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xC2, /* 0xF4-0xF7 */ - 0x00, 0x00, 0xA8, 0xB4, 0xA8, 0xB2, 0x00, 0x00, /* 0xF8-0xFB */ - 0xA8, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */ -}; - static unsigned char u2c_01[512] = { 0xA8, 0xA1, 0xA8, 0xA1, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ @@ -10892,7 +10825,7 @@ static unsigned char u2c_FF[512] = { }; static unsigned char *page_uni2charset[256] = { - u2c_00, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL, + NULL, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -11003,34 +10936,11 @@ static int uni2char(const wchar_t uni, unsigned char *uni2charset; unsigned char cl = uni&0xFF; unsigned char ch = (uni>>8)&0xFF; - unsigned char out0,out1; + int n; if (boundlen <= 0) return -ENAMETOOLONG; - if (uni == 0x20ac) {/* Euro symbol.The only exception with a non-ascii unicode */ - out[0] = 0x80; - return 1; - } - - if (ch == 0) { /* handle the U00 plane*/ - /* if (cl == 0) return -EINVAL;*/ /*U0000 is legal in cp936*/ - out0 = u2c_00[cl*2]; - out1 = u2c_00[cl*2+1]; - if (out0 == 0x00 && out1 == 0x00) { - if (cl<0x80) { - out[0] = cl; - return 1; - } - return -EINVAL; - } else { - if (boundlen <= 1) - return -ENAMETOOLONG; - out[0] = out0; - out[1] = out1; - return 2; - } - } uni2charset = page_uni2charset[ch]; if (uni2charset) { @@ -11040,10 +10950,15 @@ static int uni2char(const wchar_t uni, out[1] = uni2charset[cl*2+1]; if (out[0] == 0x00 && out[1] == 0x00) return -EINVAL; - return 2; + n = 2; + } else if (ch==0 && cl) { + out[0] = cl; + n = 1; } else return -EINVAL; + + return n; } static int char2uni(const unsigned char *rawstring, int boundlen, @@ -11057,11 +10972,7 @@ static int char2uni(const unsigned char *rawstring, int boundlen, return -ENAMETOOLONG; if (boundlen == 1) { - if (rawstring[0]==0x80) { /* Euro symbol.The only exception with a non-ascii unicode */ - *uni = 0x20ac; - } else { - *uni = rawstring[0]; - } + *uni = rawstring[0]; return 1; } @@ -11075,11 +10986,7 @@ static int char2uni(const unsigned char *rawstring, int boundlen, return -EINVAL; n = 2; } else{ - if (ch==0x80) {/* Euro symbol.The only exception with a non-ascii unicode */ - *uni = 0x20ac; - } else { - *uni = ch; - } + *uni = ch; n = 1; } return n; diff --git a/trunk/fs/ntfs/attrib.c b/trunk/fs/ntfs/attrib.c index c577d8e1bd95..9f08e851cfb6 100644 --- a/trunk/fs/ntfs/attrib.c +++ b/trunk/fs/ntfs/attrib.c @@ -1272,7 +1272,7 @@ ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec) { ntfs_attr_search_ctx *ctx; - ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, GFP_NOFS); + ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, SLAB_NOFS); if (ctx) ntfs_attr_init_search_ctx(ctx, ni, mrec); return ctx; diff --git a/trunk/fs/ntfs/index.c b/trunk/fs/ntfs/index.c index 2194eff49743..e32cde486362 100644 --- a/trunk/fs/ntfs/index.c +++ b/trunk/fs/ntfs/index.c @@ -38,7 +38,7 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni) { ntfs_index_context *ictx; - ictx = kmem_cache_alloc(ntfs_index_ctx_cache, GFP_NOFS); + ictx = kmem_cache_alloc(ntfs_index_ctx_cache, SLAB_NOFS); if (ictx) *ictx = (ntfs_index_context){ .idx_ni = idx_ni }; return ictx; diff --git a/trunk/fs/ntfs/inode.c b/trunk/fs/ntfs/inode.c index 247989891b4b..2d3de9c89818 100644 --- a/trunk/fs/ntfs/inode.c +++ b/trunk/fs/ntfs/inode.c @@ -324,7 +324,7 @@ struct inode *ntfs_alloc_big_inode(struct super_block *sb) ntfs_inode *ni; ntfs_debug("Entering."); - ni = kmem_cache_alloc(ntfs_big_inode_cache, GFP_NOFS); + ni = kmem_cache_alloc(ntfs_big_inode_cache, SLAB_NOFS); if (likely(ni != NULL)) { ni->state = 0; return VFS_I(ni); @@ -349,7 +349,7 @@ static inline ntfs_inode *ntfs_alloc_extent_inode(void) ntfs_inode *ni; ntfs_debug("Entering."); - ni = kmem_cache_alloc(ntfs_inode_cache, GFP_NOFS); + ni = kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS); if (likely(ni != NULL)) { ni->state = 0; return ni; diff --git a/trunk/fs/ntfs/unistr.c b/trunk/fs/ntfs/unistr.c index 005ca4b0f132..6a495f7369f9 100644 --- a/trunk/fs/ntfs/unistr.c +++ b/trunk/fs/ntfs/unistr.c @@ -266,7 +266,7 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins, /* We do not trust outside sources. */ if (likely(ins)) { - ucs = kmem_cache_alloc(ntfs_name_cache, GFP_NOFS); + ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); if (likely(ucs)) { for (i = o = 0; i < ins_len; i += wc_len) { wc_len = nls->char2uni(ins + i, ins_len - i, diff --git a/trunk/fs/ocfs2/dlm/dlmfs.c b/trunk/fs/ocfs2/dlm/dlmfs.c index 941acf14e61f..16b8d1ba7066 100644 --- a/trunk/fs/ocfs2/dlm/dlmfs.c +++ b/trunk/fs/ocfs2/dlm/dlmfs.c @@ -66,7 +66,7 @@ static struct file_operations dlmfs_file_operations; static struct inode_operations dlmfs_dir_inode_operations; static struct inode_operations dlmfs_root_inode_operations; static struct inode_operations dlmfs_file_inode_operations; -static struct kmem_cache *dlmfs_inode_cache; +static kmem_cache_t *dlmfs_inode_cache; struct workqueue_struct *user_dlm_worker; @@ -257,7 +257,7 @@ static ssize_t dlmfs_file_write(struct file *filp, } static void dlmfs_init_once(void *foo, - struct kmem_cache *cachep, + kmem_cache_t *cachep, unsigned long flags) { struct dlmfs_inode_private *ip = @@ -276,7 +276,7 @@ static struct inode *dlmfs_alloc_inode(struct super_block *sb) { struct dlmfs_inode_private *ip; - ip = kmem_cache_alloc(dlmfs_inode_cache, GFP_NOFS); + ip = kmem_cache_alloc(dlmfs_inode_cache, SLAB_NOFS); if (!ip) return NULL; diff --git a/trunk/fs/ocfs2/dlm/dlmmaster.c b/trunk/fs/ocfs2/dlm/dlmmaster.c index 856012b4fa49..f784177b6241 100644 --- a/trunk/fs/ocfs2/dlm/dlmmaster.c +++ b/trunk/fs/ocfs2/dlm/dlmmaster.c @@ -221,7 +221,7 @@ EXPORT_SYMBOL_GPL(dlm_dump_all_mles); #endif /* 0 */ -static struct kmem_cache *dlm_mle_cache = NULL; +static kmem_cache_t *dlm_mle_cache = NULL; static void dlm_mle_release(struct kref *kref); diff --git a/trunk/fs/ocfs2/extent_map.c b/trunk/fs/ocfs2/extent_map.c index 80ac69f11d9f..fcd4475d1f89 100644 --- a/trunk/fs/ocfs2/extent_map.c +++ b/trunk/fs/ocfs2/extent_map.c @@ -61,7 +61,7 @@ struct ocfs2_em_insert_context { struct ocfs2_extent_map_entry *right_ent; }; -static struct kmem_cache *ocfs2_em_ent_cachep = NULL; +static kmem_cache_t *ocfs2_em_ent_cachep = NULL; static struct ocfs2_extent_map_entry * diff --git a/trunk/fs/ocfs2/inode.h b/trunk/fs/ocfs2/inode.h index 1a7dd2945b34..46a378fbc40b 100644 --- a/trunk/fs/ocfs2/inode.h +++ b/trunk/fs/ocfs2/inode.h @@ -106,7 +106,7 @@ static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) #define INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags & OCFS2_INODE_JOURNAL) #define SET_INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags |= OCFS2_INODE_JOURNAL) -extern struct kmem_cache *ocfs2_inode_cache; +extern kmem_cache_t *ocfs2_inode_cache; extern const struct address_space_operations ocfs2_aops; diff --git a/trunk/fs/ocfs2/super.c b/trunk/fs/ocfs2/super.c index 4bf39540e652..d9b4214a12da 100644 --- a/trunk/fs/ocfs2/super.c +++ b/trunk/fs/ocfs2/super.c @@ -68,7 +68,7 @@ #include "buffer_head_io.h" -static struct kmem_cache *ocfs2_inode_cachep = NULL; +static kmem_cache_t *ocfs2_inode_cachep = NULL; /* OCFS2 needs to schedule several differnt types of work which * require cluster locking, disk I/O, recovery waits, etc. Since these @@ -303,7 +303,7 @@ static struct inode *ocfs2_alloc_inode(struct super_block *sb) { struct ocfs2_inode_info *oi; - oi = kmem_cache_alloc(ocfs2_inode_cachep, GFP_NOFS); + oi = kmem_cache_alloc(ocfs2_inode_cachep, SLAB_NOFS); if (!oi) return NULL; @@ -914,7 +914,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) } static void ocfs2_inode_init_once(void *data, - struct kmem_cache *cachep, + kmem_cache_t *cachep, unsigned long flags) { struct ocfs2_inode_info *oi = data; @@ -1674,7 +1674,7 @@ void __ocfs2_error(struct super_block *sb, va_list args; va_start(args, fmt); - vsnprintf(error_buf, sizeof(error_buf), fmt, args); + vsprintf(error_buf, fmt, args); va_end(args); /* Not using mlog here because we want to show the actual @@ -1695,7 +1695,7 @@ void __ocfs2_abort(struct super_block* sb, va_list args; va_start(args, fmt); - vsnprintf(error_buf, sizeof(error_buf), fmt, args); + vsprintf(error_buf, fmt, args); va_end(args); printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n", diff --git a/trunk/fs/ocfs2/uptodate.c b/trunk/fs/ocfs2/uptodate.c index 39814b900fc0..9707ed7a3206 100644 --- a/trunk/fs/ocfs2/uptodate.c +++ b/trunk/fs/ocfs2/uptodate.c @@ -69,7 +69,7 @@ struct ocfs2_meta_cache_item { sector_t c_block; }; -static struct kmem_cache *ocfs2_uptodate_cachep = NULL; +static kmem_cache_t *ocfs2_uptodate_cachep = NULL; void ocfs2_metadata_cache_init(struct inode *inode) { diff --git a/trunk/fs/openpromfs/inode.c b/trunk/fs/openpromfs/inode.c index 26f44e0074ec..592a6402e851 100644 --- a/trunk/fs/openpromfs/inode.c +++ b/trunk/fs/openpromfs/inode.c @@ -330,13 +330,13 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld return 0; } -static struct kmem_cache *op_inode_cachep; +static kmem_cache_t *op_inode_cachep; static struct inode *openprom_alloc_inode(struct super_block *sb) { struct op_inode_info *oi; - oi = kmem_cache_alloc(op_inode_cachep, GFP_KERNEL); + oi = kmem_cache_alloc(op_inode_cachep, SLAB_KERNEL); if (!oi) return NULL; @@ -415,7 +415,7 @@ static struct file_system_type openprom_fs_type = { .kill_sb = kill_anon_super, }; -static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned long flags) +static void op_inode_init_once(void *data, kmem_cache_t * cachep, unsigned long flags) { struct op_inode_info *oi = (struct op_inode_info *) data; diff --git a/trunk/fs/partitions/amiga.c b/trunk/fs/partitions/amiga.c index 9917a8c360f2..3068528890a6 100644 --- a/trunk/fs/partitions/amiga.c +++ b/trunk/fs/partitions/amiga.c @@ -43,7 +43,6 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) if (warn_no_part) printk("Dev %s: unable to read RDB block %d\n", bdevname(bdev, b), blk); - res = -1; goto rdb_done; } if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) @@ -80,7 +79,6 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) if (warn_no_part) printk("Dev %s: unable to read partition block %d\n", bdevname(bdev, b), blk); - res = -1; goto rdb_done; } pb = (struct PartitionBlock *)data; diff --git a/trunk/fs/partitions/atari.c b/trunk/fs/partitions/atari.c index 1f3572d5b755..192a6adfdefd 100644 --- a/trunk/fs/partitions/atari.c +++ b/trunk/fs/partitions/atari.c @@ -88,7 +88,7 @@ int atari_partition(struct parsed_partitions *state, struct block_device *bdev) if (!xrs) { printk (" block %ld read failed\n", partsect); put_dev_sector(sect); - return -1; + return 0; } /* ++roman: sanity check: bit 0 of flg field must be set */ diff --git a/trunk/fs/partitions/check.c b/trunk/fs/partitions/check.c index 1901137f4eca..6fb4b6150d77 100644 --- a/trunk/fs/partitions/check.c +++ b/trunk/fs/partitions/check.c @@ -153,7 +153,7 @@ static struct parsed_partitions * check_partition(struct gendisk *hd, struct block_device *bdev) { struct parsed_partitions *state; - int i, res, err; + int i, res; state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); if (!state) @@ -165,30 +165,19 @@ check_partition(struct gendisk *hd, struct block_device *bdev) sprintf(state->name, "p"); state->limit = hd->minors; - i = res = err = 0; + i = res = 0; while (!res && check_part[i]) { memset(&state->parts, 0, sizeof(state->parts)); res = check_part[i++](state, bdev); - if (res < 0) { - /* We have hit an I/O error which we don't report now. - * But record it, and let the others do their job. - */ - err = res; - res = 0; - } - } if (res > 0) return state; - if (!err) - /* The partition is unrecognized. So report I/O errors if there were any */ - res = err; if (!res) printk(" unknown partition table\n"); else if (warn_no_part) printk(" unable to read partition table\n"); kfree(state); - return ERR_PTR(res); + return NULL; } /* @@ -505,8 +494,6 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) disk->fops->revalidate_disk(disk); if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) return 0; - if (IS_ERR(state)) /* I/O error reading the partition table */ - return PTR_ERR(state); for (p = 1; p < state->limit; p++) { sector_t size = state->parts[p].size; sector_t from = state->parts[p].from; diff --git a/trunk/fs/partitions/ibm.c b/trunk/fs/partitions/ibm.c index 9f7ad4244f63..d352a7381fed 100644 --- a/trunk/fs/partitions/ibm.c +++ b/trunk/fs/partitions/ibm.c @@ -43,7 +43,7 @@ cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { int ibm_partition(struct parsed_partitions *state, struct block_device *bdev) { - int blocksize, offset, size,res; + int blocksize, offset, size; loff_t i_size; dasd_information_t *info; struct hd_geometry *geo; @@ -56,16 +56,15 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) unsigned char *data; Sector sect; - res = 0; blocksize = bdev_hardsect_size(bdev); if (blocksize <= 0) - goto out_exit; + return 0; i_size = i_size_read(bdev->bd_inode); if (i_size == 0) - goto out_exit; + return 0; if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) - goto out_exit; + goto out_noinfo; if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) goto out_nogeo; if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) @@ -73,7 +72,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) - goto out_freeall; + goto out_noioctl; /* * Get volume label, extract name and type. @@ -93,8 +92,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) EBCASC(type, 4); EBCASC(name, 6); - res = 1; - /* * Three different types: CMS1, VOL1 and LNX1/unlabeled */ @@ -159,9 +156,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) counter++; blk++; } - if (!data) - /* Are we not supposed to report this ? */ - goto out_readerr; } else { /* * Old style LNX1 or unlabeled disk @@ -177,17 +171,18 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) } printk("\n"); - goto out_freeall; - + kfree(label); + kfree(geo); + kfree(info); + return 1; out_readerr: - res = -1; -out_freeall: +out_noioctl: kfree(label); out_nolab: kfree(geo); out_nogeo: kfree(info); -out_exit: - return res; +out_noinfo: + return 0; } diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index ae36b89b1a37..b1626f269a34 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -830,14 +830,7 @@ void free_pipe_info(struct inode *inode) static struct vfsmount *pipe_mnt __read_mostly; static int pipefs_delete_dentry(struct dentry *dentry) { - /* - * At creation time, we pretended this dentry was hashed - * (by clearing DCACHE_UNHASHED bit in d_flags) - * At delete time, we restore the truth : not hashed. - * (so that dput() can proceed correctly) - */ - dentry->d_flags |= DCACHE_UNHASHED; - return 0; + return 1; } static struct dentry_operations pipefs_dentry_operations = { @@ -898,22 +891,17 @@ struct file *create_write_pipe(void) if (!inode) goto err_file; - this.len = sprintf(name, "[%lu]", inode->i_ino); + sprintf(name, "[%lu]", inode->i_ino); this.name = name; - this.hash = 0; + this.len = strlen(name); + this.hash = inode->i_ino; /* will go */ err = -ENOMEM; dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); if (!dentry) goto err_inode; dentry->d_op = &pipefs_dentry_operations; - /* - * We dont want to publish this dentry into global dentry hash table. - * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED - * This permits a working /proc/$pid/fd/XXX on pipes - */ - dentry->d_flags &= ~DCACHE_UNHASHED; - d_instantiate(dentry, inode); + d_add(dentry, inode); f->f_vfsmnt = mntget(pipe_mnt); f->f_dentry = dentry; f->f_mapping = inode->i_mapping; diff --git a/trunk/fs/proc/Makefile b/trunk/fs/proc/Makefile index f6c776272572..7431d7ba2d09 100644 --- a/trunk/fs/proc/Makefile +++ b/trunk/fs/proc/Makefile @@ -8,9 +8,8 @@ proc-y := nommu.o task_nommu.o proc-$(CONFIG_MMU) := mmu.o task_mmu.o proc-y += inode.o root.o base.o generic.o array.o \ - proc_tty.o proc_misc.o + kmsg.o proc_tty.o proc_misc.o proc-$(CONFIG_PROC_KCORE) += kcore.o proc-$(CONFIG_PROC_VMCORE) += vmcore.o proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o -proc-$(CONFIG_PRINTK) += kmsg.o diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index b859fc749c07..795319c54f72 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -683,6 +683,8 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, char buffer[PROC_NUMBUF], *end; int oom_adjust; + if (!capable(CAP_SYS_RESOURCE)) + return -EPERM; memset(buffer, 0, sizeof(buffer)); if (count > sizeof(buffer) - 1) count = sizeof(buffer) - 1; @@ -697,10 +699,6 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, task = get_proc_task(file->f_dentry->d_inode); if (!task) return -ESRCH; - if (oom_adjust < task->oomkilladj && !capable(CAP_SYS_RESOURCE)) { - put_task_struct(task); - return -EACCES; - } task->oomkilladj = oom_adjust; put_task_struct(task); if (end - buffer == 0) @@ -1885,9 +1883,8 @@ void proc_flush_task(struct task_struct *task) return; } -static struct dentry *proc_pid_instantiate(struct inode *dir, - struct dentry * dentry, - struct task_struct *task, void *ptr) +struct dentry *proc_pid_instantiate(struct inode *dir, + struct dentry * dentry, struct task_struct *task, void *ptr) { struct dentry *error = ERR_PTR(-ENOENT); struct inode *inode; diff --git a/trunk/fs/proc/inode.c b/trunk/fs/proc/inode.c index e26945ba685b..49dfb2ab783e 100644 --- a/trunk/fs/proc/inode.c +++ b/trunk/fs/proc/inode.c @@ -81,14 +81,14 @@ static void proc_read_inode(struct inode * inode) inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; } -static struct kmem_cache * proc_inode_cachep; +static kmem_cache_t * proc_inode_cachep; static struct inode *proc_alloc_inode(struct super_block *sb) { struct proc_inode *ei; struct inode *inode; - ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL); + ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; ei->pid = NULL; @@ -105,7 +105,7 @@ static void proc_destroy_inode(struct inode *inode) kmem_cache_free(proc_inode_cachep, PROC_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct proc_inode *ei = (struct proc_inode *) foo; diff --git a/trunk/fs/proc/kcore.c b/trunk/fs/proc/kcore.c index 1be73082edd3..1294eda4acae 100644 --- a/trunk/fs/proc/kcore.c +++ b/trunk/fs/proc/kcore.c @@ -22,7 +22,6 @@ #include #include -#define CORE_STR "CORE" static int open_kcore(struct inode * inode, struct file * filp) { @@ -83,11 +82,10 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) } *elf_buflen = sizeof(struct elfhdr) + (*nphdr + 2)*sizeof(struct elf_phdr) + - 3 * ((sizeof(struct elf_note)) + - roundup(sizeof(CORE_STR), 4)) + - roundup(sizeof(struct elf_prstatus), 4) + - roundup(sizeof(struct elf_prpsinfo), 4) + - roundup(sizeof(struct task_struct), 4); + 3 * (sizeof(struct elf_note) + 4) + + sizeof(struct elf_prstatus) + + sizeof(struct elf_prpsinfo) + + sizeof(struct task_struct); *elf_buflen = PAGE_ALIGN(*elf_buflen); return size + *elf_buflen; } @@ -212,7 +210,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) nhdr->p_offset = offset; /* set up the process status */ - notes[0].name = CORE_STR; + notes[0].name = "CORE"; notes[0].type = NT_PRSTATUS; notes[0].datasz = sizeof(struct elf_prstatus); notes[0].data = &prstatus; @@ -223,7 +221,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) bufp = storenote(¬es[0], bufp); /* set up the process info */ - notes[1].name = CORE_STR; + notes[1].name = "CORE"; notes[1].type = NT_PRPSINFO; notes[1].datasz = sizeof(struct elf_prpsinfo); notes[1].data = &prpsinfo; @@ -240,7 +238,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) bufp = storenote(¬es[1], bufp); /* set up the task structure */ - notes[2].name = CORE_STR; + notes[2].name = "CORE"; notes[2].type = NT_TASKSTRUCT; notes[2].datasz = sizeof(struct task_struct); notes[2].data = current; diff --git a/trunk/fs/proc/proc_misc.c b/trunk/fs/proc/proc_misc.c index 51815cece6f3..93c43b676e59 100644 --- a/trunk/fs/proc/proc_misc.c +++ b/trunk/fs/proc/proc_misc.c @@ -696,11 +696,9 @@ void __init proc_misc_init(void) proc_symlink("mounts", NULL, "self/mounts"); /* And now for trickier ones */ -#ifdef CONFIG_PRINTK entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); if (entry) entry->proc_fops = &proc_kmsg_operations; -#endif create_seq_entry("devices", 0, &proc_devinfo_operations); create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); #ifdef CONFIG_BLOCK diff --git a/trunk/fs/qnx4/inode.c b/trunk/fs/qnx4/inode.c index c047dc654d5c..5a41db2a218d 100644 --- a/trunk/fs/qnx4/inode.c +++ b/trunk/fs/qnx4/inode.c @@ -515,12 +515,12 @@ static void qnx4_read_inode(struct inode *inode) brelse(bh); } -static struct kmem_cache *qnx4_inode_cachep; +static kmem_cache_t *qnx4_inode_cachep; static struct inode *qnx4_alloc_inode(struct super_block *sb) { struct qnx4_inode_info *ei; - ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL); + ei = kmem_cache_alloc(qnx4_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -531,7 +531,7 @@ static void qnx4_destroy_inode(struct inode *inode) kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); } -static void init_once(void *foo, struct kmem_cache * cachep, +static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; diff --git a/trunk/fs/reiserfs/file.c b/trunk/fs/reiserfs/file.c index 373d862c3f87..ac14318c81ba 100644 --- a/trunk/fs/reiserfs/file.c +++ b/trunk/fs/reiserfs/file.c @@ -317,11 +317,12 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl /* area filled with zeroes, to supply as list of zero blocknumbers We allocate it outside of loop just in case loop would spin for several iterations. */ - char *zeros = kzalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. + char *zeros = kmalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. if (!zeros) { res = -ENOMEM; goto error_exit_free_blocks; } + memset(zeros, 0, to_paste * UNFM_P_SIZE); do { to_paste = min_t(__u64, hole_size, @@ -406,8 +407,6 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl we restart it. This will also free the path. */ if (journal_transaction_should_end (th, th->t_blocks_allocated)) { - inode->i_size = cpu_key_k_offset(&key) + - (to_paste << inode->i_blkbits); res = restart_transaction(th, inode, &path); @@ -1046,7 +1045,6 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); memset(kaddr, 0, from); kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(prepared_pages[0]); } if (to != PAGE_CACHE_SIZE) { /* Last page needs to be partially zeroed */ char *kaddr = @@ -1054,7 +1052,6 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode KM_USER0); memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(prepared_pages[num_pages - 1]); } /* Since all blocks are new - use already calculated value */ @@ -1188,7 +1185,6 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode memset(kaddr + block_start, 0, from - block_start); kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(prepared_pages[0]); set_buffer_uptodate(bh); } } @@ -1226,7 +1222,6 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode KM_USER0); memset(kaddr + to, 0, block_end - to); kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(prepared_pages[num_pages - 1]); set_buffer_uptodate(bh); } } @@ -1312,8 +1307,56 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t count = MAX_NON_LFS - (unsigned long)*ppos; } - if (file->f_flags & O_DIRECT) - return do_sync_write(file, buf, count, ppos); + if (file->f_flags & O_DIRECT) { // Direct IO needs treatment + ssize_t result, after_file_end = 0; + if ((*ppos + count >= inode->i_size) + || (file->f_flags & O_APPEND)) { + /* If we are appending a file, we need to put this savelink in here. + If we will crash while doing direct io, finish_unfinished will + cut the garbage from the file end. */ + reiserfs_write_lock(inode->i_sb); + err = + journal_begin(&th, inode->i_sb, + JOURNAL_PER_BALANCE_CNT); + if (err) { + reiserfs_write_unlock(inode->i_sb); + return err; + } + reiserfs_update_inode_transaction(inode); + add_save_link(&th, inode, 1 /* Truncate */ ); + after_file_end = 1; + err = + journal_end(&th, inode->i_sb, + JOURNAL_PER_BALANCE_CNT); + reiserfs_write_unlock(inode->i_sb); + if (err) + return err; + } + result = do_sync_write(file, buf, count, ppos); + + if (after_file_end) { /* Now update i_size and remove the savelink */ + struct reiserfs_transaction_handle th; + reiserfs_write_lock(inode->i_sb); + err = journal_begin(&th, inode->i_sb, 1); + if (err) { + reiserfs_write_unlock(inode->i_sb); + return err; + } + reiserfs_update_inode_transaction(inode); + mark_inode_dirty(inode); + err = journal_end(&th, inode->i_sb, 1); + if (err) { + reiserfs_write_unlock(inode->i_sb); + return err; + } + err = remove_save_link(inode, 1 /* truncate */ ); + reiserfs_write_unlock(inode->i_sb); + if (err) + return err; + } + + return result; + } if (unlikely((ssize_t) count < 0)) return -EINVAL; diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c index 254239e6f9e3..9c69bcacad22 100644 --- a/trunk/fs/reiserfs/inode.c +++ b/trunk/fs/reiserfs/inode.c @@ -216,12 +216,11 @@ static int file_capable(struct inode *inode, long block) BUG_ON(!th->t_trans_id); BUG_ON(!th->t_refcount); - pathrelse(path); - /* we cannot restart while nested */ if (th->t_refcount > 1) { return 0; } + pathrelse(path); reiserfs_update_sd(th, inode); err = journal_end(th, s, len); if (!err) { @@ -929,12 +928,15 @@ int reiserfs_get_block(struct inode *inode, sector_t block, if (blocks_needed == 1) { un = &unf_single; } else { - un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. + un = kmalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. if (!un) { un = &unf_single; blocks_needed = 1; max_to_insert = 0; - } + } else + memset(un, 0, + UNFM_P_SIZE * min(blocks_needed, + max_to_insert)); } if (blocks_needed <= max_to_insert) { /* we are going to add target block to the file. Use allocated diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 7fb5fb036f90..17249994110f 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -490,13 +490,13 @@ static void reiserfs_put_super(struct super_block *s) return; } -static struct kmem_cache *reiserfs_inode_cachep; +static kmem_cache_t *reiserfs_inode_cachep; static struct inode *reiserfs_alloc_inode(struct super_block *sb) { struct reiserfs_inode_info *ei; ei = (struct reiserfs_inode_info *) - kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL); + kmem_cache_alloc(reiserfs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -507,7 +507,7 @@ static void reiserfs_destroy_inode(struct inode *inode) kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); } -static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; @@ -1549,12 +1549,13 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) struct reiserfs_sb_info *sbi; int errval = -EINVAL; - sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); + sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); if (!sbi) { errval = -ENOMEM; goto error; } s->s_fs_info = sbi; + memset(sbi, 0, sizeof(struct reiserfs_sb_info)); /* Set default values for options: non-aggressive tails, RO on errors */ REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO); diff --git a/trunk/fs/romfs/inode.c b/trunk/fs/romfs/inode.c index c5af088d4a4c..ddcd9e1ef282 100644 --- a/trunk/fs/romfs/inode.c +++ b/trunk/fs/romfs/inode.c @@ -550,12 +550,12 @@ romfs_read_inode(struct inode *i) } } -static struct kmem_cache * romfs_inode_cachep; +static kmem_cache_t * romfs_inode_cachep; static struct inode *romfs_alloc_inode(struct super_block *sb) { struct romfs_inode_info *ei; - ei = (struct romfs_inode_info *)kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL); + ei = (struct romfs_inode_info *)kmem_cache_alloc(romfs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -566,7 +566,7 @@ static void romfs_destroy_inode(struct inode *inode) kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index 10690aa401c7..555b9ac04c25 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -26,7 +26,7 @@ * ERR_PTR(error). In the end of sequence they return %NULL. ->show() * returns 0 in case of success and negative number in case of error. */ -int seq_open(struct file *file, const struct seq_operations *op) +int seq_open(struct file *file, struct seq_operations *op) { struct seq_file *p = file->private_data; @@ -408,7 +408,7 @@ EXPORT_SYMBOL(single_open); int single_release(struct inode *inode, struct file *file) { - const struct seq_operations *op = ((struct seq_file *)file->private_data)->op; + struct seq_operations *op = ((struct seq_file *)file->private_data)->op; int res = seq_release(inode, file); kfree(op); return res; diff --git a/trunk/fs/smbfs/inode.c b/trunk/fs/smbfs/inode.c index 4af4cd729a5a..2c122ee83adb 100644 --- a/trunk/fs/smbfs/inode.c +++ b/trunk/fs/smbfs/inode.c @@ -50,12 +50,12 @@ static void smb_put_super(struct super_block *); static int smb_statfs(struct dentry *, struct kstatfs *); static int smb_show_options(struct seq_file *, struct vfsmount *); -static struct kmem_cache *smb_inode_cachep; +static kmem_cache_t *smb_inode_cachep; static struct inode *smb_alloc_inode(struct super_block *sb) { struct smb_inode_info *ei; - ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, GFP_KERNEL); + ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -66,7 +66,7 @@ static void smb_destroy_inode(struct inode *inode) kmem_cache_free(smb_inode_cachep, SMB_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct smb_inode_info *ei = (struct smb_inode_info *) foo; unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; diff --git a/trunk/fs/smbfs/request.c b/trunk/fs/smbfs/request.c index a4bcae8a9aff..0fb74697abc4 100644 --- a/trunk/fs/smbfs/request.c +++ b/trunk/fs/smbfs/request.c @@ -25,7 +25,7 @@ #define ROUND_UP(x) (((x)+3) & ~3) /* cache for request structures */ -static struct kmem_cache *req_cachep; +static kmem_cache_t *req_cachep; static int smb_request_send_req(struct smb_request *req); @@ -61,7 +61,7 @@ static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server, struct smb_request *req; unsigned char *buf = NULL; - req = kmem_cache_alloc(req_cachep, GFP_KERNEL); + req = kmem_cache_alloc(req_cachep, SLAB_KERNEL); VERBOSE("allocating request: %p\n", req); if (!req) goto out; diff --git a/trunk/fs/stat.c b/trunk/fs/stat.c index a0ebfc7f8a64..bca07eb2003c 100644 --- a/trunk/fs/stat.c +++ b/trunk/fs/stat.c @@ -51,6 +51,13 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) return inode->i_op->getattr(mnt, dentry, stat); generic_fillattr(inode, stat); + if (!stat->blksize) { + struct super_block *s = inode->i_sb; + unsigned blocks; + blocks = (stat->size+s->s_blocksize-1) >> s->s_blocksize_bits; + stat->blocks = (s->s_blocksize / 512) * blocks; + stat->blksize = s->s_blocksize; + } return 0; } diff --git a/trunk/fs/sysfs/mount.c b/trunk/fs/sysfs/mount.c index e503f858fba8..20551a1b8a56 100644 --- a/trunk/fs/sysfs/mount.c +++ b/trunk/fs/sysfs/mount.c @@ -16,7 +16,7 @@ struct vfsmount *sysfs_mount; struct super_block * sysfs_sb = NULL; -struct kmem_cache *sysfs_dir_cachep; +kmem_cache_t *sysfs_dir_cachep; static struct super_operations sysfs_ops = { .statfs = simple_statfs, diff --git a/trunk/fs/sysfs/sysfs.h b/trunk/fs/sysfs/sysfs.h index bd7cec295dab..6f3d6bd52887 100644 --- a/trunk/fs/sysfs/sysfs.h +++ b/trunk/fs/sysfs/sysfs.h @@ -1,6 +1,6 @@ extern struct vfsmount * sysfs_mount; -extern struct kmem_cache *sysfs_dir_cachep; +extern kmem_cache_t *sysfs_dir_cachep; extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); diff --git a/trunk/fs/sysv/CHANGES b/trunk/fs/sysv/CHANGES new file mode 100644 index 000000000000..66ea6e92be66 --- /dev/null +++ b/trunk/fs/sysv/CHANGES @@ -0,0 +1,60 @@ +Mon, 15 Dec 1997 Krzysztof G. Baranowski + * namei.c: struct sysv_dir_inode_operations updated to use dentries. + +Fri, 23 Jan 1998 Krzysztof G. Baranowski + * inode.c: corrected 1 track offset setting (in sb->sv_block_base). + Originally it was overridden (by setting to zero) + in detected_[xenix,sysv4,sysv2,coherent]. Thanks + to Andrzej Krzysztofowicz + for identifying the problem. + +Tue, 27 Jan 1998 Krzysztof G. Baranowski + * inode.c: added 2048-byte block support to SystemV FS. + Merged detected_bs[512,1024,2048]() into one function: + void detected_bs (u_char type, struct super_block *sb). + Thanks to Andrzej Krzysztofowicz + for the patch. + +Wed, 4 Feb 1998 Krzysztof G. Baranowski + * namei.c: removed static subdir(); is_subdir() from dcache.c + is used instead. Cosmetic changes. + +Thu, 3 Dec 1998 Al Viro (viro@parcelfarce.linux.theplanet.co.uk) + * namei.c (sysv_rmdir): + Bugectomy: old check for victim being busy + (inode->i_count) wasn't replaced (with checking + dentry->d_count) and escaped Linus in the last round + of changes. Shot and buried. + +Wed, 9 Dec 1998 AV + * namei.c (do_sysv_rename): + Fixed incorrect check for other owners + race. + Removed checks that went to VFS. + * namei.c (sysv_unlink): + Removed checks that went to VFS. + +Thu, 10 Dec 1998 AV + * namei.c (do_mknod): + Removed dead code - mknod is never asked to + create a symlink or directory. Incidentially, + it wouldn't do it right if it would be called. + +Sat, 26 Dec 1998 KGB + * inode.c (detect_sysv4): + Added detection of expanded s_type field (0x10, + 0x20 and 0x30). Forced read-only access in this case. + +Sun, 21 Mar 1999 AV + * namei.c (sysv_link): + Fixed i_count usage that resulted in dcache corruption. + * inode.c: + Filled ->delete_inode() method with sysv_delete_inode(). + sysv_put_inode() is gone, as it tried to do ->delete_ + _inode()'s job. + * ialloc.c: (sysv_free_inode): + Fixed race. + +Sun, 30 Apr 1999 AV + * namei.c (sysv_mknod): + Removed dead code (S_IFREG case is now passed to + ->create() by VFS). diff --git a/trunk/fs/sysv/ChangeLog b/trunk/fs/sysv/ChangeLog new file mode 100644 index 000000000000..f403f8b91b80 --- /dev/null +++ b/trunk/fs/sysv/ChangeLog @@ -0,0 +1,106 @@ +Thu Feb 14 2002 Andrew Morton + + * dir_commit_chunk(): call writeout_one_page() as well as + waitfor_one_page() for IS_SYNC directories, so that we + actually do sync the directory. (forward-port from 2.4). + +Thu Feb 7 2002 Alexander Viro + + * super.c: switched to ->get_sb() + * ChangeLog: fixed dates ;-) + +2002-01-24 David S. Miller + + * inode.c: Include linux/init.h + +Mon Jan 21 2002 Alexander Viro + * ialloc.c (sysv_new_inode): zero SYSV_I(inode)->i_data out. + * i_vnode renamed to vfs_inode. Sorry, but let's keep that + consistent. + +Sat Jan 19 2002 Christoph Hellwig + + * include/linux/sysv_fs.h (SYSV_I): Get fs-private inode data using + list_entry() instead of inode->u. + * include/linux/sysv_fs_i.h: Add 'struct inode i_vnode' field to + sysv_inode_info structure. + * inode.c: Include , implement alloc_inode/destroy_inode + sop methods, add infrastructure for per-fs inode slab cache. + * super.c (init_sysv_fs): Initialize inode cache, recover properly + in the case of failed register_filesystem for V7. + (exit_sysv_fs): Destroy inode cache. + +Sat Jan 19 2002 Christoph Hellwig + + * include/linux/sysv_fs.h: Include , declare SYSV_I(). + * dir.c (sysv_find_entry): Use SYSV_I() instead of ->u.sysv_i to + access fs-private inode data. + * ialloc.c (sysv_new_inode): Likewise. + * inode.c (sysv_read_inode): Likewise. + (sysv_update_inode): Likewise. + * itree.c (get_branch): Likewise. + (sysv_truncate): Likewise. + * symlink.c (sysv_readlink): Likewise. + (sysv_follow_link): Likewise. + +Fri Jan 4 2002 Alexander Viro + + * ialloc.c (sysv_free_inode): Use sb->s_id instead of bdevname(). + * inode.c (sysv_read_inode): Likewise. + (sysv_update_inode): Likewise. + (sysv_sync_inode): Likewise. + * super.c (detect_sysv): Likewise. + (complete_read_super): Likewise. + (sysv_read_super): Likewise. + (v7_read_super): Likewise. + +Sun Dec 30 2001 Manfred Spraul + + * dir.c (dir_commit_chunk): Do not set dir->i_version. + (sysv_readdir): Likewise. + +Thu Dec 27 2001 Alexander Viro + + * itree.c (get_block): Use map_bh() to fill out bh_result. + +Tue Dec 25 2001 Alexander Viro + + * super.c (sysv_read_super): Use sb_set_blocksize() to set blocksize. + (v7_read_super): Likewise. + +Tue Nov 27 2001 Alexander Viro + + * itree.c (get_block): Change type for iblock argument to sector_t. + * super.c (sysv_read_super): Set s_blocksize early. + (v7_read_super): Likewise. + * balloc.c (sysv_new_block): Use sb_bread(). instead of bread(). + (sysv_count_free_blocks): Likewise. + * ialloc.c (sysv_raw_inode): Likewise. + * itree.c (get_branch): Likewise. + (free_branches): Likewise. + * super.c (sysv_read_super): Likewise. + (v7_read_super): Likewise. + +Sat Dec 15 2001 Christoph Hellwig + + * inode.c (sysv_read_inode): Mark inode as bad in case of failure. + * super.c (complete_read_super): Check for bad root inode. + +Wed Nov 21 2001 Andrew Morton + + * file.c (sysv_sync_file): Call fsync_inode_data_buffers. + +Fri Oct 26 2001 Christoph Hellwig + + * dir.c, ialloc.c, namei.c, include/linux/sysv_fs_i.h: + Implement per-Inode lookup offset cache. + Modelled after Ted's ext2 patch. + +Fri Oct 26 2001 Christoph Hellwig + + * inode.c, super.c, include/linux/sysv_fs.h, + include/linux/sysv_fs_sb.h: + Remove symlink faking. Noone really wants to use these as + linux filesystems and native OSes don't support it anyway. + + diff --git a/trunk/fs/sysv/INTRO b/trunk/fs/sysv/INTRO new file mode 100644 index 000000000000..de4e4d17cac6 --- /dev/null +++ b/trunk/fs/sysv/INTRO @@ -0,0 +1,182 @@ +This is the implementation of the SystemV/Coherent filesystem for Linux. +It grew out of separate filesystem implementations + + Xenix FS Doug Evans June 1992 + SystemV FS Paul B. Monday March-June 1993 + Coherent FS B. Haible June 1993 + +and was merged together in July 1993. + +These filesystems are rather similar. Here is a comparison with Minix FS: + +* Linux fdisk reports on partitions + - Minix FS 0x81 Linux/Minix + - Xenix FS ?? + - SystemV FS ?? + - Coherent FS 0x08 AIX bootable + +* Size of a block or zone (data allocation unit on disk) + - Minix FS 1024 + - Xenix FS 1024 (also 512 ??) + - SystemV FS 1024 (also 512 and 2048) + - Coherent FS 512 + +* General layout: all have one boot block, one super block and + separate areas for inodes and for directories/data. + On SystemV Release 2 FS (e.g. Microport) the first track is reserved and + all the block numbers (including the super block) are offset by one track. + +* Byte ordering of "short" (16 bit entities) on disk: + - Minix FS little endian 0 1 + - Xenix FS little endian 0 1 + - SystemV FS little endian 0 1 + - Coherent FS little endian 0 1 + Of course, this affects only the file system, not the data of files on it! + +* Byte ordering of "long" (32 bit entities) on disk: + - Minix FS little endian 0 1 2 3 + - Xenix FS little endian 0 1 2 3 + - SystemV FS little endian 0 1 2 3 + - Coherent FS PDP-11 2 3 0 1 + Of course, this affects only the file system, not the data of files on it! + +* Inode on disk: "short", 0 means non-existent, the root dir ino is: + - Minix FS 1 + - Xenix FS, SystemV FS, Coherent FS 2 + +* Maximum number of hard links to a file: + - Minix FS 250 + - Xenix FS ?? + - SystemV FS ?? + - Coherent FS >=10000 + +* Free inode management: + - Minix FS a bitmap + - Xenix FS, SystemV FS, Coherent FS + There is a cache of a certain number of free inodes in the super-block. + When it is exhausted, new free inodes are found using a linear search. + +* Free block management: + - Minix FS a bitmap + - Xenix FS, SystemV FS, Coherent FS + Free blocks are organized in a "free list". Maybe a misleading term, + since it is not true that every free block contains a pointer to + the next free block. Rather, the free blocks are organized in chunks + of limited size, and every now and then a free block contains pointers + to the free blocks pertaining to the next chunk; the first of these + contains pointers and so on. The list terminates with a "block number" + 0 on Xenix FS and SystemV FS, with a block zeroed out on Coherent FS. + +* Super-block location: + - Minix FS block 1 = bytes 1024..2047 + - Xenix FS block 1 = bytes 1024..2047 + - SystemV FS bytes 512..1023 + - Coherent FS block 1 = bytes 512..1023 + +* Super-block layout: + - Minix FS + unsigned short s_ninodes; + unsigned short s_nzones; + unsigned short s_imap_blocks; + unsigned short s_zmap_blocks; + unsigned short s_firstdatazone; + unsigned short s_log_zone_size; + unsigned long s_max_size; + unsigned short s_magic; + - Xenix FS, SystemV FS, Coherent FS + unsigned short s_firstdatazone; + unsigned long s_nzones; + unsigned short s_fzone_count; + unsigned long s_fzones[NICFREE]; + unsigned short s_finode_count; + unsigned short s_finodes[NICINOD]; + char s_flock; + char s_ilock; + char s_modified; + char s_rdonly; + unsigned long s_time; + short s_dinfo[4]; -- SystemV FS only + unsigned long s_free_zones; + unsigned short s_free_inodes; + short s_dinfo[4]; -- Xenix FS only + unsigned short s_interleave_m,s_interleave_n; -- Coherent FS only + char s_fname[6]; + char s_fpack[6]; + then they differ considerably: + Xenix FS + char s_clean; + char s_fill[371]; + long s_magic; + long s_type; + SystemV FS + long s_fill[12 or 14]; + long s_state; + long s_magic; + long s_type; + Coherent FS + unsigned long s_unique; + Note that Coherent FS has no magic. + +* Inode layout: + - Minix FS + unsigned short i_mode; + unsigned short i_uid; + unsigned long i_size; + unsigned long i_time; + unsigned char i_gid; + unsigned char i_nlinks; + unsigned short i_zone[7+1+1]; + - Xenix FS, SystemV FS, Coherent FS + unsigned short i_mode; + unsigned short i_nlink; + unsigned short i_uid; + unsigned short i_gid; + unsigned long i_size; + unsigned char i_zone[3*(10+1+1+1)]; + unsigned long i_atime; + unsigned long i_mtime; + unsigned long i_ctime; + +* Regular file data blocks are organized as + - Minix FS + 7 direct blocks + 1 indirect block (pointers to blocks) + 1 double-indirect block (pointer to pointers to blocks) + - Xenix FS, SystemV FS, Coherent FS + 10 direct blocks + 1 indirect block (pointers to blocks) + 1 double-indirect block (pointer to pointers to blocks) + 1 triple-indirect block (pointer to pointers to pointers to blocks) + +* Inode size, inodes per block + - Minix FS 32 32 + - Xenix FS 64 16 + - SystemV FS 64 16 + - Coherent FS 64 8 + +* Directory entry on disk + - Minix FS + unsigned short inode; + char name[14/30]; + - Xenix FS, SystemV FS, Coherent FS + unsigned short inode; + char name[14]; + +* Dir entry size, dir entries per block + - Minix FS 16/32 64/32 + - Xenix FS 16 64 + - SystemV FS 16 64 + - Coherent FS 16 32 + +* How to implement symbolic links such that the host fsck doesn't scream: + - Minix FS normal + - Xenix FS kludge: as regular files with chmod 1000 + - SystemV FS ?? + - Coherent FS kludge: as regular files with chmod 1000 + + +Notation: We often speak of a "block" but mean a zone (the allocation unit) +and not the disk driver's notion of "block". + + +Bruno Haible diff --git a/trunk/fs/sysv/inode.c b/trunk/fs/sysv/inode.c index ead9864567e3..d63c5e48b050 100644 --- a/trunk/fs/sysv/inode.c +++ b/trunk/fs/sysv/inode.c @@ -301,13 +301,13 @@ static void sysv_delete_inode(struct inode *inode) unlock_kernel(); } -static struct kmem_cache *sysv_inode_cachep; +static kmem_cache_t *sysv_inode_cachep; static struct inode *sysv_alloc_inode(struct super_block *sb) { struct sysv_inode_info *si; - si = kmem_cache_alloc(sysv_inode_cachep, GFP_KERNEL); + si = kmem_cache_alloc(sysv_inode_cachep, SLAB_KERNEL); if (!si) return NULL; return &si->vfs_inode; @@ -318,7 +318,7 @@ static void sysv_destroy_inode(struct inode *inode) kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); } -static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags) +static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags) { struct sysv_inode_info *si = (struct sysv_inode_info *)p; diff --git a/trunk/fs/udf/super.c b/trunk/fs/udf/super.c index 1dbc2955f02e..1aea6a4f9a4a 100644 --- a/trunk/fs/udf/super.c +++ b/trunk/fs/udf/super.c @@ -107,12 +107,12 @@ static struct file_system_type udf_fstype = { .fs_flags = FS_REQUIRES_DEV, }; -static struct kmem_cache * udf_inode_cachep; +static kmem_cache_t * udf_inode_cachep; static struct inode *udf_alloc_inode(struct super_block *sb) { struct udf_inode_info *ei; - ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL); + ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; @@ -130,7 +130,7 @@ static void udf_destroy_inode(struct inode *inode) kmem_cache_free(udf_inode_cachep, UDF_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct udf_inode_info *ei = (struct udf_inode_info *) foo; @@ -1709,7 +1709,7 @@ void udf_error(struct super_block *sb, const char *function, sb->s_dirt = 1; } va_start(args, fmt); - vsnprintf(error_buf, sizeof(error_buf), fmt, args); + vsprintf(error_buf, fmt, args); va_end(args); printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n", sb->s_id, function, error_buf); @@ -1721,7 +1721,7 @@ void udf_warning(struct super_block *sb, const char *function, va_list args; va_start (args, fmt); - vsnprintf(error_buf, sizeof(error_buf), fmt, args); + vsprintf(error_buf, fmt, args); va_end(args); printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n", sb->s_id, function, error_buf); diff --git a/trunk/fs/ufs/super.c b/trunk/fs/ufs/super.c index 8a8e9382ec09..ec79e3091d1b 100644 --- a/trunk/fs/ufs/super.c +++ b/trunk/fs/ufs/super.c @@ -224,7 +224,7 @@ void ufs_error (struct super_block * sb, const char * function, sb->s_flags |= MS_RDONLY; } va_start (args, fmt); - vsnprintf (error_buf, sizeof(error_buf), fmt, args); + vsprintf (error_buf, fmt, args); va_end (args); switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) { case UFS_MOUNT_ONERROR_PANIC: @@ -255,7 +255,7 @@ void ufs_panic (struct super_block * sb, const char * function, sb->s_dirt = 1; } va_start (args, fmt); - vsnprintf (error_buf, sizeof(error_buf), fmt, args); + vsprintf (error_buf, fmt, args); va_end (args); sb->s_flags |= MS_RDONLY; printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n", @@ -268,7 +268,7 @@ void ufs_warning (struct super_block * sb, const char * function, va_list args; va_start (args, fmt); - vsnprintf (error_buf, sizeof(error_buf), fmt, args); + vsprintf (error_buf, fmt, args); va_end (args); printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n", sb->s_id, function, error_buf); @@ -1204,12 +1204,12 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -static struct kmem_cache * ufs_inode_cachep; +static kmem_cache_t * ufs_inode_cachep; static struct inode *ufs_alloc_inode(struct super_block *sb) { struct ufs_inode_info *ei; - ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_KERNEL); + ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; ei->vfs_inode.i_version = 1; @@ -1221,7 +1221,7 @@ static void ufs_destroy_inode(struct inode *inode) kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; diff --git a/trunk/fs/ufs/util.h b/trunk/fs/ufs/util.h index 7dd12bb1d62b..28fce6c239b5 100644 --- a/trunk/fs/ufs/util.h +++ b/trunk/fs/ufs/util.h @@ -299,7 +299,7 @@ static inline void *get_usb_offset(struct ufs_sb_private_info *uspi, #define ubh_get_addr16(ubh,begin) \ (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \ - ((begin) & ((uspi->fsize>>1) - 1))) + ((begin) & (uspi->fsize>>1) - 1))) #define ubh_get_addr32(ubh,begin) \ (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index 4fb01ffdfd1a..eef4a0ba11e9 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -32,7 +32,6 @@ #include #include #include -#include STATIC kmem_zone_t *xfs_buf_zone; STATIC kmem_shaker_t xfs_buf_shake; @@ -1827,11 +1826,11 @@ xfs_buf_init(void) if (!xfs_buf_zone) goto out_free_trace_buf; - xfslogd_workqueue = create_freezeable_workqueue("xfslogd"); + xfslogd_workqueue = create_workqueue("xfslogd"); if (!xfslogd_workqueue) goto out_free_buf_zone; - xfsdatad_workqueue = create_freezeable_workqueue("xfsdatad"); + xfsdatad_workqueue = create_workqueue("xfsdatad"); if (!xfsdatad_workqueue) goto out_destroy_xfslogd_workqueue; diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index b93265b7c79c..de05abbbe7fd 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -56,7 +56,6 @@ #include #include #include -#include STATIC struct quotactl_ops xfs_quotactl_operations; STATIC struct super_operations xfs_super_operations; diff --git a/trunk/include/acpi/platform/aclinux.h b/trunk/include/acpi/platform/aclinux.h index 7f1e92930b62..47faf27913a5 100644 --- a/trunk/include/acpi/platform/aclinux.h +++ b/trunk/include/acpi/platform/aclinux.h @@ -64,7 +64,7 @@ /* Host-dependent types and defines */ #define ACPI_MACHINE_WIDTH BITS_PER_LONG -#define acpi_cache_t struct kmem_cache +#define acpi_cache_t kmem_cache_t #define acpi_spinlock spinlock_t * #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); #define strtoul simple_strtoul diff --git a/trunk/include/asm-alpha/dma-mapping.h b/trunk/include/asm-alpha/dma-mapping.h index 57e09f5e3424..b9ff4d8cb33a 100644 --- a/trunk/include/asm-alpha/dma-mapping.h +++ b/trunk/include/asm-alpha/dma-mapping.h @@ -51,7 +51,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(dev) (1) int dma_set_mask(struct device *dev, u64 mask); @@ -60,7 +60,7 @@ int dma_set_mask(struct device *dev, u64 mask); #define dma_sync_single_range(dev, addr, off, size, dir) do { } while (0) #define dma_sync_sg_for_cpu(dev, sg, nents, dir) do { } while (0) #define dma_sync_sg_for_device(dev, sg, nents, dir) do { } while (0) -#define dma_cache_sync(dev, va, size, dir) do { } while (0) +#define dma_cache_sync(va, size, dir) do { } while (0) #define dma_get_cache_alignment() L1_CACHE_BYTES diff --git a/trunk/include/asm-alpha/unistd.h b/trunk/include/asm-alpha/unistd.h index 84313d14e780..2cabbd465c0c 100644 --- a/trunk/include/asm-alpha/unistd.h +++ b/trunk/include/asm-alpha/unistd.h @@ -387,6 +387,188 @@ #define NR_SYSCALLS 447 +#if defined(__GNUC__) + +#define _syscall_return(type) \ + return (_sc_err ? errno = _sc_ret, _sc_ret = -1L : 0), (type) _sc_ret + +#define _syscall_clobbers \ + "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \ + "$22", "$23", "$24", "$25", "$27", "$28" \ + +#define _syscall0(type, name) \ +type name(void) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_19 __asm__("$19"); \ + \ + _sc_0 = __NR_##name; \ + __asm__("callsys # %0 %1 %2" \ + : "=r"(_sc_0), "=r"(_sc_19) \ + : "0"(_sc_0) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; \ + } \ + _syscall_return(type); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_16 __asm__("$16"); \ + register long _sc_19 __asm__("$19"); \ + \ + _sc_0 = __NR_##name; \ + _sc_16 = (long) (arg1); \ + __asm__("callsys # %0 %1 %2 %3" \ + : "=r"(_sc_0), "=r"(_sc_19) \ + : "0"(_sc_0), "r"(_sc_16) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; \ + } \ + _syscall_return(type); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_16 __asm__("$16"); \ + register long _sc_17 __asm__("$17"); \ + register long _sc_19 __asm__("$19"); \ + \ + _sc_0 = __NR_##name; \ + _sc_16 = (long) (arg1); \ + _sc_17 = (long) (arg2); \ + __asm__("callsys # %0 %1 %2 %3 %4" \ + : "=r"(_sc_0), "=r"(_sc_19) \ + : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; \ + } \ + _syscall_return(type); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_16 __asm__("$16"); \ + register long _sc_17 __asm__("$17"); \ + register long _sc_18 __asm__("$18"); \ + register long _sc_19 __asm__("$19"); \ + \ + _sc_0 = __NR_##name; \ + _sc_16 = (long) (arg1); \ + _sc_17 = (long) (arg2); \ + _sc_18 = (long) (arg3); \ + __asm__("callsys # %0 %1 %2 %3 %4 %5" \ + : "=r"(_sc_0), "=r"(_sc_19) \ + : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ + "r"(_sc_18) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; \ + } \ + _syscall_return(type); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_16 __asm__("$16"); \ + register long _sc_17 __asm__("$17"); \ + register long _sc_18 __asm__("$18"); \ + register long _sc_19 __asm__("$19"); \ + \ + _sc_0 = __NR_##name; \ + _sc_16 = (long) (arg1); \ + _sc_17 = (long) (arg2); \ + _sc_18 = (long) (arg3); \ + _sc_19 = (long) (arg4); \ + __asm__("callsys # %0 %1 %2 %3 %4 %5 %6" \ + : "=r"(_sc_0), "=r"(_sc_19) \ + : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ + "r"(_sc_18), "1"(_sc_19) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; \ + } \ + _syscall_return(type); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_16 __asm__("$16"); \ + register long _sc_17 __asm__("$17"); \ + register long _sc_18 __asm__("$18"); \ + register long _sc_19 __asm__("$19"); \ + register long _sc_20 __asm__("$20"); \ + \ + _sc_0 = __NR_##name; \ + _sc_16 = (long) (arg1); \ + _sc_17 = (long) (arg2); \ + _sc_18 = (long) (arg3); \ + _sc_19 = (long) (arg4); \ + _sc_20 = (long) (arg5); \ + __asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7" \ + : "=r"(_sc_0), "=r"(_sc_19) \ + : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ + "r"(_sc_18), "1"(_sc_19), "r"(_sc_20) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; \ + } \ + _syscall_return(type); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_16 __asm__("$16"); \ + register long _sc_17 __asm__("$17"); \ + register long _sc_18 __asm__("$18"); \ + register long _sc_19 __asm__("$19"); \ + register long _sc_20 __asm__("$20"); \ + register long _sc_21 __asm__("$21"); \ + \ + _sc_0 = __NR_##name; \ + _sc_16 = (long) (arg1); \ + _sc_17 = (long) (arg2); \ + _sc_18 = (long) (arg3); \ + _sc_19 = (long) (arg4); \ + _sc_20 = (long) (arg5); \ + _sc_21 = (long) (arg6); \ + __asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7 %8" \ + : "=r"(_sc_0), "=r"(_sc_19) \ + : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ + "r"(_sc_18), "1"(_sc_19), "r"(_sc_20), "r"(_sc_21) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; \ + } \ + _syscall_return(type); \ +} + +#endif /* __GNUC__ */ + #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/trunk/include/asm-arm/dma-mapping.h b/trunk/include/asm-arm/dma-mapping.h index 9bc46b486afb..666617711c81 100644 --- a/trunk/include/asm-arm/dma-mapping.h +++ b/trunk/include/asm-arm/dma-mapping.h @@ -48,7 +48,7 @@ static inline int dma_get_cache_alignment(void) return 32; } -static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) +static inline int dma_is_consistent(dma_addr_t handle) { return !!arch_is_coherent(); } diff --git a/trunk/include/asm-arm/setup.h b/trunk/include/asm-arm/setup.h index e5407392afca..aa4b5782f0c9 100644 --- a/trunk/include/asm-arm/setup.h +++ b/trunk/include/asm-arm/setup.h @@ -14,57 +14,55 @@ #ifndef __ASMARM_SETUP_H #define __ASMARM_SETUP_H -#include - #define COMMAND_LINE_SIZE 1024 /* The list ends with an ATAG_NONE node. */ #define ATAG_NONE 0x00000000 struct tag_header { - __u32 size; - __u32 tag; + u32 size; + u32 tag; }; /* The list must start with an ATAG_CORE node */ #define ATAG_CORE 0x54410001 struct tag_core { - __u32 flags; /* bit 0 = read-only */ - __u32 pagesize; - __u32 rootdev; + u32 flags; /* bit 0 = read-only */ + u32 pagesize; + u32 rootdev; }; /* it is allowed to have multiple ATAG_MEM nodes */ #define ATAG_MEM 0x54410002 struct tag_mem32 { - __u32 size; - __u32 start; /* physical start address */ + u32 size; + u32 start; /* physical start address */ }; /* VGA text type displays */ #define ATAG_VIDEOTEXT 0x54410003 struct tag_videotext { - __u8 x; - __u8 y; - __u16 video_page; - __u8 video_mode; - __u8 video_cols; - __u16 video_ega_bx; - __u8 video_lines; - __u8 video_isvga; - __u16 video_points; + u8 x; + u8 y; + u16 video_page; + u8 video_mode; + u8 video_cols; + u16 video_ega_bx; + u8 video_lines; + u8 video_isvga; + u16 video_points; }; /* describes how the ramdisk will be used in kernel */ #define ATAG_RAMDISK 0x54410004 struct tag_ramdisk { - __u32 flags; /* bit 0 = load, bit 1 = prompt */ - __u32 size; /* decompressed ramdisk size in _kilo_ bytes */ - __u32 start; /* starting block of floppy-based RAM disk image */ + u32 flags; /* bit 0 = load, bit 1 = prompt */ + u32 size; /* decompressed ramdisk size in _kilo_ bytes */ + u32 start; /* starting block of floppy-based RAM disk image */ }; /* describes where the compressed ramdisk image lives (virtual address) */ @@ -78,23 +76,23 @@ struct tag_ramdisk { #define ATAG_INITRD2 0x54420005 struct tag_initrd { - __u32 start; /* physical start address */ - __u32 size; /* size of compressed ramdisk image in bytes */ + u32 start; /* physical start address */ + u32 size; /* size of compressed ramdisk image in bytes */ }; /* board serial number. "64 bits should be enough for everybody" */ #define ATAG_SERIAL 0x54410006 struct tag_serialnr { - __u32 low; - __u32 high; + u32 low; + u32 high; }; /* board revision */ #define ATAG_REVISION 0x54410007 struct tag_revision { - __u32 rev; + u32 rev; }; /* initial values for vesafb-type framebuffers. see struct screen_info @@ -103,20 +101,20 @@ struct tag_revision { #define ATAG_VIDEOLFB 0x54410008 struct tag_videolfb { - __u16 lfb_width; - __u16 lfb_height; - __u16 lfb_depth; - __u16 lfb_linelength; - __u32 lfb_base; - __u32 lfb_size; - __u8 red_size; - __u8 red_pos; - __u8 green_size; - __u8 green_pos; - __u8 blue_size; - __u8 blue_pos; - __u8 rsvd_size; - __u8 rsvd_pos; + u16 lfb_width; + u16 lfb_height; + u16 lfb_depth; + u16 lfb_linelength; + u32 lfb_base; + u32 lfb_size; + u8 red_size; + u8 red_pos; + u8 green_size; + u8 green_pos; + u8 blue_size; + u8 blue_pos; + u8 rsvd_size; + u8 rsvd_pos; }; /* command line: \0 terminated string */ @@ -130,17 +128,17 @@ struct tag_cmdline { #define ATAG_ACORN 0x41000101 struct tag_acorn { - __u32 memc_control_reg; - __u32 vram_pages; - __u8 sounddefault; - __u8 adfsdrives; + u32 memc_control_reg; + u32 vram_pages; + u8 sounddefault; + u8 adfsdrives; }; /* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */ #define ATAG_MEMCLK 0x41000402 struct tag_memclk { - __u32 fmemclk; + u32 fmemclk; }; struct tag { @@ -169,26 +167,24 @@ struct tag { }; struct tagtable { - __u32 tag; + u32 tag; int (*parse)(const struct tag *); }; +#define __tag __attribute_used__ __attribute__((__section__(".taglist.init"))) +#define __tagtable(tag, fn) \ +static struct tagtable __tagtable_##fn __tag = { tag, fn } + #define tag_member_present(tag,member) \ ((unsigned long)(&((struct tag *)0L)->member + 1) \ <= (tag)->hdr.size * 4) -#define tag_next(t) ((struct tag *)((__u32 *)(t) + (t)->hdr.size)) +#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size)) #define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) #define for_each_tag(t,base) \ for (t = base; t->hdr.size; t = tag_next(t)) -#ifdef __KERNEL__ - -#define __tag __attribute_used__ __attribute__((__section__(".taglist.init"))) -#define __tagtable(tag, fn) \ -static struct tagtable __tagtable_##fn __tag = { tag, fn } - /* * Memory map description */ @@ -221,6 +217,4 @@ struct early_params { static struct early_params __early_##fn __attribute_used__ \ __attribute__((__section__(".early_param.init"))) = { name, fn } -#endif /* __KERNEL__ */ - #endif diff --git a/trunk/include/asm-arm/unistd.h b/trunk/include/asm-arm/unistd.h index d44c629d8424..14a87eec5a2d 100644 --- a/trunk/include/asm-arm/unistd.h +++ b/trunk/include/asm-arm/unistd.h @@ -377,6 +377,156 @@ #endif #ifdef __KERNEL__ +#include +#include + +#define __sys2(x) #x +#define __sys1(x) __sys2(x) + +#ifndef __syscall +#if defined(__thumb__) || defined(__ARM_EABI__) +#define __SYS_REG(name) register long __sysreg __asm__("r7") = __NR_##name; +#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs +#define __syscall(name) "swi\t0" +#else +#define __SYS_REG(name) +#define __SYS_REG_LIST(regs...) regs +#define __syscall(name) "swi\t" __sys1(__NR_##name) "" +#endif +#endif + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) { \ + __SYS_REG(name) \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST() \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __r4 __asm__("r4") = (long)arg5; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ + "r" (__r3), "r" (__r4) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __r4 __asm__("r4") = (long)arg5; \ + register long __r5 __asm__("r5") = (long)arg6; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ + "r" (__r3), "r" (__r4), "r" (__r5) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 diff --git a/trunk/include/asm-arm26/pgalloc.h b/trunk/include/asm-arm26/pgalloc.h index 7725af3ddb4d..6437167b1ffe 100644 --- a/trunk/include/asm-arm26/pgalloc.h +++ b/trunk/include/asm-arm26/pgalloc.h @@ -15,7 +15,7 @@ #include #include -extern struct kmem_cache *pte_cache; +extern kmem_cache_t *pte_cache; static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr){ return kmem_cache_alloc(pte_cache, GFP_KERNEL); diff --git a/trunk/include/asm-arm26/setup.h b/trunk/include/asm-arm26/setup.h index 1a867b4e8d53..6348931be65d 100644 --- a/trunk/include/asm-arm26/setup.h +++ b/trunk/include/asm-arm26/setup.h @@ -16,8 +16,6 @@ #define COMMAND_LINE_SIZE 1024 -#ifdef __KERNEL__ - /* The list ends with an ATAG_NONE node. */ #define ATAG_NONE 0x00000000 @@ -204,6 +202,4 @@ struct meminfo { extern struct meminfo meminfo; -#endif /* __KERNEL__ */ - #endif diff --git a/trunk/include/asm-arm26/unistd.h b/trunk/include/asm-arm26/unistd.h index 4c3b919177e5..25a5eead85be 100644 --- a/trunk/include/asm-arm26/unistd.h +++ b/trunk/include/asm-arm26/unistd.h @@ -311,6 +311,139 @@ #define __ARM_NR_usr26 (__ARM_NR_BASE+3) #ifdef __KERNEL__ +#include +#include + +#define __sys2(x) #x +#define __sys1(x) __sys2(x) + +#ifndef __syscall +#define __syscall(name) "swi\t" __sys1(__NR_##name) "" +#endif + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)-MAX_ERRNO) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) { \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : \ + : "lr"); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) { \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : "r" (__r0) \ + : "lr"); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) { \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : "r" (__r0),"r" (__r1) \ + : "lr"); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) { \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : "r" (__r0),"r" (__r1),"r" (__r2) \ + : "lr"); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3) \ + : "lr"); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __r4 __asm__("r4") = (long)arg5; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4) \ + : "lr"); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __r4 __asm__("r4") = (long)arg5; \ + register long __r5 __asm__("r5") = (long)arg6; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3), "r" (__r4),"r" (__r5) \ + : "lr"); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-avr32/dma-mapping.h b/trunk/include/asm-avr32/dma-mapping.h index 0580b5d62bba..4c40cb41cdf8 100644 --- a/trunk/include/asm-avr32/dma-mapping.h +++ b/trunk/include/asm-avr32/dma-mapping.h @@ -8,8 +8,7 @@ #include #include -extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - int direction); +extern void dma_cache_sync(void *vaddr, size_t size, int direction); /* * Return whether the given device DMA address mask can be supported @@ -308,7 +307,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +static inline int dma_is_consistent(dma_addr_t dma_addr) { return 1; } diff --git a/trunk/include/asm-avr32/setup.h b/trunk/include/asm-avr32/setup.h index 0a5224245e44..10193da4113b 100644 --- a/trunk/include/asm-avr32/setup.h +++ b/trunk/include/asm-avr32/setup.h @@ -13,8 +13,6 @@ #define COMMAND_LINE_SIZE 256 -#ifdef __KERNEL__ - /* Magic number indicating that a tag table is present */ #define ATAG_MAGIC 0xa2a25441 @@ -140,6 +138,4 @@ void chip_enable_sdram(void); #endif /* !__ASSEMBLY__ */ -#endif /* __KERNEL__ */ - #endif /* __ASM_AVR32_SETUP_H__ */ diff --git a/trunk/include/asm-cris/arch-v10/bitops.h b/trunk/include/asm-cris/arch-v10/bitops.h index be85f6de25d3..b73f5396e5a6 100644 --- a/trunk/include/asm-cris/arch-v10/bitops.h +++ b/trunk/include/asm-cris/arch-v10/bitops.h @@ -10,7 +10,7 @@ * number. They differ in that the first function also inverts all bits * in the input. */ -static inline unsigned long cris_swapnwbrlz(unsigned long w) +extern inline unsigned long cris_swapnwbrlz(unsigned long w) { /* Let's just say we return the result in the same register as the input. Saying we clobber the input but can return the result @@ -26,7 +26,7 @@ static inline unsigned long cris_swapnwbrlz(unsigned long w) return res; } -static inline unsigned long cris_swapwbrlz(unsigned long w) +extern inline unsigned long cris_swapwbrlz(unsigned long w) { unsigned res; __asm__ ("swapwbr %0 \n\t" @@ -40,7 +40,7 @@ static inline unsigned long cris_swapwbrlz(unsigned long w) * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */ -static inline unsigned long ffz(unsigned long w) +extern inline unsigned long ffz(unsigned long w) { return cris_swapnwbrlz(w); } @@ -51,7 +51,7 @@ static inline unsigned long ffz(unsigned long w) * * Undefined if no bit exists, so code should check against 0 first. */ -static inline unsigned long __ffs(unsigned long word) +extern inline unsigned long __ffs(unsigned long word) { return cris_swapnwbrlz(~word); } @@ -65,7 +65,7 @@ static inline unsigned long __ffs(unsigned long word) * differs in spirit from the above ffz (man ffs). */ -static inline unsigned long kernel_ffs(unsigned long w) +extern inline unsigned long kernel_ffs(unsigned long w) { return w ? cris_swapwbrlz (w) + 1 : 0; } diff --git a/trunk/include/asm-cris/dma-mapping.h b/trunk/include/asm-cris/dma-mapping.h index 662cea70152d..cbf1a98f0129 100644 --- a/trunk/include/asm-cris/dma-mapping.h +++ b/trunk/include/asm-cris/dma-mapping.h @@ -156,10 +156,10 @@ dma_get_cache_alignment(void) return (1 << INTERNODE_CACHE_SHIFT); } -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { } diff --git a/trunk/include/asm-cris/semaphore-helper.h b/trunk/include/asm-cris/semaphore-helper.h index a8e1e6cb7cd0..dbd0f30b85b6 100644 --- a/trunk/include/asm-cris/semaphore-helper.h +++ b/trunk/include/asm-cris/semaphore-helper.h @@ -20,12 +20,12 @@ /* * These two _must_ execute atomically wrt each other. */ -static inline void wake_one_more(struct semaphore * sem) +extern inline void wake_one_more(struct semaphore * sem) { atomic_inc(&sem->waking); } -static inline int waking_non_zero(struct semaphore *sem) +extern inline int waking_non_zero(struct semaphore *sem) { unsigned long flags; int ret = 0; @@ -40,7 +40,7 @@ static inline int waking_non_zero(struct semaphore *sem) return ret; } -static inline int waking_non_zero_interruptible(struct semaphore *sem, +extern inline int waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) { int ret = 0; @@ -59,7 +59,7 @@ static inline int waking_non_zero_interruptible(struct semaphore *sem, return ret; } -static inline int waking_non_zero_trylock(struct semaphore *sem) +extern inline int waking_non_zero_trylock(struct semaphore *sem) { int ret = 1; unsigned long flags; diff --git a/trunk/include/asm-frv/dma-mapping.h b/trunk/include/asm-frv/dma-mapping.h index bcb2df68496e..e9fc1d47797e 100644 --- a/trunk/include/asm-frv/dma-mapping.h +++ b/trunk/include/asm-frv/dma-mapping.h @@ -172,10 +172,10 @@ int dma_get_cache_alignment(void) return 1 << L1_CACHE_SHIFT; } -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) static inline -void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { flush_write_buffers(); diff --git a/trunk/include/asm-frv/highmem.h b/trunk/include/asm-frv/highmem.h index ff4d6cdeb152..0f390f41f816 100644 --- a/trunk/include/asm-frv/highmem.h +++ b/trunk/include/asm-frv/highmem.h @@ -115,7 +115,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) { unsigned long paddr; - pagefault_disable(); + inc_preempt_count(); paddr = page_to_phys(page); switch (type) { @@ -170,7 +170,8 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) default: BUG(); } - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); } #endif /* !__ASSEMBLY__ */ diff --git a/trunk/include/asm-frv/param.h b/trunk/include/asm-frv/param.h index 365653b1726c..168381ebb41a 100644 --- a/trunk/include/asm-frv/param.h +++ b/trunk/include/asm-frv/param.h @@ -18,5 +18,6 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#define COMMAND_LINE_SIZE 512 #endif /* _ASM_PARAM_H */ diff --git a/trunk/include/asm-frv/setup.h b/trunk/include/asm-frv/setup.h index afd787ceede6..0d293b9a5857 100644 --- a/trunk/include/asm-frv/setup.h +++ b/trunk/include/asm-frv/setup.h @@ -12,10 +12,6 @@ #ifndef _ASM_SETUP_H #define _ASM_SETUP_H -#define COMMAND_LINE_SIZE 512 - -#ifdef __KERNEL__ - #include #ifndef __ASSEMBLY__ @@ -26,6 +22,4 @@ extern unsigned long __initdata num_mappedpages; #endif /* !__ASSEMBLY__ */ -#endif /* __KERNEL__ */ - #endif /* _ASM_SETUP_H */ diff --git a/trunk/include/asm-frv/unistd.h b/trunk/include/asm-frv/unistd.h index 584c0417ae4d..725e854928cf 100644 --- a/trunk/include/asm-frv/unistd.h +++ b/trunk/include/asm-frv/unistd.h @@ -320,6 +320,125 @@ #ifdef __KERNEL__ #define NR_syscalls 310 +#include + +/* + * process the return value of a syscall, consigning it to one of two possible fates + * - user-visible error numbers are in the range -1 - -4095: see + */ +#undef __syscall_return +#define __syscall_return(type, res) \ +do { \ + unsigned long __sr2 = (res); \ + if (__builtin_expect(__sr2 >= (unsigned long)(-MAX_ERRNO), 0)) { \ + errno = (-__sr2); \ + __sr2 = ~0UL; \ + } \ + return (type) __sr2; \ +} while (0) + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ + +#undef _syscall0 +#define _syscall0(type,name) \ +type name(void) \ +{ \ + register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ + register unsigned long __sc0 __asm__ ("gr8"); \ + __asm__ __volatile__ ("tira gr0,#0" \ + : "=r" (__sc0) \ + : "r" (__scnum)); \ + __syscall_return(type, __sc0); \ +} + +#undef _syscall1 +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ + register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ + __asm__ __volatile__ ("tira gr0,#0" \ + : "+r" (__sc0) \ + : "r" (__scnum)); \ + __syscall_return(type, __sc0); \ +} + +#undef _syscall2 +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ + register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ + register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ + __asm__ __volatile__ ("tira gr0,#0" \ + : "+r" (__sc0) \ + : "r" (__scnum), "r" (__sc1)); \ + __syscall_return(type, __sc0); \ +} + +#undef _syscall3 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ + register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ + register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ + register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ + register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ + __asm__ __volatile__ ("tira gr0,#0" \ + : "+r" (__sc0) \ + : "r" (__scnum), "r" (__sc1), "r" (__sc2)); \ + __syscall_return(type, __sc0); \ +} + +#undef _syscall4 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ + register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ + register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ + register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ + register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \ + __asm__ __volatile__ ("tira gr0,#0" \ + : "+r" (__sc0) \ + : "r" (__scnum), "r" (__sc1), "r" (__sc2), "r" (__sc3)); \ + __syscall_return(type, __sc0); \ +} + +#undef _syscall5 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ +{ \ + register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ + register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ + register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ + register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ + register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \ + register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \ + __asm__ __volatile__ ("tira gr0,#0" \ + : "+r" (__sc0) \ + : "r" (__scnum), "r" (__sc1), "r" (__sc2), \ + "r" (__sc3), "r" (__sc4)); \ + __syscall_return(type, __sc0); \ +} + +#undef _syscall6 +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ +{ \ + register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ + register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ + register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ + register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ + register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \ + register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \ + register unsigned long __sc5 __asm__ ("gr13") = (unsigned long) arg6; \ + __asm__ __volatile__ ("tira gr0,#0" \ + : "+r" (__sc0) \ + : "r" (__scnum), "r" (__sc1), "r" (__sc2), \ + "r" (__sc3), "r" (__sc4), "r" (__sc5)); \ + __syscall_return(type, __sc0); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ diff --git a/trunk/include/asm-generic/Kbuild b/trunk/include/asm-generic/Kbuild index fa14f8cd30c5..3c06be381701 100644 --- a/trunk/include/asm-generic/Kbuild +++ b/trunk/include/asm-generic/Kbuild @@ -1,3 +1,4 @@ +header-y += atomic.h header-y += errno-base.h header-y += errno.h header-y += fcntl.h diff --git a/trunk/include/asm-generic/Kbuild.asm b/trunk/include/asm-generic/Kbuild.asm index a37e95fe58d6..a84c3d88a189 100644 --- a/trunk/include/asm-generic/Kbuild.asm +++ b/trunk/include/asm-generic/Kbuild.asm @@ -14,7 +14,6 @@ unifdef-y += posix_types.h unifdef-y += ptrace.h unifdef-y += resource.h unifdef-y += sembuf.h -unifdef-y += setup.h unifdef-y += shmbuf.h unifdef-y += sigcontext.h unifdef-y += siginfo.h diff --git a/trunk/include/asm-generic/atomic.h b/trunk/include/asm-generic/atomic.h index b7e4a0467cb1..42a95d9a0641 100644 --- a/trunk/include/asm-generic/atomic.h +++ b/trunk/include/asm-generic/atomic.h @@ -66,7 +66,7 @@ static inline void atomic_long_sub(long i, atomic_long_t *l) atomic64_sub(i, v); } -#else /* BITS_PER_LONG == 64 */ +#else typedef atomic_t atomic_long_t; @@ -113,6 +113,5 @@ static inline void atomic_long_sub(long i, atomic_long_t *l) atomic_sub(i, v); } -#endif /* BITS_PER_LONG == 64 */ - -#endif /* _ASM_GENERIC_ATOMIC_H */ +#endif +#endif diff --git a/trunk/include/asm-generic/dma-mapping.h b/trunk/include/asm-generic/dma-mapping.h index 783ab9944d70..b541e48cc545 100644 --- a/trunk/include/asm-generic/dma-mapping.h +++ b/trunk/include/asm-generic/dma-mapping.h @@ -266,7 +266,7 @@ dma_error(dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) static inline int dma_get_cache_alignment(void) @@ -295,7 +295,7 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, } static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { /* could define this in terms of the dma_cache ... operations, diff --git a/trunk/include/asm-generic/futex.h b/trunk/include/asm-generic/futex.h index f422df0956a2..df893c160318 100644 --- a/trunk/include/asm-generic/futex.h +++ b/trunk/include/asm-generic/futex.h @@ -21,7 +21,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -33,7 +33,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-generic/vmlinux.lds.h b/trunk/include/asm-generic/vmlinux.lds.h index 4d4c62d11059..e60d6f21fa62 100644 --- a/trunk/include/asm-generic/vmlinux.lds.h +++ b/trunk/include/asm-generic/vmlinux.lds.h @@ -11,8 +11,8 @@ #define RODATA \ . = ALIGN(4096); \ + __start_rodata = .; \ .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_rodata) = .; \ *(.rodata) *(.rodata.*) \ *(__vermagic) /* Kernel version magic */ \ } \ @@ -119,16 +119,17 @@ *(__ksymtab_strings) \ } \ \ - EH_FRAME \ - \ /* Built-in module parameters. */ \ __param : AT(ADDR(__param) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___param) = .; \ *(__param) \ VMLINUX_SYMBOL(__stop___param) = .; \ - VMLINUX_SYMBOL(__end_rodata) = .; \ } \ \ + /* Unwind data binary search table */ \ + EH_FRAME_HDR \ + \ + __end_rodata = .; \ . = ALIGN(4096); #define SECURITY_INIT \ @@ -161,23 +162,15 @@ VMLINUX_SYMBOL(__kprobes_text_end) = .; #ifdef CONFIG_STACK_UNWIND -#define EH_FRAME \ - /* Unwind data binary search table */ \ - . = ALIGN(8); \ + /* Unwind data binary search table */ +#define EH_FRAME_HDR \ .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_unwind_hdr) = .; \ *(.eh_frame_hdr) \ VMLINUX_SYMBOL(__end_unwind_hdr) = .; \ - } \ - /* Unwind data */ \ - . = ALIGN(8); \ - .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_unwind) = .; \ - *(.eh_frame) \ - VMLINUX_SYMBOL(__end_unwind) = .; \ } #else -#define EH_FRAME +#define EH_FRAME_HDR #endif /* DWARF debug sections. diff --git a/trunk/include/asm-h8300/delay.h b/trunk/include/asm-h8300/delay.h index 743beba70f82..cbccbbdd640f 100644 --- a/trunk/include/asm-h8300/delay.h +++ b/trunk/include/asm-h8300/delay.h @@ -9,7 +9,7 @@ * Delay routines, using a pre-computed "loops_per_second" value. */ -static inline void __delay(unsigned long loops) +extern __inline__ void __delay(unsigned long loops) { __asm__ __volatile__ ("1:\n\t" "dec.l #1,%0\n\t" @@ -27,7 +27,7 @@ static inline void __delay(unsigned long loops) extern unsigned long loops_per_jiffy; -static inline void udelay(unsigned long usecs) +extern __inline__ void udelay(unsigned long usecs) { usecs *= 4295; /* 2**32 / 1000000 */ usecs /= (loops_per_jiffy*HZ); diff --git a/trunk/include/asm-h8300/mmu_context.h b/trunk/include/asm-h8300/mmu_context.h index 5c165f7bee0e..855721a5dcc9 100644 --- a/trunk/include/asm-h8300/mmu_context.h +++ b/trunk/include/asm-h8300/mmu_context.h @@ -9,7 +9,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } -static inline int +extern inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { // mm->context = virt_to_phys(mm->pgd); @@ -23,7 +23,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, str { } -static inline void activate_mm(struct mm_struct *prev_mm, +extern inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm) { } diff --git a/trunk/include/asm-h8300/pci.h b/trunk/include/asm-h8300/pci.h index 0c771b05fdd5..5edad5b70fd5 100644 --- a/trunk/include/asm-h8300/pci.h +++ b/trunk/include/asm-h8300/pci.h @@ -10,12 +10,12 @@ #define pcibios_assign_all_busses() 0 #define pcibios_scan_all_fns(a, b) 0 -static inline void pcibios_set_master(struct pci_dev *dev) +extern inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ } -static inline void pcibios_penalize_isa_irq(int irq, int active) +extern inline void pcibios_penalize_isa_irq(int irq, int active) { /* We don't do dynamic PCI IRQ allocation */ } diff --git a/trunk/include/asm-h8300/tlbflush.h b/trunk/include/asm-h8300/tlbflush.h index 9a2c5c9fd700..bbdffbeeedef 100644 --- a/trunk/include/asm-h8300/tlbflush.h +++ b/trunk/include/asm-h8300/tlbflush.h @@ -47,12 +47,12 @@ static inline void flush_tlb_range(struct mm_struct *mm, BUG(); } -static inline void flush_tlb_kernel_page(unsigned long addr) +extern inline void flush_tlb_kernel_page(unsigned long addr) { BUG(); } -static inline void flush_tlb_pgtables(struct mm_struct *mm, +extern inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) { BUG(); diff --git a/trunk/include/asm-h8300/unistd.h b/trunk/include/asm-h8300/unistd.h index 7ddd414f8d16..747788d629ae 100644 --- a/trunk/include/asm-h8300/unistd.h +++ b/trunk/include/asm-h8300/unistd.h @@ -295,6 +295,172 @@ #ifdef __KERNEL__ #define NR_syscalls 289 +#include + +/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see + */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + /* avoid using res which is declared to be in register d0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type, name) \ +type name(void) \ +{ \ + register long __res __asm__("er0"); \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "g" (__NR_##name) \ + : "cc", "memory"); \ + __syscall_return(type, __res); \ +} + +#define _syscall1(type, name, atype, a) \ +type name(atype a) \ +{ \ + register long __res __asm__("er0"); \ + register long _a __asm__("er1"); \ + _a = (long)a; \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "g" (__NR_##name), \ + "g" (_a) \ + : "cc", "memory"); \ + __syscall_return(type, __res); \ +} + +#define _syscall2(type, name, atype, a, btype, b) \ +type name(atype a, btype b) \ +{ \ + register long __res __asm__("er0"); \ + register long _a __asm__("er1"); \ + register long _b __asm__("er2"); \ + _a = (long)a; \ + _b = (long)b; \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "g" (__NR_##name), \ + "g" (_a), \ + "g" (_b) \ + : "cc", "memory"); \ + __syscall_return(type, __res); \ +} + +#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ +type name(atype a, btype b, ctype c) \ +{ \ + register long __res __asm__("er0"); \ + register long _a __asm__("er1"); \ + register long _b __asm__("er2"); \ + register long _c __asm__("er3"); \ + _a = (long)a; \ + _b = (long)b; \ + _c = (long)c; \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "g" (__NR_##name), \ + "g" (_a), \ + "g" (_b), \ + "g" (_c) \ + : "cc", "memory"); \ + __syscall_return(type, __res); \ +} + +#define _syscall4(type, name, atype, a, btype, b, \ + ctype, c, dtype, d) \ +type name(atype a, btype b, ctype c, dtype d) \ +{ \ + register long __res __asm__("er0"); \ + register long _a __asm__("er1"); \ + register long _b __asm__("er2"); \ + register long _c __asm__("er3"); \ + register long _d __asm__("er4"); \ + _a = (long)a; \ + _b = (long)b; \ + _c = (long)c; \ + _d = (long)d; \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "g" (__NR_##name), \ + "g" (_a), \ + "g" (_b), \ + "g" (_c), \ + "g" (_d) \ + : "cc", "memory"); \ + __syscall_return(type, __res); \ +} + +#define _syscall5(type, name, atype, a, btype, b, \ + ctype, c, dtype, d, etype, e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ +{ \ + register long __res __asm__("er0"); \ + register long _a __asm__("er1"); \ + register long _b __asm__("er2"); \ + register long _c __asm__("er3"); \ + register long _d __asm__("er4"); \ + register long _e __asm__("er5"); \ + _a = (long)a; \ + _b = (long)b; \ + _c = (long)c; \ + _d = (long)d; \ + _e = (long)e; \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "g" (__NR_##name), \ + "g" (_a), \ + "g" (_b), \ + "g" (_c), \ + "g" (_d), \ + "g" (_e) \ + : "cc", "memory"); \ + __syscall_return(type, __res); \ +} + +#define _syscall6(type, name, atype, a, btype, b, \ + ctype, c, dtype, d, etype, e, ftype, f) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \ +{ \ + register long __res __asm__("er0"); \ + register long _a __asm__("er1"); \ + register long _b __asm__("er2"); \ + register long _c __asm__("er3"); \ + register long _d __asm__("er4"); \ + register long _e __asm__("er5"); \ + register long _f __asm__("er6"); \ + _a = (long)a; \ + _b = (long)b; \ + _c = (long)c; \ + _d = (long)d; \ + _e = (long)e; \ + _f = (long)f; \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "g" (__NR_##name), \ + "g" (_a), \ + "g" (_b), \ + "g" (_c), \ + "g" (_d), \ + "g" (_e) \ + "g" (_f) \ + : "cc", "memory"); \ + __syscall_return(type, __res); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-i386/Kbuild b/trunk/include/asm-i386/Kbuild index 5ae93afc67e1..147e4ac1ebf0 100644 --- a/trunk/include/asm-i386/Kbuild +++ b/trunk/include/asm-i386/Kbuild @@ -7,4 +7,5 @@ header-y += ptrace-abi.h header-y += ucontext.h unifdef-y += mtrr.h +unifdef-y += setup.h unifdef-y += vm86.h diff --git a/trunk/include/asm-i386/alternative.h b/trunk/include/asm-i386/alternative.h index b8fa9557c532..b01a7ec409ce 100644 --- a/trunk/include/asm-i386/alternative.h +++ b/trunk/include/asm-i386/alternative.h @@ -4,7 +4,7 @@ #ifdef __KERNEL__ #include -#include + #include struct alt_instr { @@ -118,15 +118,4 @@ static inline void alternatives_smp_switch(int smp) {} #define LOCK_PREFIX "" #endif -struct paravirt_patch; -#ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end); -#else -static inline void -apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) -{} -#define __start_parainstructions NULL -#define __stop_parainstructions NULL -#endif - #endif /* _I386_ALTERNATIVE_H */ diff --git a/trunk/include/asm-i386/apic.h b/trunk/include/asm-i386/apic.h index 41a44319905f..b9529578fc37 100644 --- a/trunk/include/asm-i386/apic.h +++ b/trunk/include/asm-i386/apic.h @@ -37,27 +37,18 @@ extern void generic_apic_probe(void); /* * Basic functions accessing APICs. */ -#ifdef CONFIG_PARAVIRT -#include -#else -#define apic_write native_apic_write -#define apic_write_atomic native_apic_write_atomic -#define apic_read native_apic_read -#endif -static __inline fastcall void native_apic_write(unsigned long reg, - unsigned long v) +static __inline void apic_write(unsigned long reg, unsigned long v) { *((volatile unsigned long *)(APIC_BASE+reg)) = v; } -static __inline fastcall void native_apic_write_atomic(unsigned long reg, - unsigned long v) +static __inline void apic_write_atomic(unsigned long reg, unsigned long v) { xchg((volatile unsigned long *)(APIC_BASE+reg), v); } -static __inline fastcall unsigned long native_apic_read(unsigned long reg) +static __inline unsigned long apic_read(unsigned long reg) { return *((volatile unsigned long *)(APIC_BASE+reg)); } diff --git a/trunk/include/asm-i386/atomic.h b/trunk/include/asm-i386/atomic.h index c57441bb2905..a6c024e2506f 100644 --- a/trunk/include/asm-i386/atomic.h +++ b/trunk/include/asm-i386/atomic.h @@ -187,9 +187,9 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) /* Modern 486+ processor */ __i = i; __asm__ __volatile__( - LOCK_PREFIX "xaddl %0, %1" - :"+r" (i), "+m" (v->counter) - : : "memory"); + LOCK_PREFIX "xaddl %0, %1;" + :"=r"(i) + :"m"(v->counter), "0"(i)); return i + __i; #ifdef CONFIG_M386 diff --git a/trunk/include/asm-i386/boot.h b/trunk/include/asm-i386/boot.h index 8ce79a6fa891..96b228e6e79c 100644 --- a/trunk/include/asm-i386/boot.h +++ b/trunk/include/asm-i386/boot.h @@ -12,8 +12,4 @@ #define EXTENDED_VGA 0xfffe /* 80x50 mode */ #define ASK_VGA 0xfffd /* ask for it at bootup */ -/* Physical address where kenrel should be loaded. */ -#define LOAD_PHYSICAL_ADDR ((0x100000 + CONFIG_PHYSICAL_ALIGN - 1) \ - & ~(CONFIG_PHYSICAL_ALIGN - 1)) - -#endif /* _LINUX_BOOT_H */ +#endif diff --git a/trunk/include/asm-i386/bugs.h b/trunk/include/asm-i386/bugs.h index 38f1aebbbdb5..592ffeeda45e 100644 --- a/trunk/include/asm-i386/bugs.h +++ b/trunk/include/asm-i386/bugs.h @@ -21,7 +21,6 @@ #include #include #include -#include static int __init no_halt(char *s) { @@ -92,9 +91,6 @@ static void __init check_fpu(void) static void __init check_hlt(void) { - if (paravirt_enabled()) - return; - printk(KERN_INFO "Checking 'hlt' instruction... "); if (!boot_cpu_data.hlt_works_ok) { printk("disabled\n"); diff --git a/trunk/include/asm-i386/cpu.h b/trunk/include/asm-i386/cpu.h index 9d914e1e4aad..b1bc7b1b64b0 100644 --- a/trunk/include/asm-i386/cpu.h +++ b/trunk/include/asm-i386/cpu.h @@ -13,9 +13,6 @@ struct i386_cpu { extern int arch_register_cpu(int num); #ifdef CONFIG_HOTPLUG_CPU extern void arch_unregister_cpu(int); -extern int enable_cpu_hotplug; -#else -#define enable_cpu_hotplug 0 #endif DECLARE_PER_CPU(int, cpu_state); diff --git a/trunk/include/asm-i386/cpufeature.h b/trunk/include/asm-i386/cpufeature.h index 3f92b94e0d75..d314ebb3d59e 100644 --- a/trunk/include/asm-i386/cpufeature.h +++ b/trunk/include/asm-i386/cpufeature.h @@ -31,7 +31,7 @@ #define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ #define X86_FEATURE_PN (0*32+18) /* Processor serial number */ #define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ -#define X86_FEATURE_DS (0*32+21) /* Debug Store */ +#define X86_FEATURE_DTES (0*32+21) /* Debug Trace Store */ #define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ #define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ #define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ @@ -73,8 +73,6 @@ #define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */ #define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */ -#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ -#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ @@ -136,10 +134,6 @@ #define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN) #define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM) #define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) -#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) -#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) -#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) -#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) #endif /* __ASM_I386_CPUFEATURE_H */ diff --git a/trunk/include/asm-i386/current.h b/trunk/include/asm-i386/current.h index 5252ee0f6d7a..3cbbecd79016 100644 --- a/trunk/include/asm-i386/current.h +++ b/trunk/include/asm-i386/current.h @@ -1,14 +1,13 @@ #ifndef _I386_CURRENT_H #define _I386_CURRENT_H -#include -#include +#include struct task_struct; -static __always_inline struct task_struct *get_current(void) +static __always_inline struct task_struct * get_current(void) { - return read_pda(pcurrent); + return current_thread_info()->task; } #define current get_current() diff --git a/trunk/include/asm-i386/delay.h b/trunk/include/asm-i386/delay.h index 32d6678d0bbf..b1c7650dc7b9 100644 --- a/trunk/include/asm-i386/delay.h +++ b/trunk/include/asm-i386/delay.h @@ -7,7 +7,6 @@ * Delay routines calling functions in arch/i386/lib/delay.c */ -/* Undefined functions to get compile-time errors */ extern void __bad_udelay(void); extern void __bad_ndelay(void); @@ -16,23 +15,13 @@ extern void __ndelay(unsigned long nsecs); extern void __const_udelay(unsigned long usecs); extern void __delay(unsigned long loops); -#if defined(CONFIG_PARAVIRT) && !defined(USE_REAL_TIME_DELAY) -#define udelay(n) paravirt_ops.const_udelay((n) * 0x10c7ul) - -#define ndelay(n) paravirt_ops.const_udelay((n) * 5ul) - -#else /* !PARAVIRT || USE_REAL_TIME_DELAY */ - -/* 0x10c7 is 2**32 / 1000000 (rounded up) */ #define udelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ __udelay(n)) - -/* 0x5 is 2**32 / 1000000000 (rounded up) */ + #define ndelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) -#endif void use_tsc_delay(void); diff --git a/trunk/include/asm-i386/desc.h b/trunk/include/asm-i386/desc.h index f398cc456448..5874ef119ffd 100644 --- a/trunk/include/asm-i386/desc.h +++ b/trunk/include/asm-i386/desc.h @@ -4,6 +4,8 @@ #include #include +#define CPU_16BIT_STACK_SIZE 1024 + #ifndef __ASSEMBLY__ #include @@ -14,6 +16,8 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; +DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); + struct Xgt_desc_struct { unsigned short size; unsigned long address __attribute__((packed)); @@ -29,6 +33,11 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; } +/* + * This is the ldt that every process will get unless we need + * something other than this. + */ +extern struct desc_struct default_ldt[]; extern struct desc_struct idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); @@ -55,10 +64,8 @@ static inline void pack_gate(__u32 *a, __u32 *b, #define DESCTYPE_DPL3 0x60 /* DPL-3 */ #define DESCTYPE_S 0x10 /* !system */ -#ifdef CONFIG_PARAVIRT -#include -#else #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) +#define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)) #define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) #define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr)) @@ -81,10 +88,6 @@ static inline void load_TLS(struct thread_struct *t, unsigned int cpu) #undef C } -#define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) - static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) { __u32 *lp = (__u32 *)((char *)dt + entry*8); @@ -92,25 +95,9 @@ static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entr *(lp+1) = entry_b; } -#define set_ldt native_set_ldt -#endif /* CONFIG_PARAVIRT */ - -static inline fastcall void native_set_ldt(const void *addr, - unsigned int entries) -{ - if (likely(entries == 0)) - __asm__ __volatile__("lldt %w0"::"q" (0)); - else { - unsigned cpu = smp_processor_id(); - __u32 a, b; - - pack_descriptor(&a, &b, (unsigned long)addr, - entries * sizeof(struct desc_struct) - 1, - DESCTYPE_LDT, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); - __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); - } -} +#define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) { @@ -128,6 +115,14 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); } +static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entries) +{ + __u32 a, b; + pack_descriptor(&a, &b, (unsigned long)addr, + entries * sizeof(struct desc_struct) - 1, + DESCTYPE_LDT, 0); + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); +} #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) @@ -158,22 +153,35 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo static inline void clear_LDT(void) { - set_ldt(NULL, 0); + int cpu = get_cpu(); + + set_ldt_desc(cpu, &default_ldt[0], 5); + load_LDT_desc(); + put_cpu(); } /* * load one particular LDT into the current CPU */ -static inline void load_LDT_nolock(mm_context_t *pc) +static inline void load_LDT_nolock(mm_context_t *pc, int cpu) { - set_ldt(pc->ldt, pc->size); + void *segments = pc->ldt; + int count = pc->size; + + if (likely(!count)) { + segments = &default_ldt[0]; + count = 5; + } + + set_ldt_desc(cpu, segments, count); + load_LDT_desc(); } static inline void load_LDT(mm_context_t *pc) { - preempt_disable(); - load_LDT_nolock(pc); - preempt_enable(); + int cpu = get_cpu(); + load_LDT_nolock(pc, cpu); + put_cpu(); } static inline unsigned long get_desc_base(unsigned long *desc) @@ -185,29 +193,6 @@ static inline unsigned long get_desc_base(unsigned long *desc) return base; } -#else /* __ASSEMBLY__ */ - -/* - * GET_DESC_BASE reads the descriptor base of the specified segment. - * - * Args: - * idx - descriptor index - * gdt - GDT pointer - * base - 32bit register to which the base will be written - * lo_w - lo word of the "base" register - * lo_b - lo byte of the "base" register - * hi_b - hi byte of the low word of the "base" register - * - * Example: - * GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) - * Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. - */ -#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \ - movb idx*8+4(gdt), lo_b; \ - movb idx*8+7(gdt), hi_b; \ - shll $16, base; \ - movw idx*8+2(gdt), lo_w; - #endif /* !__ASSEMBLY__ */ #endif diff --git a/trunk/include/asm-i386/dma-mapping.h b/trunk/include/asm-i386/dma-mapping.h index 183eebeebbdc..81999a3ebe7c 100644 --- a/trunk/include/asm-i386/dma-mapping.h +++ b/trunk/include/asm-i386/dma-mapping.h @@ -156,10 +156,10 @@ dma_get_cache_alignment(void) return (1 << INTERNODE_CACHE_SHIFT); } -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { flush_write_buffers(); diff --git a/trunk/include/asm-i386/e820.h b/trunk/include/asm-i386/e820.h index 395077aba583..f7514fb6e8e4 100644 --- a/trunk/include/asm-i386/e820.h +++ b/trunk/include/asm-i386/e820.h @@ -38,11 +38,6 @@ extern struct e820map e820; extern int e820_all_mapped(unsigned long start, unsigned long end, unsigned type); -extern void find_max_pfn(void); -extern void register_bootmem_low_pages(unsigned long max_low_pfn); -extern void register_memory(void); -extern void limit_regions(unsigned long long size); -extern void print_memory_map(char *who); #endif/*!__ASSEMBLY__*/ diff --git a/trunk/include/asm-i386/elf.h b/trunk/include/asm-i386/elf.h index 45d21a0c95bf..3a05436f31c0 100644 --- a/trunk/include/asm-i386/elf.h +++ b/trunk/include/asm-i386/elf.h @@ -91,7 +91,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t; pr_reg[7] = regs->xds; \ pr_reg[8] = regs->xes; \ savesegment(fs,pr_reg[9]); \ - pr_reg[10] = regs->xgs; \ + savesegment(gs,pr_reg[10]); \ pr_reg[11] = regs->orig_eax; \ pr_reg[12] = regs->eip; \ pr_reg[13] = regs->xcs; \ diff --git a/trunk/include/asm-i386/futex.h b/trunk/include/asm-i386/futex.h index 438ef0ec7101..946d97cfea23 100644 --- a/trunk/include/asm-i386/futex.h +++ b/trunk/include/asm-i386/futex.h @@ -56,7 +56,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); if (op == FUTEX_OP_SET) __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); @@ -88,7 +88,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) } } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-i386/genapic.h b/trunk/include/asm-i386/genapic.h index fd2be593b06e..8ffbb0f07457 100644 --- a/trunk/include/asm-i386/genapic.h +++ b/trunk/include/asm-i386/genapic.h @@ -122,6 +122,6 @@ struct genapic { APICFUNC(phys_pkg_id) \ } -extern struct genapic *genapic, apic_default; +extern struct genapic *genapic; #endif diff --git a/trunk/include/asm-i386/i387.h b/trunk/include/asm-i386/i387.h index 434936c732d6..bc1d6edae1ed 100644 --- a/trunk/include/asm-i386/i387.h +++ b/trunk/include/asm-i386/i387.h @@ -76,9 +76,7 @@ static inline void __save_init_fpu( struct task_struct *tsk ) #define __unlazy_fpu( tsk ) do { \ if (task_thread_info(tsk)->status & TS_USEDFPU) \ - save_init_fpu( tsk ); \ - else \ - tsk->fpu_counter = 0; \ + save_init_fpu( tsk ); \ } while (0) #define __clear_fpu( tsk ) \ @@ -120,7 +118,6 @@ static inline void save_init_fpu( struct task_struct *tsk ) extern unsigned short get_fpu_cwd( struct task_struct *tsk ); extern unsigned short get_fpu_swd( struct task_struct *tsk ); extern unsigned short get_fpu_mxcsr( struct task_struct *tsk ); -extern asmlinkage void math_state_restore(void); /* * Signal frame handlers... diff --git a/trunk/include/asm-i386/io.h b/trunk/include/asm-i386/io.h index 86ff5e83be2f..68df0dc3ab8f 100644 --- a/trunk/include/asm-i386/io.h +++ b/trunk/include/asm-i386/io.h @@ -256,11 +256,11 @@ static inline void flush_write_buffers(void) #endif /* __KERNEL__ */ -#if defined(CONFIG_PARAVIRT) -#include +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:" #else - #define __SLOW_DOWN_IO "outb %%al,$0x80;" +#endif static inline void slow_down_io(void) { __asm__ __volatile__( @@ -271,8 +271,6 @@ static inline void slow_down_io(void) { : : ); } -#endif - #ifdef CONFIG_X86_NUMAQ extern void *xquad_portio; /* Where the IO area was mapped */ #define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port) diff --git a/trunk/include/asm-i386/irq.h b/trunk/include/asm-i386/irq.h index 11761cdaae19..331726b41128 100644 --- a/trunk/include/asm-i386/irq.h +++ b/trunk/include/asm-i386/irq.h @@ -37,13 +37,8 @@ static __inline__ int irq_canonicalize(int irq) extern int irqbalance_disable(char *str); #endif -extern void quirk_intel_irqbalance(void); - #ifdef CONFIG_HOTPLUG_CPU extern void fixup_irqs(cpumask_t map); #endif -void init_IRQ(void); -void __init native_init_IRQ(void); - #endif /* _ASM_IRQ_H */ diff --git a/trunk/include/asm-i386/irq_regs.h b/trunk/include/asm-i386/irq_regs.h index a1b3f7f594a2..3dd9c0b70270 100644 --- a/trunk/include/asm-i386/irq_regs.h +++ b/trunk/include/asm-i386/irq_regs.h @@ -1,27 +1 @@ -/* - * Per-cpu current frame pointer - the location of the last exception frame on - * the stack, stored in the PDA. - * - * Jeremy Fitzhardinge - */ -#ifndef _ASM_I386_IRQ_REGS_H -#define _ASM_I386_IRQ_REGS_H - -#include - -static inline struct pt_regs *get_irq_regs(void) -{ - return read_pda(irq_regs); -} - -static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) -{ - struct pt_regs *old_regs; - - old_regs = read_pda(irq_regs); - write_pda(irq_regs, new_regs); - - return old_regs; -} - -#endif /* _ASM_I386_IRQ_REGS_H */ +#include diff --git a/trunk/include/asm-i386/irqflags.h b/trunk/include/asm-i386/irqflags.h index 17b18cf4fe9d..e1bdb97c07fa 100644 --- a/trunk/include/asm-i386/irqflags.h +++ b/trunk/include/asm-i386/irqflags.h @@ -10,9 +10,6 @@ #ifndef _ASM_IRQFLAGS_H #define _ASM_IRQFLAGS_H -#ifdef CONFIG_PARAVIRT -#include -#else #ifndef __ASSEMBLY__ static inline unsigned long __raw_local_save_flags(void) @@ -28,6 +25,9 @@ static inline unsigned long __raw_local_save_flags(void) return flags; } +#define raw_local_save_flags(flags) \ + do { (flags) = __raw_local_save_flags(); } while (0) + static inline void raw_local_irq_restore(unsigned long flags) { __asm__ __volatile__( @@ -66,6 +66,18 @@ static inline void halt(void) __asm__ __volatile__("hlt": : :"memory"); } +static inline int raw_irqs_disabled_flags(unsigned long flags) +{ + return !(flags & (1 << 9)); +} + +static inline int raw_irqs_disabled(void) +{ + unsigned long flags = __raw_local_save_flags(); + + return raw_irqs_disabled_flags(flags); +} + /* * For spinlocks, etc: */ @@ -78,33 +90,9 @@ static inline unsigned long __raw_local_irq_save(void) return flags; } -#else -#define DISABLE_INTERRUPTS(clobbers) cli -#define ENABLE_INTERRUPTS(clobbers) sti -#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit -#define INTERRUPT_RETURN iret -#define GET_CR0_INTO_EAX movl %cr0, %eax -#endif /* __ASSEMBLY__ */ -#endif /* CONFIG_PARAVIRT */ - -#ifndef __ASSEMBLY__ -#define raw_local_save_flags(flags) \ - do { (flags) = __raw_local_save_flags(); } while (0) - #define raw_local_irq_save(flags) \ do { (flags) = __raw_local_irq_save(); } while (0) -static inline int raw_irqs_disabled_flags(unsigned long flags) -{ - return !(flags & (1 << 9)); -} - -static inline int raw_irqs_disabled(void) -{ - unsigned long flags = __raw_local_save_flags(); - - return raw_irqs_disabled_flags(flags); -} #endif /* __ASSEMBLY__ */ /* diff --git a/trunk/include/asm-i386/mach-default/setup_arch.h b/trunk/include/asm-i386/mach-default/setup_arch.h index 605e3ccb991b..fb42099e7bd4 100644 --- a/trunk/include/asm-i386/mach-default/setup_arch.h +++ b/trunk/include/asm-i386/mach-default/setup_arch.h @@ -2,6 +2,4 @@ /* no action for generic */ -#ifndef ARCH_SETUP #define ARCH_SETUP -#endif diff --git a/trunk/include/asm-i386/math_emu.h b/trunk/include/asm-i386/math_emu.h index a4b0aa3320e6..697673b555ce 100644 --- a/trunk/include/asm-i386/math_emu.h +++ b/trunk/include/asm-i386/math_emu.h @@ -21,7 +21,6 @@ struct info { long ___eax; long ___ds; long ___es; - long ___fs; long ___orig_eax; long ___eip; long ___cs; diff --git a/trunk/include/asm-i386/mmu_context.h b/trunk/include/asm-i386/mmu_context.h index 68ff102d6f5e..62b7bf184094 100644 --- a/trunk/include/asm-i386/mmu_context.h +++ b/trunk/include/asm-i386/mmu_context.h @@ -44,7 +44,7 @@ static inline void switch_mm(struct mm_struct *prev, * load the LDT, if the LDT is different: */ if (unlikely(prev->context.ldt != next->context.ldt)) - load_LDT_nolock(&next->context); + load_LDT_nolock(&next->context, cpu); } #ifdef CONFIG_SMP else { @@ -56,14 +56,14 @@ static inline void switch_mm(struct mm_struct *prev, * tlb flush IPI delivery. We must reload %cr3. */ load_cr3(next->pgd); - load_LDT_nolock(&next->context); + load_LDT_nolock(&next->context, cpu); } } #endif } -#define deactivate_mm(tsk, mm) \ - asm("movl %0,%%fs": :"r" (0)); +#define deactivate_mm(tsk, mm) \ + asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0)) #define activate_mm(prev, next) \ switch_mm((prev),(next),NULL) diff --git a/trunk/include/asm-i386/mmzone.h b/trunk/include/asm-i386/mmzone.h index 3503ad66945e..61b073322006 100644 --- a/trunk/include/asm-i386/mmzone.h +++ b/trunk/include/asm-i386/mmzone.h @@ -120,26 +120,13 @@ static inline int pfn_valid(int pfn) __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_low_pages(x) \ __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0) -#define alloc_bootmem_node(pgdat, x) \ -({ \ - struct pglist_data __attribute__ ((unused)) \ - *__alloc_bootmem_node__pgdat = (pgdat); \ - __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, \ - __pa(MAX_DMA_ADDRESS)); \ -}) -#define alloc_bootmem_pages_node(pgdat, x) \ -({ \ - struct pglist_data __attribute__ ((unused)) \ - *__alloc_bootmem_node__pgdat = (pgdat); \ - __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, \ - __pa(MAX_DMA_ADDRESS)) \ -}) -#define alloc_bootmem_low_pages_node(pgdat, x) \ -({ \ - struct pglist_data __attribute__ ((unused)) \ - *__alloc_bootmem_node__pgdat = (pgdat); \ - __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0); \ -}) +#define alloc_bootmem_node(ignore, x) \ + __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_pages_node(ignore, x) \ + __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_low_pages_node(ignore, x) \ + __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0) + #endif /* CONFIG_NEED_MULTIPLE_NODES */ #endif /* _ASM_MMZONE_H_ */ diff --git a/trunk/include/asm-i386/module.h b/trunk/include/asm-i386/module.h index 02f8f541cbe0..424661d25bd3 100644 --- a/trunk/include/asm-i386/module.h +++ b/trunk/include/asm-i386/module.h @@ -20,8 +20,6 @@ struct mod_arch_specific #define MODULE_PROC_FAMILY "586TSC " #elif defined CONFIG_M586MMX #define MODULE_PROC_FAMILY "586MMX " -#elif defined CONFIG_MCORE2 -#define MODULE_PROC_FAMILY "CORE2 " #elif defined CONFIG_M686 #define MODULE_PROC_FAMILY "686 " #elif defined CONFIG_MPENTIUMII @@ -62,12 +60,18 @@ struct mod_arch_specific #error unknown processor family #endif +#ifdef CONFIG_REGPARM +#define MODULE_REGPARM "REGPARM " +#else +#define MODULE_REGPARM "" +#endif + #ifdef CONFIG_4KSTACKS #define MODULE_STACKSIZE "4KSTACKS " #else #define MODULE_STACKSIZE "" #endif -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE #endif /* _ASM_I386_MODULE_H */ diff --git a/trunk/include/asm-i386/mpspec_def.h b/trunk/include/asm-i386/mpspec_def.h index 13bafb16e7af..76feedf85a8a 100644 --- a/trunk/include/asm-i386/mpspec_def.h +++ b/trunk/include/asm-i386/mpspec_def.h @@ -97,6 +97,7 @@ struct mpc_config_bus #define BUSTYPE_TC "TC" #define BUSTYPE_VME "VME" #define BUSTYPE_XPRESS "XPRESS" +#define BUSTYPE_NEC98 "NEC98" struct mpc_config_ioapic { @@ -181,6 +182,7 @@ enum mp_bustype { MP_BUS_EISA, MP_BUS_PCI, MP_BUS_MCA, + MP_BUS_NEC98 }; #endif diff --git a/trunk/include/asm-i386/msr.h b/trunk/include/asm-i386/msr.h index 5679d4993072..62b76cd96957 100644 --- a/trunk/include/asm-i386/msr.h +++ b/trunk/include/asm-i386/msr.h @@ -1,10 +1,6 @@ #ifndef __ASM_MSR_H #define __ASM_MSR_H -#ifdef CONFIG_PARAVIRT -#include -#else - /* * Access to machine-specific registers (available on 586 and better only) * Note: the rd* operations modify the parameters directly (without using @@ -81,7 +77,6 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val) __asm__ __volatile__("rdpmc" \ : "=a" (low), "=d" (high) \ : "c" (counter)) -#endif /* !CONFIG_PARAVIRT */ /* symbolic names for some interesting MSRs */ /* Intel defined MSRs. */ @@ -146,10 +141,6 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val) #define MSR_IA32_MC0_ADDR 0x402 #define MSR_IA32_MC0_MISC 0x403 -#define MSR_IA32_PEBS_ENABLE 0x3f1 -#define MSR_IA32_DS_AREA 0x600 -#define MSR_IA32_PERF_CAPABILITIES 0x345 - /* Pentium IV performance counter MSRs */ #define MSR_P4_BPU_PERFCTR0 0x300 #define MSR_P4_BPU_PERFCTR1 0x301 @@ -293,13 +284,4 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val) #define MSR_TMTA_LRTI_READOUT 0x80868018 #define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a -/* Intel Core-based CPU performance counters */ -#define MSR_CORE_PERF_FIXED_CTR0 0x309 -#define MSR_CORE_PERF_FIXED_CTR1 0x30a -#define MSR_CORE_PERF_FIXED_CTR2 0x30b -#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x38d -#define MSR_CORE_PERF_GLOBAL_STATUS 0x38e -#define MSR_CORE_PERF_GLOBAL_CTRL 0x38f -#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x390 - #endif /* __ASM_MSR_H */ diff --git a/trunk/include/asm-i386/nmi.h b/trunk/include/asm-i386/nmi.h index b04333ea6f31..269d315719ca 100644 --- a/trunk/include/asm-i386/nmi.h +++ b/trunk/include/asm-i386/nmi.h @@ -5,9 +5,6 @@ #define ASM_NMI_H #include -#include - -#ifdef ARCH_HAS_NMI_WATCHDOG /** * do_nmi_callback @@ -45,9 +42,4 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, void __user *, size_t *, loff_t *); extern int unknown_nmi_panic; -void __trigger_all_cpu_backtrace(void); -#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() - -#endif - #endif /* ASM_NMI_H */ diff --git a/trunk/include/asm-i386/page.h b/trunk/include/asm-i386/page.h index fd3f64ace248..f5bf544c729a 100644 --- a/trunk/include/asm-i386/page.h +++ b/trunk/include/asm-i386/page.h @@ -52,7 +52,6 @@ typedef struct { unsigned long long pgprot; } pgprot_t; #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) #define __pmd(x) ((pmd_t) { (x) } ) #define HPAGE_SHIFT 21 -#include #else typedef struct { unsigned long pte_low; } pte_t; typedef struct { unsigned long pgd; } pgd_t; @@ -60,7 +59,6 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define boot_pte_t pte_t /* or would you rather have a typedef */ #define pte_val(x) ((x).pte_low) #define HPAGE_SHIFT 22 -#include #endif #define PTE_MASK PAGE_MASK @@ -114,18 +112,18 @@ extern int page_is_ram(unsigned long pagenr); #ifdef __ASSEMBLY__ #define __PAGE_OFFSET CONFIG_PAGE_OFFSET +#define __PHYSICAL_START CONFIG_PHYSICAL_START #else #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET) +#define __PHYSICAL_START ((unsigned long)CONFIG_PHYSICAL_START) #endif +#define __KERNEL_START (__PAGE_OFFSET + __PHYSICAL_START) #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) #define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -/* __pa_symbol should be used for C visible symbols. - This seems to be the official gcc blessed way to do such arithmetic. */ -#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0)) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #ifdef CONFIG_FLATMEM diff --git a/trunk/include/asm-i386/param.h b/trunk/include/asm-i386/param.h index 21b32466fcdc..745dc5bd0fbc 100644 --- a/trunk/include/asm-i386/param.h +++ b/trunk/include/asm-i386/param.h @@ -18,5 +18,6 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#define COMMAND_LINE_SIZE 256 #endif diff --git a/trunk/include/asm-i386/paravirt.h b/trunk/include/asm-i386/paravirt.h deleted file mode 100644 index 9f06265065f4..000000000000 --- a/trunk/include/asm-i386/paravirt.h +++ /dev/null @@ -1,505 +0,0 @@ -#ifndef __ASM_PARAVIRT_H -#define __ASM_PARAVIRT_H -/* Various instructions on x86 need to be replaced for - * para-virtualization: those hooks are defined here. */ -#include -#include -#include - -#ifdef CONFIG_PARAVIRT -/* These are the most performance critical ops, so we want to be able to patch - * callers */ -#define PARAVIRT_IRQ_DISABLE 0 -#define PARAVIRT_IRQ_ENABLE 1 -#define PARAVIRT_RESTORE_FLAGS 2 -#define PARAVIRT_SAVE_FLAGS 3 -#define PARAVIRT_SAVE_FLAGS_IRQ_DISABLE 4 -#define PARAVIRT_INTERRUPT_RETURN 5 -#define PARAVIRT_STI_SYSEXIT 6 - -/* Bitmask of what can be clobbered: usually at least eax. */ -#define CLBR_NONE 0x0 -#define CLBR_EAX 0x1 -#define CLBR_ECX 0x2 -#define CLBR_EDX 0x4 -#define CLBR_ANY 0x7 - -#ifndef __ASSEMBLY__ -struct thread_struct; -struct Xgt_desc_struct; -struct tss_struct; -struct mm_struct; -struct paravirt_ops -{ - unsigned int kernel_rpl; - int paravirt_enabled; - const char *name; - - /* - * Patch may replace one of the defined code sequences with arbitrary - * code, subject to the same register constraints. This generally - * means the code is not free to clobber any registers other than EAX. - * The patch function should return the number of bytes of code - * generated, as we nop pad the rest in generic code. - */ - unsigned (*patch)(u8 type, u16 clobber, void *firstinsn, unsigned len); - - void (*arch_setup)(void); - char *(*memory_setup)(void); - void (*init_IRQ)(void); - - void (*banner)(void); - - unsigned long (*get_wallclock)(void); - int (*set_wallclock)(unsigned long); - void (*time_init)(void); - - /* All the function pointers here are declared as "fastcall" - so that we get a specific register-based calling - convention. This makes it easier to implement inline - assembler replacements. */ - - void (fastcall *cpuid)(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx); - - unsigned long (fastcall *get_debugreg)(int regno); - void (fastcall *set_debugreg)(int regno, unsigned long value); - - void (fastcall *clts)(void); - - unsigned long (fastcall *read_cr0)(void); - void (fastcall *write_cr0)(unsigned long); - - unsigned long (fastcall *read_cr2)(void); - void (fastcall *write_cr2)(unsigned long); - - unsigned long (fastcall *read_cr3)(void); - void (fastcall *write_cr3)(unsigned long); - - unsigned long (fastcall *read_cr4_safe)(void); - unsigned long (fastcall *read_cr4)(void); - void (fastcall *write_cr4)(unsigned long); - - unsigned long (fastcall *save_fl)(void); - void (fastcall *restore_fl)(unsigned long); - void (fastcall *irq_disable)(void); - void (fastcall *irq_enable)(void); - void (fastcall *safe_halt)(void); - void (fastcall *halt)(void); - void (fastcall *wbinvd)(void); - - /* err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ - u64 (fastcall *read_msr)(unsigned int msr, int *err); - int (fastcall *write_msr)(unsigned int msr, u64 val); - - u64 (fastcall *read_tsc)(void); - u64 (fastcall *read_pmc)(void); - - void (fastcall *load_tr_desc)(void); - void (fastcall *load_gdt)(const struct Xgt_desc_struct *); - void (fastcall *load_idt)(const struct Xgt_desc_struct *); - void (fastcall *store_gdt)(struct Xgt_desc_struct *); - void (fastcall *store_idt)(struct Xgt_desc_struct *); - void (fastcall *set_ldt)(const void *desc, unsigned entries); - unsigned long (fastcall *store_tr)(void); - void (fastcall *load_tls)(struct thread_struct *t, unsigned int cpu); - void (fastcall *write_ldt_entry)(void *dt, int entrynum, - u32 low, u32 high); - void (fastcall *write_gdt_entry)(void *dt, int entrynum, - u32 low, u32 high); - void (fastcall *write_idt_entry)(void *dt, int entrynum, - u32 low, u32 high); - void (fastcall *load_esp0)(struct tss_struct *tss, - struct thread_struct *thread); - - void (fastcall *set_iopl_mask)(unsigned mask); - - void (fastcall *io_delay)(void); - void (*const_udelay)(unsigned long loops); - -#ifdef CONFIG_X86_LOCAL_APIC - void (fastcall *apic_write)(unsigned long reg, unsigned long v); - void (fastcall *apic_write_atomic)(unsigned long reg, unsigned long v); - unsigned long (fastcall *apic_read)(unsigned long reg); -#endif - - void (fastcall *flush_tlb_user)(void); - void (fastcall *flush_tlb_kernel)(void); - void (fastcall *flush_tlb_single)(u32 addr); - - void (fastcall *set_pte)(pte_t *ptep, pte_t pteval); - void (fastcall *set_pte_at)(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval); - void (fastcall *set_pmd)(pmd_t *pmdp, pmd_t pmdval); - void (fastcall *pte_update)(struct mm_struct *mm, u32 addr, pte_t *ptep); - void (fastcall *pte_update_defer)(struct mm_struct *mm, u32 addr, pte_t *ptep); -#ifdef CONFIG_X86_PAE - void (fastcall *set_pte_atomic)(pte_t *ptep, pte_t pteval); - void (fastcall *set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); - void (fastcall *set_pud)(pud_t *pudp, pud_t pudval); - void (fastcall *pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); - void (fastcall *pmd_clear)(pmd_t *pmdp); -#endif - - /* These two are jmp to, not actually called. */ - void (fastcall *irq_enable_sysexit)(void); - void (fastcall *iret)(void); -}; - -/* Mark a paravirt probe function. */ -#define paravirt_probe(fn) \ - static asmlinkage void (*__paravirtprobe_##fn)(void) __attribute_used__ \ - __attribute__((__section__(".paravirtprobe"))) = fn - -extern struct paravirt_ops paravirt_ops; - -#define paravirt_enabled() (paravirt_ops.paravirt_enabled) - -static inline void load_esp0(struct tss_struct *tss, - struct thread_struct *thread) -{ - paravirt_ops.load_esp0(tss, thread); -} - -#define ARCH_SETUP paravirt_ops.arch_setup(); -static inline unsigned long get_wallclock(void) -{ - return paravirt_ops.get_wallclock(); -} - -static inline int set_wallclock(unsigned long nowtime) -{ - return paravirt_ops.set_wallclock(nowtime); -} - -static inline void do_time_init(void) -{ - return paravirt_ops.time_init(); -} - -/* The paravirtualized CPUID instruction. */ -static inline void __cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - paravirt_ops.cpuid(eax, ebx, ecx, edx); -} - -/* - * These special macros can be used to get or set a debugging register - */ -#define get_debugreg(var, reg) var = paravirt_ops.get_debugreg(reg) -#define set_debugreg(val, reg) paravirt_ops.set_debugreg(reg, val) - -#define clts() paravirt_ops.clts() - -#define read_cr0() paravirt_ops.read_cr0() -#define write_cr0(x) paravirt_ops.write_cr0(x) - -#define read_cr2() paravirt_ops.read_cr2() -#define write_cr2(x) paravirt_ops.write_cr2(x) - -#define read_cr3() paravirt_ops.read_cr3() -#define write_cr3(x) paravirt_ops.write_cr3(x) - -#define read_cr4() paravirt_ops.read_cr4() -#define read_cr4_safe(x) paravirt_ops.read_cr4_safe() -#define write_cr4(x) paravirt_ops.write_cr4(x) - -static inline void raw_safe_halt(void) -{ - paravirt_ops.safe_halt(); -} - -static inline void halt(void) -{ - paravirt_ops.safe_halt(); -} -#define wbinvd() paravirt_ops.wbinvd() - -#define get_kernel_rpl() (paravirt_ops.kernel_rpl) - -#define rdmsr(msr,val1,val2) do { \ - int _err; \ - u64 _l = paravirt_ops.read_msr(msr,&_err); \ - val1 = (u32)_l; \ - val2 = _l >> 32; \ -} while(0) - -#define wrmsr(msr,val1,val2) do { \ - u64 _l = ((u64)(val2) << 32) | (val1); \ - paravirt_ops.write_msr((msr), _l); \ -} while(0) - -#define rdmsrl(msr,val) do { \ - int _err; \ - val = paravirt_ops.read_msr((msr),&_err); \ -} while(0) - -#define wrmsrl(msr,val) (paravirt_ops.write_msr((msr),(val))) -#define wrmsr_safe(msr,a,b) ({ \ - u64 _l = ((u64)(b) << 32) | (a); \ - paravirt_ops.write_msr((msr),_l); \ -}) - -/* rdmsr with exception handling */ -#define rdmsr_safe(msr,a,b) ({ \ - int _err; \ - u64 _l = paravirt_ops.read_msr(msr,&_err); \ - (*a) = (u32)_l; \ - (*b) = _l >> 32; \ - _err; }) - -#define rdtsc(low,high) do { \ - u64 _l = paravirt_ops.read_tsc(); \ - low = (u32)_l; \ - high = _l >> 32; \ -} while(0) - -#define rdtscl(low) do { \ - u64 _l = paravirt_ops.read_tsc(); \ - low = (int)_l; \ -} while(0) - -#define rdtscll(val) (val = paravirt_ops.read_tsc()) - -#define write_tsc(val1,val2) wrmsr(0x10, val1, val2) - -#define rdpmc(counter,low,high) do { \ - u64 _l = paravirt_ops.read_pmc(); \ - low = (u32)_l; \ - high = _l >> 32; \ -} while(0) - -#define load_TR_desc() (paravirt_ops.load_tr_desc()) -#define load_gdt(dtr) (paravirt_ops.load_gdt(dtr)) -#define load_idt(dtr) (paravirt_ops.load_idt(dtr)) -#define set_ldt(addr, entries) (paravirt_ops.set_ldt((addr), (entries))) -#define store_gdt(dtr) (paravirt_ops.store_gdt(dtr)) -#define store_idt(dtr) (paravirt_ops.store_idt(dtr)) -#define store_tr(tr) ((tr) = paravirt_ops.store_tr()) -#define load_TLS(t,cpu) (paravirt_ops.load_tls((t),(cpu))) -#define write_ldt_entry(dt, entry, low, high) \ - (paravirt_ops.write_ldt_entry((dt), (entry), (low), (high))) -#define write_gdt_entry(dt, entry, low, high) \ - (paravirt_ops.write_gdt_entry((dt), (entry), (low), (high))) -#define write_idt_entry(dt, entry, low, high) \ - (paravirt_ops.write_idt_entry((dt), (entry), (low), (high))) -#define set_iopl_mask(mask) (paravirt_ops.set_iopl_mask(mask)) - -/* The paravirtualized I/O functions */ -static inline void slow_down_io(void) { - paravirt_ops.io_delay(); -#ifdef REALLY_SLOW_IO - paravirt_ops.io_delay(); - paravirt_ops.io_delay(); - paravirt_ops.io_delay(); -#endif -} - -#ifdef CONFIG_X86_LOCAL_APIC -/* - * Basic functions accessing APICs. - */ -static inline void apic_write(unsigned long reg, unsigned long v) -{ - paravirt_ops.apic_write(reg,v); -} - -static inline void apic_write_atomic(unsigned long reg, unsigned long v) -{ - paravirt_ops.apic_write_atomic(reg,v); -} - -static inline unsigned long apic_read(unsigned long reg) -{ - return paravirt_ops.apic_read(reg); -} -#endif - - -#define __flush_tlb() paravirt_ops.flush_tlb_user() -#define __flush_tlb_global() paravirt_ops.flush_tlb_kernel() -#define __flush_tlb_single(addr) paravirt_ops.flush_tlb_single(addr) - -static inline void set_pte(pte_t *ptep, pte_t pteval) -{ - paravirt_ops.set_pte(ptep, pteval); -} - -static inline void set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval) -{ - paravirt_ops.set_pte_at(mm, addr, ptep, pteval); -} - -static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) -{ - paravirt_ops.set_pmd(pmdp, pmdval); -} - -static inline void pte_update(struct mm_struct *mm, u32 addr, pte_t *ptep) -{ - paravirt_ops.pte_update(mm, addr, ptep); -} - -static inline void pte_update_defer(struct mm_struct *mm, u32 addr, pte_t *ptep) -{ - paravirt_ops.pte_update_defer(mm, addr, ptep); -} - -#ifdef CONFIG_X86_PAE -static inline void set_pte_atomic(pte_t *ptep, pte_t pteval) -{ - paravirt_ops.set_pte_atomic(ptep, pteval); -} - -static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) -{ - paravirt_ops.set_pte_present(mm, addr, ptep, pte); -} - -static inline void set_pud(pud_t *pudp, pud_t pudval) -{ - paravirt_ops.set_pud(pudp, pudval); -} - -static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - paravirt_ops.pte_clear(mm, addr, ptep); -} - -static inline void pmd_clear(pmd_t *pmdp) -{ - paravirt_ops.pmd_clear(pmdp); -} -#endif - -/* These all sit in the .parainstructions section to tell us what to patch. */ -struct paravirt_patch { - u8 *instr; /* original instructions */ - u8 instrtype; /* type of this instruction */ - u8 len; /* length of original instruction */ - u16 clobbers; /* what registers you may clobber */ -}; - -#define paravirt_alt(insn_string, typenum, clobber) \ - "771:\n\t" insn_string "\n" "772:\n" \ - ".pushsection .parainstructions,\"a\"\n" \ - " .long 771b\n" \ - " .byte " __stringify(typenum) "\n" \ - " .byte 772b-771b\n" \ - " .short " __stringify(clobber) "\n" \ - ".popsection" - -static inline unsigned long __raw_local_save_flags(void) -{ - unsigned long f; - - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%1;" - "popl %%edx; popl %%ecx", - PARAVIRT_SAVE_FLAGS, CLBR_NONE) - : "=a"(f): "m"(paravirt_ops.save_fl) - : "memory", "cc"); - return f; -} - -static inline void raw_local_irq_restore(unsigned long f) -{ - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%1;" - "popl %%edx; popl %%ecx", - PARAVIRT_RESTORE_FLAGS, CLBR_EAX) - : "=a"(f) : "m" (paravirt_ops.restore_fl), "0"(f) - : "memory", "cc"); -} - -static inline void raw_local_irq_disable(void) -{ - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%0;" - "popl %%edx; popl %%ecx", - PARAVIRT_IRQ_DISABLE, CLBR_EAX) - : : "m" (paravirt_ops.irq_disable) - : "memory", "eax", "cc"); -} - -static inline void raw_local_irq_enable(void) -{ - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%0;" - "popl %%edx; popl %%ecx", - PARAVIRT_IRQ_ENABLE, CLBR_EAX) - : : "m" (paravirt_ops.irq_enable) - : "memory", "eax", "cc"); -} - -static inline unsigned long __raw_local_irq_save(void) -{ - unsigned long f; - - __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" - "call *%1; pushl %%eax;" - "call *%2; popl %%eax;" - "popl %%edx; popl %%ecx", - PARAVIRT_SAVE_FLAGS_IRQ_DISABLE, - CLBR_NONE) - : "=a"(f) - : "m" (paravirt_ops.save_fl), - "m" (paravirt_ops.irq_disable) - : "memory", "cc"); - return f; -} - -#define CLI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;" \ - "call *paravirt_ops+%c[irq_disable];" \ - "popl %%edx; popl %%ecx", \ - PARAVIRT_IRQ_DISABLE, CLBR_EAX) - -#define STI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;" \ - "call *paravirt_ops+%c[irq_enable];" \ - "popl %%edx; popl %%ecx", \ - PARAVIRT_IRQ_ENABLE, CLBR_EAX) -#define CLI_STI_CLOBBERS , "%eax" -#define CLI_STI_INPUT_ARGS \ - , \ - [irq_disable] "i" (offsetof(struct paravirt_ops, irq_disable)), \ - [irq_enable] "i" (offsetof(struct paravirt_ops, irq_enable)) - -#else /* __ASSEMBLY__ */ - -#define PARA_PATCH(ptype, clobbers, ops) \ -771:; \ - ops; \ -772:; \ - .pushsection .parainstructions,"a"; \ - .long 771b; \ - .byte ptype; \ - .byte 772b-771b; \ - .short clobbers; \ - .popsection - -#define INTERRUPT_RETURN \ - PARA_PATCH(PARAVIRT_INTERRUPT_RETURN, CLBR_ANY, \ - jmp *%cs:paravirt_ops+PARAVIRT_iret) - -#define DISABLE_INTERRUPTS(clobbers) \ - PARA_PATCH(PARAVIRT_IRQ_DISABLE, clobbers, \ - pushl %ecx; pushl %edx; \ - call *paravirt_ops+PARAVIRT_irq_disable; \ - popl %edx; popl %ecx) \ - -#define ENABLE_INTERRUPTS(clobbers) \ - PARA_PATCH(PARAVIRT_IRQ_ENABLE, clobbers, \ - pushl %ecx; pushl %edx; \ - call *%cs:paravirt_ops+PARAVIRT_irq_enable; \ - popl %edx; popl %ecx) - -#define ENABLE_INTERRUPTS_SYSEXIT \ - PARA_PATCH(PARAVIRT_STI_SYSEXIT, CLBR_ANY, \ - jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit) - -#define GET_CR0_INTO_EAX \ - call *paravirt_ops+PARAVIRT_read_cr0 - -#endif /* __ASSEMBLY__ */ -#endif /* CONFIG_PARAVIRT */ -#endif /* __ASM_PARAVIRT_H */ diff --git a/trunk/include/asm-i386/pda.h b/trunk/include/asm-i386/pda.h deleted file mode 100644 index 2ba2736aa109..000000000000 --- a/trunk/include/asm-i386/pda.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - Per-processor Data Areas - Jeremy Fitzhardinge 2006 - Based on asm-x86_64/pda.h by Andi Kleen. - */ -#ifndef _I386_PDA_H -#define _I386_PDA_H - -#include -#include - -struct i386_pda -{ - struct i386_pda *_pda; /* pointer to self */ - - int cpu_number; - struct task_struct *pcurrent; /* current process */ - struct pt_regs *irq_regs; -}; - -extern struct i386_pda *_cpu_pda[]; - -#define cpu_pda(i) (_cpu_pda[i]) - -#define pda_offset(field) offsetof(struct i386_pda, field) - -extern void __bad_pda_field(void); - -/* This variable is never instantiated. It is only used as a stand-in - for the real per-cpu PDA memory, so that gcc can understand what - memory operations the inline asms() below are performing. This - eliminates the need to make the asms volatile or have memory - clobbers, so gcc can readily analyse them. */ -extern struct i386_pda _proxy_pda; - -#define pda_to_op(op,field,val) \ - do { \ - typedef typeof(_proxy_pda.field) T__; \ - if (0) { T__ tmp__; tmp__ = (val); } \ - switch (sizeof(_proxy_pda.field)) { \ - case 1: \ - asm(op "b %1,%%gs:%c2" \ - : "+m" (_proxy_pda.field) \ - :"ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - case 2: \ - asm(op "w %1,%%gs:%c2" \ - : "+m" (_proxy_pda.field) \ - :"ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - case 4: \ - asm(op "l %1,%%gs:%c2" \ - : "+m" (_proxy_pda.field) \ - :"ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - default: __bad_pda_field(); \ - } \ - } while (0) - -#define pda_from_op(op,field) \ - ({ \ - typeof(_proxy_pda.field) ret__; \ - switch (sizeof(_proxy_pda.field)) { \ - case 1: \ - asm(op "b %%gs:%c1,%0" \ - : "=r" (ret__) \ - : "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 2: \ - asm(op "w %%gs:%c1,%0" \ - : "=r" (ret__) \ - : "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 4: \ - asm(op "l %%gs:%c1,%0" \ - : "=r" (ret__) \ - : "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - default: __bad_pda_field(); \ - } \ - ret__; }) - -/* Return a pointer to a pda field */ -#define pda_addr(field) \ - ((typeof(_proxy_pda.field) *)((unsigned char *)read_pda(_pda) + \ - pda_offset(field))) - -#define read_pda(field) pda_from_op("mov",field) -#define write_pda(field,val) pda_to_op("mov",field,val) -#define add_pda(field,val) pda_to_op("add",field,val) -#define sub_pda(field,val) pda_to_op("sub",field,val) -#define or_pda(field,val) pda_to_op("or",field,val) - -#endif /* _I386_PDA_H */ diff --git a/trunk/include/asm-i386/percpu.h b/trunk/include/asm-i386/percpu.h index 510ae1d3486c..5764afa4b6a4 100644 --- a/trunk/include/asm-i386/percpu.h +++ b/trunk/include/asm-i386/percpu.h @@ -1,31 +1,6 @@ #ifndef __ARCH_I386_PERCPU__ #define __ARCH_I386_PERCPU__ -#ifndef __ASSEMBLY__ #include -#else - -/* - * PER_CPU finds an address of a per-cpu variable. - * - * Args: - * var - variable name - * cpu - 32bit register containing the current CPU number - * - * The resulting address is stored in the "cpu" argument. - * - * Example: - * PER_CPU(cpu_gdt_descr, %ebx) - */ -#ifdef CONFIG_SMP -#define PER_CPU(var, cpu) \ - movl __per_cpu_offset(,cpu,4), cpu; \ - addl $per_cpu__/**/var, cpu; -#else /* ! SMP */ -#define PER_CPU(var, cpu) \ - movl $per_cpu__/**/var, cpu; -#endif /* SMP */ - -#endif /* !__ASSEMBLY__ */ #endif /* __ARCH_I386_PERCPU__ */ diff --git a/trunk/include/asm-i386/pgtable-2level.h b/trunk/include/asm-i386/pgtable-2level.h index 38c3fcc0676d..8d8d3b9ecdb0 100644 --- a/trunk/include/asm-i386/pgtable-2level.h +++ b/trunk/include/asm-i386/pgtable-2level.h @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_2LEVEL_H #define _I386_PGTABLE_2LEVEL_H +#include + #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) #define pgd_ERROR(e) \ @@ -11,19 +13,17 @@ * within a page table are directly modified. Thus, the following * hook is made available. */ -#ifndef CONFIG_PARAVIRT #define set_pte(pteptr, pteval) (*(pteptr) = pteval) #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) -#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) -#endif - #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) #define set_pte_present(mm,addr,ptep,pteval) set_pte_at(mm,addr,ptep,pteval) +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) #define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define raw_ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0)) +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +#define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0)) #define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_none(x) (!(x).pte_low) diff --git a/trunk/include/asm-i386/pgtable-3level.h b/trunk/include/asm-i386/pgtable-3level.h index 7a2318f38303..c2d701ea35be 100644 --- a/trunk/include/asm-i386/pgtable-3level.h +++ b/trunk/include/asm-i386/pgtable-3level.h @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_3LEVEL_H #define _I386_PGTABLE_3LEVEL_H +#include + /* * Intel Physical Address Extension (PAE) Mode - three-level page * tables on PPro+ CPUs. @@ -42,7 +44,6 @@ static inline int pte_exec_kernel(pte_t pte) return pte_x(pte); } -#ifndef CONFIG_PARAVIRT /* Rules for using set_pte: the pte being assigned *must* be * either not present or in a state where the hardware will * not attempt to update the pte. In places where this is @@ -79,6 +80,25 @@ static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte #define set_pud(pudptr,pudval) \ (*(pudptr) = (pudval)) +/* + * Pentium-II erratum A13: in PAE mode we explicitly have to flush + * the TLB via cr3 if the top-level pgd is changed... + * We do not let the generic code free and clear pgd entries due to + * this erratum. + */ +static inline void pud_clear (pud_t * pud) { } + +#define pud_page(pud) \ +((struct page *) __va(pud_val(pud) & PAGE_MASK)) + +#define pud_page_vaddr(pud) \ +((unsigned long) __va(pud_val(pud) & PAGE_MASK)) + + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ + pmd_index(address)) + /* * For PTEs and PDEs, we must clear the P-bit first when clearing a page table * entry, so clear the bottom half first and enforce ordering with a compiler @@ -98,28 +118,9 @@ static inline void pmd_clear(pmd_t *pmd) smp_wmb(); *(tmp + 1) = 0; } -#endif - -/* - * Pentium-II erratum A13: in PAE mode we explicitly have to flush - * the TLB via cr3 if the top-level pgd is changed... - * We do not let the generic code free and clear pgd entries due to - * this erratum. - */ -static inline void pud_clear (pud_t * pud) { } - -#define pud_page(pud) \ -((struct page *) __va(pud_val(pud) & PAGE_MASK)) - -#define pud_page_vaddr(pud) \ -((unsigned long) __va(pud_val(pud) & PAGE_MASK)) - - -/* Find an entry in the second-level page table.. */ -#define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ - pmd_index(address)) -static inline pte_t raw_ptep_get_and_clear(pte_t *ptep) +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t res; diff --git a/trunk/include/asm-i386/pgtable.h b/trunk/include/asm-i386/pgtable.h index e6a4723f0eb1..7d398f493dde 100644 --- a/trunk/include/asm-i386/pgtable.h +++ b/trunk/include/asm-i386/pgtable.h @@ -15,7 +15,6 @@ #include #include #include -#include #ifndef _I386_BITOPS_H #include @@ -35,14 +34,14 @@ struct vm_area_struct; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) extern unsigned long empty_zero_page[1024]; extern pgd_t swapper_pg_dir[1024]; -extern struct kmem_cache *pgd_cache; -extern struct kmem_cache *pmd_cache; +extern kmem_cache_t *pgd_cache; +extern kmem_cache_t *pmd_cache; extern spinlock_t pgd_lock; extern struct page *pgd_list; -void pmd_ctor(void *, struct kmem_cache *, unsigned long); -void pgd_ctor(void *, struct kmem_cache *, unsigned long); -void pgd_dtor(void *, struct kmem_cache *, unsigned long); +void pmd_ctor(void *, kmem_cache_t *, unsigned long); +void pgd_ctor(void *, kmem_cache_t *, unsigned long); +void pgd_dtor(void *, kmem_cache_t *, unsigned long); void pgtable_cache_init(void); void paging_init(void); @@ -247,7 +246,6 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p # include #endif -#ifndef CONFIG_PARAVIRT /* * Rules for using pte_update - it must be called after any PTE update which * has not been done using the set_pte / clear_pte interfaces. It is used by @@ -263,7 +261,7 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p */ #define pte_update(mm, addr, ptep) do { } while (0) #define pte_update_defer(mm, addr, ptep) do { } while (0) -#endif + /* * We only update the dirty/accessed state if we set @@ -277,7 +275,7 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p do { \ if (dirty) { \ (ptep)->pte_low = (entry).pte_low; \ - pte_update_defer((vma)->vm_mm, (address), (ptep)); \ + pte_update_defer((vma)->vm_mm, (addr), (ptep)); \ flush_tlb_page(vma, address); \ } \ } while (0) @@ -307,7 +305,7 @@ do { \ __dirty = pte_dirty(*(ptep)); \ if (__dirty) { \ clear_bit(_PAGE_BIT_DIRTY, &(ptep)->pte_low); \ - pte_update_defer((vma)->vm_mm, (address), (ptep)); \ + pte_update_defer((vma)->vm_mm, (addr), (ptep)); \ flush_tlb_page(vma, address); \ } \ __dirty; \ @@ -320,20 +318,12 @@ do { \ __young = pte_young(*(ptep)); \ if (__young) { \ clear_bit(_PAGE_BIT_ACCESSED, &(ptep)->pte_low); \ - pte_update_defer((vma)->vm_mm, (address), (ptep)); \ + pte_update_defer((vma)->vm_mm, (addr), (ptep)); \ flush_tlb_page(vma, address); \ } \ __young; \ }) -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR -static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - pte_t pte = raw_ptep_get_and_clear(ptep); - pte_update(mm, addr, ptep); - return pte; -} - #define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) { diff --git a/trunk/include/asm-i386/processor.h b/trunk/include/asm-i386/processor.h index a52d65440429..e0ddca94d50c 100644 --- a/trunk/include/asm-i386/processor.h +++ b/trunk/include/asm-i386/processor.h @@ -20,7 +20,6 @@ #include #include #include -#include /* flag for disabling the tsc */ extern int tsc_disable; @@ -73,7 +72,6 @@ struct cpuinfo_x86 { #endif unsigned char x86_max_cores; /* cpuid returned max cores value */ unsigned char apicid; - unsigned short x86_clflush_size; #ifdef CONFIG_SMP unsigned char booted_cores; /* number of cores as seen by OS */ __u8 phys_proc_id; /* Physical processor id. */ @@ -113,8 +111,6 @@ extern struct cpuinfo_x86 cpu_data[]; extern int cpu_llc_id[NR_CPUS]; extern char ignore_fpu_irq; -void __init cpu_detect(struct cpuinfo_x86 *c); - extern void identify_cpu(struct cpuinfo_x86 *); extern void print_cpu_info(struct cpuinfo_x86 *); extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); @@ -147,8 +143,8 @@ static inline void detect_ht(struct cpuinfo_x86 *c) {} #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ -static inline fastcall void native_cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) +static inline void __cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) { /* ecx is often an input as well as an output. */ __asm__("cpuid" @@ -159,6 +155,59 @@ static inline fastcall void native_cpuid(unsigned int *eax, unsigned int *ebx, : "0" (*eax), "2" (*ecx)); } +/* + * Generic CPUID function + * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx + * resulting in stale register contents being returned. + */ +static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) +{ + *eax = op; + *ecx = 0; + __cpuid(eax, ebx, ecx, edx); +} + +/* Some CPUID calls want 'count' to be placed in ecx */ +static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, + int *edx) +{ + *eax = op; + *ecx = count; + __cpuid(eax, ebx, ecx, edx); +} + +/* + * CPUID functions returning a single datum + */ +static inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return eax; +} +static inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return ebx; +} +static inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return ecx; +} +static inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return edx; +} + #define load_cr3(pgdir) write_cr3(__pa(pgdir)) /* @@ -424,7 +473,6 @@ struct thread_struct { .vm86_info = NULL, \ .sysenter_cs = __KERNEL_CS, \ .io_bitmap_ptr = NULL, \ - .gs = __KERNEL_PDA, \ } /* @@ -441,9 +489,18 @@ struct thread_struct { .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ } +static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) +{ + tss->esp0 = thread->esp0; + /* This can only happen when SEP is enabled, no need to test "SEP"arately */ + if (unlikely(tss->ss1 != thread->sysenter_cs)) { + tss->ss1 = thread->sysenter_cs; + wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); + } +} + #define start_thread(regs, new_eip, new_esp) do { \ - __asm__("movl %0,%%fs": :"r" (0)); \ - regs->xgs = 0; \ + __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \ set_fs(USER_DS); \ regs->xds = __USER_DS; \ regs->xes = __USER_DS; \ @@ -453,6 +510,33 @@ struct thread_struct { regs->esp = new_esp; \ } while (0) +/* + * These special macros can be used to get or set a debugging register + */ +#define get_debugreg(var, register) \ + __asm__("movl %%db" #register ", %0" \ + :"=r" (var)) +#define set_debugreg(value, register) \ + __asm__("movl %0,%%db" #register \ + : /* no output */ \ + :"r" (value)) + +/* + * Set IOPL bits in EFLAGS from given mask + */ +static inline void set_iopl_mask(unsigned mask) +{ + unsigned int reg; + __asm__ __volatile__ ("pushfl;" + "popl %0;" + "andl %1, %0;" + "orl %2, %0;" + "pushl %0;" + "popfl" + : "=&r" (reg) + : "i" (~X86_EFLAGS_IOPL), "r" (mask)); +} + /* Forward declaration, a strange C thing */ struct task_struct; struct mm_struct; @@ -544,105 +628,6 @@ static inline void rep_nop(void) #define cpu_relax() rep_nop() -#ifdef CONFIG_PARAVIRT -#include -#else -#define paravirt_enabled() 0 -#define __cpuid native_cpuid - -static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) -{ - tss->esp0 = thread->esp0; - /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->ss1 != thread->sysenter_cs)) { - tss->ss1 = thread->sysenter_cs; - wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); - } -} - -/* - * These special macros can be used to get or set a debugging register - */ -#define get_debugreg(var, register) \ - __asm__("movl %%db" #register ", %0" \ - :"=r" (var)) -#define set_debugreg(value, register) \ - __asm__("movl %0,%%db" #register \ - : /* no output */ \ - :"r" (value)) - -#define set_iopl_mask native_set_iopl_mask -#endif /* CONFIG_PARAVIRT */ - -/* - * Set IOPL bits in EFLAGS from given mask - */ -static fastcall inline void native_set_iopl_mask(unsigned mask) -{ - unsigned int reg; - __asm__ __volatile__ ("pushfl;" - "popl %0;" - "andl %1, %0;" - "orl %2, %0;" - "pushl %0;" - "popfl" - : "=&r" (reg) - : "i" (~X86_EFLAGS_IOPL), "r" (mask)); -} - -/* - * Generic CPUID function - * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx - * resulting in stale register contents being returned. - */ -static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = 0; - __cpuid(eax, ebx, ecx, edx); -} - -/* Some CPUID calls want 'count' to be placed in ecx */ -static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, - int *edx) -{ - *eax = op; - *ecx = count; - __cpuid(eax, ebx, ecx, edx); -} - -/* - * CPUID functions returning a single datum - */ -static inline unsigned int cpuid_eax(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return eax; -} -static inline unsigned int cpuid_ebx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return ebx; -} -static inline unsigned int cpuid_ecx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return ecx; -} -static inline unsigned int cpuid_edx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return edx; -} - /* generic versions from gas */ #define GENERIC_NOP1 ".byte 0x90\n" #define GENERIC_NOP2 ".byte 0x89,0xf6\n" @@ -742,7 +727,4 @@ extern unsigned long boot_option_idle_override; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -extern int init_gdt(int cpu, struct task_struct *idle); -extern void secondary_cpu_init(void); - #endif /* __ASM_I386_PROCESSOR_H */ diff --git a/trunk/include/asm-i386/ptrace.h b/trunk/include/asm-i386/ptrace.h index bdbc894339b4..d505f501077a 100644 --- a/trunk/include/asm-i386/ptrace.h +++ b/trunk/include/asm-i386/ptrace.h @@ -16,8 +16,6 @@ struct pt_regs { long eax; int xds; int xes; - /* int xfs; */ - int xgs; long orig_eax; long eip; int xcs; diff --git a/trunk/include/asm-i386/rwsem.h b/trunk/include/asm-i386/rwsem.h index 041906f3c6df..bc598d6388e3 100644 --- a/trunk/include/asm-i386/rwsem.h +++ b/trunk/include/asm-i386/rwsem.h @@ -75,8 +75,8 @@ struct rw_semaphore { #define __RWSEM_INITIALIZER(name) \ -{ RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ - LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } +{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \ + __RWSEM_DEP_MAP_INIT(name) } #define DECLARE_RWSEM(name) \ struct rw_semaphore name = __RWSEM_INITIALIZER(name) diff --git a/trunk/include/asm-i386/segment.h b/trunk/include/asm-i386/segment.h index 3c796af33776..b7ab59685ba7 100644 --- a/trunk/include/asm-i386/segment.h +++ b/trunk/include/asm-i386/segment.h @@ -39,7 +39,7 @@ * 25 - APM BIOS support * * 26 - ESPFIX small SS - * 27 - PDA [ per-cpu private data area ] + * 27 - unused * 28 - unused * 29 - unused * 30 - unused @@ -74,9 +74,6 @@ #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14) #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) -#define GDT_ENTRY_PDA (GDT_ENTRY_KERNEL_BASE + 15) -#define __KERNEL_PDA (GDT_ENTRY_PDA * 8) - #define GDT_ENTRY_DOUBLEFAULT_TSS 31 /* @@ -131,7 +128,5 @@ #define SEGMENT_LDT 0x4 #define SEGMENT_GDT 0x0 -#ifndef CONFIG_PARAVIRT #define get_kernel_rpl() 0 #endif -#endif diff --git a/trunk/include/asm-i386/setup.h b/trunk/include/asm-i386/setup.h index 67659dbaf120..2734909eff84 100644 --- a/trunk/include/asm-i386/setup.h +++ b/trunk/include/asm-i386/setup.h @@ -6,8 +6,6 @@ #ifndef _i386_SETUP_H #define _i386_SETUP_H -#define COMMAND_LINE_SIZE 256 - #ifdef __KERNEL__ #include @@ -16,8 +14,10 @@ */ #define MAXMEM_PFN PFN_DOWN(MAXMEM) #define MAX_NONPAE_PFN (1 << 20) +#endif #define PARAM_SIZE 4096 +#define COMMAND_LINE_SIZE 256 #define OLD_CL_MAGIC_ADDR 0x90020 #define OLD_CL_MAGIC 0xA33F @@ -70,7 +70,6 @@ extern unsigned char boot_params[PARAM_SIZE]; struct e820entry; char * __init machine_specific_memory_setup(void); -char *memory_setup(void); int __init copy_e820_map(struct e820entry * biosmap, int nr_map); int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map); @@ -79,6 +78,4 @@ void __init add_memory_region(unsigned long long start, #endif /* __ASSEMBLY__ */ -#endif /* __KERNEL__ */ - #endif /* _i386_SETUP_H */ diff --git a/trunk/include/asm-i386/smp.h b/trunk/include/asm-i386/smp.h index 64fe624c02ca..bd59c1508e71 100644 --- a/trunk/include/asm-i386/smp.h +++ b/trunk/include/asm-i386/smp.h @@ -8,7 +8,6 @@ #include #include #include -#include #endif #ifdef CONFIG_X86_LOCAL_APIC @@ -57,7 +56,7 @@ extern void cpu_uninit(void); * from the initial startup. We map APIC_BASE very early in page_setup(), * so this is correct in the x86 case. */ -#define raw_smp_processor_id() (read_pda(cpu_number)) +#define raw_smp_processor_id() (current_thread_info()->cpu) extern cpumask_t cpu_callout_map; extern cpumask_t cpu_callin_map; diff --git a/trunk/include/asm-i386/spinlock.h b/trunk/include/asm-i386/spinlock.h index d3bcebed60ca..c18b71fae6b3 100644 --- a/trunk/include/asm-i386/spinlock.h +++ b/trunk/include/asm-i386/spinlock.h @@ -7,14 +7,8 @@ #include #include -#ifdef CONFIG_PARAVIRT -#include -#else #define CLI_STRING "cli" #define STI_STRING "sti" -#define CLI_STI_CLOBBERS -#define CLI_STI_INPUT_ARGS -#endif /* CONFIG_PARAVIRT */ /* * Your basic SMP spinlocks, allowing only a single CPU anywhere @@ -59,28 +53,25 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla { asm volatile( "\n1:\t" - LOCK_PREFIX " ; decb %[slock]\n\t" + LOCK_PREFIX " ; decb %0\n\t" "jns 5f\n" "2:\t" - "testl $0x200, %[flags]\n\t" + "testl $0x200, %1\n\t" "jz 4f\n\t" STI_STRING "\n" "3:\t" "rep;nop\n\t" - "cmpb $0, %[slock]\n\t" + "cmpb $0, %0\n\t" "jle 3b\n\t" CLI_STRING "\n\t" "jmp 1b\n" "4:\t" "rep;nop\n\t" - "cmpb $0, %[slock]\n\t" + "cmpb $0, %0\n\t" "jg 1b\n\t" "jmp 4b\n" "5:\n\t" - : [slock] "+m" (lock->slock) - : [flags] "r" (flags) - CLI_STI_INPUT_ARGS - : "memory" CLI_STI_CLOBBERS); + : "+m" (lock->slock) : "r" (flags) : "memory"); } #endif diff --git a/trunk/include/asm-i386/suspend.h b/trunk/include/asm-i386/suspend.h index 8dbaafe611ff..08be1e5009d4 100644 --- a/trunk/include/asm-i386/suspend.h +++ b/trunk/include/asm-i386/suspend.h @@ -6,14 +6,29 @@ #include #include -static inline int arch_prepare_suspend(void) { return 0; } +static inline int +arch_prepare_suspend(void) +{ + /* If you want to make non-PSE machine work, turn off paging + in swsusp_arch_suspend. swsusp_pg_dir should have identity mapping, so + it could work... */ + if (!cpu_has_pse) { + printk(KERN_ERR "PSE is required for swsusp.\n"); + return -EPERM; + } + return 0; +} /* image of the saved processor state */ struct saved_context { u16 es, fs, gs, ss; unsigned long cr0, cr2, cr3, cr4; - struct Xgt_desc_struct gdt; - struct Xgt_desc_struct idt; + u16 gdt_pad; + u16 gdt_limit; + unsigned long gdt_base; + u16 idt_pad; + u16 idt_limit; + unsigned long idt_base; u16 ldt; u16 tss; unsigned long tr; diff --git a/trunk/include/asm-i386/system.h b/trunk/include/asm-i386/system.h index a6d20d9a1a30..a6dabbcd6e6a 100644 --- a/trunk/include/asm-i386/system.h +++ b/trunk/include/asm-i386/system.h @@ -88,9 +88,6 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \ #define savesegment(seg, value) \ asm volatile("mov %%" #seg ",%0":"=rm" (value)) -#ifdef CONFIG_PARAVIRT -#include -#else #define read_cr0() ({ \ unsigned int __dummy; \ __asm__ __volatile__( \ @@ -142,18 +139,17 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \ #define write_cr4(x) \ __asm__ __volatile__("movl %0,%%cr4": :"r" (x)) -#define wbinvd() \ - __asm__ __volatile__ ("wbinvd": : :"memory") - -/* Clear the 'TS' bit */ +/* + * Clear and set 'TS' bit respectively + */ #define clts() __asm__ __volatile__ ("clts") -#endif/* CONFIG_PARAVIRT */ - -/* Set the 'TS' bit */ #define stts() write_cr0(8 | read_cr0()) #endif /* __KERNEL__ */ +#define wbinvd() \ + __asm__ __volatile__ ("wbinvd": : :"memory") + static inline unsigned long get_limit(unsigned long segment) { unsigned long __limit; diff --git a/trunk/include/asm-i386/thread_info.h b/trunk/include/asm-i386/thread_info.h index 46d32ad92082..54d6d7aea938 100644 --- a/trunk/include/asm-i386/thread_info.h +++ b/trunk/include/asm-i386/thread_info.h @@ -95,7 +95,15 @@ static inline struct thread_info *current_thread_info(void) /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE -#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL) +#define alloc_thread_info(tsk) \ + ({ \ + struct thread_info *ret; \ + \ + ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \ + if (ret) \ + memset(ret, 0, THREAD_SIZE); \ + ret; \ + }) #else #define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) #endif diff --git a/trunk/include/asm-i386/time.h b/trunk/include/asm-i386/time.h deleted file mode 100644 index ea8065af825a..000000000000 --- a/trunk/include/asm-i386/time.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _ASMi386_TIME_H -#define _ASMi386_TIME_H - -#include -#include "mach_time.h" - -static inline unsigned long native_get_wallclock(void) -{ - unsigned long retval; - - if (efi_enabled) - retval = efi_get_time(); - else - retval = mach_get_cmos_time(); - - return retval; -} - -static inline int native_set_wallclock(unsigned long nowtime) -{ - int retval; - - if (efi_enabled) - retval = efi_set_rtc_mmss(nowtime); - else - retval = mach_set_rtc_mmss(nowtime); - - return retval; -} - -#ifdef CONFIG_PARAVIRT -#include -#else /* !CONFIG_PARAVIRT */ - -#define get_wallclock() native_get_wallclock() -#define set_wallclock(x) native_set_wallclock(x) -#define do_time_init() time_init_hook() - -#endif /* CONFIG_PARAVIRT */ - -#endif diff --git a/trunk/include/asm-i386/tlbflush.h b/trunk/include/asm-i386/tlbflush.h index 4dd82840d53b..360648b0f2b3 100644 --- a/trunk/include/asm-i386/tlbflush.h +++ b/trunk/include/asm-i386/tlbflush.h @@ -4,15 +4,7 @@ #include #include -#ifdef CONFIG_PARAVIRT -#include -#else -#define __flush_tlb() __native_flush_tlb() -#define __flush_tlb_global() __native_flush_tlb_global() -#define __flush_tlb_single(addr) __native_flush_tlb_single(addr) -#endif - -#define __native_flush_tlb() \ +#define __flush_tlb() \ do { \ unsigned int tmpreg; \ \ @@ -27,7 +19,7 @@ * Global pages have to be flushed a bit differently. Not a real * performance problem because this does not happen often. */ -#define __native_flush_tlb_global() \ +#define __flush_tlb_global() \ do { \ unsigned int tmpreg, cr4, cr4_orig; \ \ @@ -44,9 +36,6 @@ : "memory"); \ } while (0) -#define __native_flush_tlb_single(addr) \ - __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory") - # define __flush_tlb_all() \ do { \ if (cpu_has_pge) \ @@ -57,6 +46,9 @@ #define cpu_has_invlpg (boot_cpu_data.x86 > 3) +#define __flush_tlb_single(addr) \ + __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory") + #ifdef CONFIG_X86_INVLPG # define __flush_tlb_one(addr) __flush_tlb_single(addr) #else diff --git a/trunk/include/asm-i386/unistd.h b/trunk/include/asm-i386/unistd.h index 833fa1704ff9..beeeaf6b054a 100644 --- a/trunk/include/asm-i386/unistd.h +++ b/trunk/include/asm-i386/unistd.h @@ -329,6 +329,104 @@ #ifdef __KERNEL__ #define NR_syscalls 320 +#include + +/* + * user-visible error numbers are in the range -1 - -MAX_ERRNO: see + * + */ +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name)); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \ + "int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "i" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ + struct { long __a1; long __a6; } __s = { (long)arg1, (long)arg6 }; \ +__asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \ + "movl 0(%2),%%ebx ; movl %1,%%eax ; int $0x80 ; " \ + "pop %%ebx ; pop %%ebp" \ + : "=a" (__res) \ + : "i" (__NR_##name),"0" ((long)(&__s)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-i386/unwind.h b/trunk/include/asm-i386/unwind.h index aa2c931e30db..5031d693b89d 100644 --- a/trunk/include/asm-i386/unwind.h +++ b/trunk/include/asm-i386/unwind.h @@ -71,7 +71,6 @@ static inline void arch_unw_init_blocked(struct unwind_frame_info *info) info->regs.xss = __KERNEL_DS; info->regs.xds = __USER_DS; info->regs.xes = __USER_DS; - info->regs.xgs = __KERNEL_PDA; } extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *, @@ -79,13 +78,17 @@ extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *, void *arg), void *arg); -static inline int arch_unw_user_mode(/*const*/ struct unwind_frame_info *info) +static inline int arch_unw_user_mode(const struct unwind_frame_info *info) { - return user_mode_vm(&info->regs) - || info->regs.eip < PAGE_OFFSET +#if 0 /* This can only work when selector register and EFLAGS saves/restores + are properly annotated (and tracked in UNW_REGISTER_INFO). */ + return user_mode_vm(&info->regs); +#else + return info->regs.eip < PAGE_OFFSET || (info->regs.eip >= __fix_to_virt(FIX_VDSO) - && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE) + && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE) || info->regs.esp < PAGE_OFFSET; +#endif } #else diff --git a/trunk/include/asm-i386/vm86.h b/trunk/include/asm-i386/vm86.h index a5edf517b992..952fd6957380 100644 --- a/trunk/include/asm-i386/vm86.h +++ b/trunk/include/asm-i386/vm86.h @@ -145,13 +145,26 @@ struct vm86plus_struct { * at the end of the structure. Look at ptrace.h to see the "normal" * setup. For user space layout see 'struct vm86_regs' above. */ -#include struct kernel_vm86_regs { /* * normal regs, with special meaning for the segment descriptors.. */ - struct pt_regs pt; + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + long __null_ds; + long __null_es; + long orig_eax; + long eip; + unsigned short cs, __csh; + long eflags; + long esp; + unsigned short ss, __ssh; /* * these are specific to v86 mode: */ diff --git a/trunk/include/asm-ia64/Kbuild b/trunk/include/asm-ia64/Kbuild index 4a1e48b9f403..15818a18bc52 100644 --- a/trunk/include/asm-ia64/Kbuild +++ b/trunk/include/asm-ia64/Kbuild @@ -10,6 +10,7 @@ header-y += intrinsics.h header-y += perfmon_default_smpl.h header-y += ptrace_offsets.h header-y += rse.h +header-y += setup.h header-y += ucontext.h unifdef-y += perfmon.h diff --git a/trunk/include/asm-ia64/dma-mapping.h b/trunk/include/asm-ia64/dma-mapping.h index ebd5887f4b1a..99a8f8e1218c 100644 --- a/trunk/include/asm-ia64/dma-mapping.h +++ b/trunk/include/asm-ia64/dma-mapping.h @@ -50,8 +50,7 @@ dma_set_mask (struct device *dev, u64 mask) extern int dma_get_cache_alignment(void); static inline void -dma_cache_sync (struct device *dev, void *vaddr, size_t size, - enum dma_data_direction dir) +dma_cache_sync (void *vaddr, size_t size, enum dma_data_direction dir) { /* * IA-64 is cache-coherent, so this is mostly a no-op. However, we do need to @@ -60,6 +59,6 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size, mb(); } -#define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */ +#define dma_is_consistent(dma_handle) (1) /* all we do is coherent memory... */ #endif /* _ASM_IA64_DMA_MAPPING_H */ diff --git a/trunk/include/asm-ia64/futex.h b/trunk/include/asm-ia64/futex.h index 8a98a2654139..07d77f3a8cbe 100644 --- a/trunk/include/asm-ia64/futex.h +++ b/trunk/include/asm-ia64/futex.h @@ -59,7 +59,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -83,7 +83,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-ia64/pgalloc.h b/trunk/include/asm-ia64/pgalloc.h index 393e04c42a2c..9cb68e9b377e 100644 --- a/trunk/include/asm-ia64/pgalloc.h +++ b/trunk/include/asm-ia64/pgalloc.h @@ -60,7 +60,7 @@ static inline void *pgtable_quicklist_alloc(void) static inline void pgtable_quicklist_free(void *pgtable_entry) { #ifdef CONFIG_NUMA - int nid = page_to_nid(virt_to_page(pgtable_entry)); + unsigned long nid = page_to_nid(virt_to_page(pgtable_entry)); if (unlikely(nid != numa_node_id())) { free_page((unsigned long)pgtable_entry); diff --git a/trunk/include/asm-m32r/setup.h b/trunk/include/asm-m32r/setup.h index 6a0b32202d4e..52f4fa29abfc 100644 --- a/trunk/include/asm-m32r/setup.h +++ b/trunk/include/asm-m32r/setup.h @@ -1,11 +1,6 @@ /* * This is set up by the setup-routine at boot-time */ - -#define COMMAND_LINE_SIZE 512 - -#ifdef __KERNEL__ - #define PARAM ((unsigned char *)empty_zero_page) #define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) @@ -23,6 +18,8 @@ #define SCREEN_INFO (*(struct screen_info *) (PARAM+0x200)) +#define COMMAND_LINE_SIZE (512) + #define RAMDISK_IMAGE_START_MASK (0x07FF) #define RAMDISK_PROMPT_FLAG (0x8000) #define RAMDISK_LOAD_FLAG (0x4000) @@ -30,5 +27,3 @@ extern unsigned long memory_start; extern unsigned long memory_end; -#endif /* __KERNEL__ */ - diff --git a/trunk/include/asm-m32r/unistd.h b/trunk/include/asm-m32r/unistd.h index 5b66bd3c6ed6..95aa34298d82 100644 --- a/trunk/include/asm-m32r/unistd.h +++ b/trunk/include/asm-m32r/unistd.h @@ -296,6 +296,117 @@ #ifdef __KERNEL__ #define NR_syscalls 285 +#include + +/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see + * + */ + +#include /* SYSCALL_* */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + /* Avoid using "res" which is declared to be in register r0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) \ +{ \ +register long __scno __asm__ ("r7") = __NR_##name; \ +register long __res __asm__("r0"); \ +__asm__ __volatile__ (\ + "trap #" SYSCALL_VECTOR "|| nop"\ + : "=r" (__res) \ + : "r" (__scno) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +register long __scno __asm__ ("r7") = __NR_##name; \ +register long __res __asm__ ("r0") = (long)(arg1); \ +__asm__ __volatile__ (\ + "trap #" SYSCALL_VECTOR "|| nop"\ + : "=r" (__res) \ + : "r" (__scno), "0" (__res) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +register long __scno __asm__ ("r7") = __NR_##name; \ +register long __arg2 __asm__ ("r1") = (long)(arg2); \ +register long __res __asm__ ("r0") = (long)(arg1); \ +__asm__ __volatile__ (\ + "trap #" SYSCALL_VECTOR "|| nop"\ + : "=r" (__res) \ + : "r" (__scno), "0" (__res), "r" (__arg2) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +register long __scno __asm__ ("r7") = __NR_##name; \ +register long __arg3 __asm__ ("r2") = (long)(arg3); \ +register long __arg2 __asm__ ("r1") = (long)(arg2); \ +register long __res __asm__ ("r0") = (long)(arg1); \ +__asm__ __volatile__ (\ + "trap #" SYSCALL_VECTOR "|| nop"\ + : "=r" (__res) \ + : "r" (__scno), "0" (__res), "r" (__arg2), \ + "r" (__arg3) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name(type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ +{ \ +register long __scno __asm__ ("r7") = __NR_##name; \ +register long __arg4 __asm__ ("r3") = (long)(arg4); \ +register long __arg3 __asm__ ("r2") = (long)(arg3); \ +register long __arg2 __asm__ ("r1") = (long)(arg2); \ +register long __res __asm__ ("r0") = (long)(arg1); \ +__asm__ __volatile__ (\ + "trap #" SYSCALL_VECTOR "|| nop"\ + : "=r" (__res) \ + : "r" (__scno), "0" (__res), "r" (__arg2), \ + "r" (__arg3), "r" (__arg4) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name(type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +register long __scno __asm__ ("r7") = __NR_##name; \ +register long __arg5 __asm__ ("r4") = (long)(arg5); \ +register long __arg4 __asm__ ("r3") = (long)(arg4); \ +register long __arg3 __asm__ ("r2") = (long)(arg3); \ +register long __arg2 __asm__ ("r1") = (long)(arg2); \ +register long __res __asm__ ("r0") = (long)(arg1); \ +__asm__ __volatile__ (\ + "trap #" SYSCALL_VECTOR "|| nop"\ + : "=r" (__res) \ + : "r" (__scno), "0" (__res), "r" (__arg2), \ + "r" (__arg3), "r" (__arg4), "r" (__arg5) \ + : "memory"); \ +__syscall_return(type,__res); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 diff --git a/trunk/include/asm-m68k/dma-mapping.h b/trunk/include/asm-m68k/dma-mapping.h index 00259ed6fc95..d90d841d3dfd 100644 --- a/trunk/include/asm-m68k/dma-mapping.h +++ b/trunk/include/asm-m68k/dma-mapping.h @@ -21,7 +21,7 @@ static inline int dma_get_cache_alignment(void) return 1 << L1_CACHE_SHIFT; } -static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +static inline int dma_is_consistent(dma_addr_t dma_addr) { return 0; } @@ -41,7 +41,7 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size, { dma_free_coherent(dev, size, addr, handle); } -static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +static inline void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction dir) { /* we use coherent allocation, so not much to do here. */ diff --git a/trunk/include/asm-m68k/setup.h b/trunk/include/asm-m68k/setup.h index 2a8853cd6554..7facc9a46e74 100644 --- a/trunk/include/asm-m68k/setup.h +++ b/trunk/include/asm-m68k/setup.h @@ -41,12 +41,8 @@ #define MACH_Q40 10 #define MACH_SUN3X 11 -#define COMMAND_LINE_SIZE 256 - #ifdef __KERNEL__ -#define CL_SIZE COMMAND_LINE_SIZE - #ifndef __ASSEMBLY__ extern unsigned long m68k_machtype; #endif /* !__ASSEMBLY__ */ @@ -359,6 +355,8 @@ extern int m68k_is040or060; */ #define NUM_MEMINFO 4 +#define CL_SIZE 256 +#define COMMAND_LINE_SIZE CL_SIZE #ifndef __ASSEMBLY__ struct mem_info { diff --git a/trunk/include/asm-m68k/unistd.h b/trunk/include/asm-m68k/unistd.h index fdbb60e6a0d4..ad4348058c66 100644 --- a/trunk/include/asm-m68k/unistd.h +++ b/trunk/include/asm-m68k/unistd.h @@ -317,6 +317,103 @@ #ifdef __KERNEL__ #define NR_syscalls 311 +#include + +/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see + */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + /* avoid using res which is declared to be in register d0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) ); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,atype,a) \ +type name(atype a) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) \ + : "d" (__a) ); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,atype,a,btype,b) \ +type name(atype a,btype b) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) \ + : "d" (__a), "d" (__b) \ + ); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ +type name(atype a,btype b,ctype c) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) \ + : "d" (__a), "d" (__b), \ + "d" (__c) \ + ); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ +type name (atype a, btype b, ctype c, dtype d) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +register long __d __asm__ ("%d4") = (long)(d); \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) \ + : "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d) \ + ); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ +type name (atype a,btype b,ctype c,dtype d,etype e) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +register long __d __asm__ ("%d4") = (long)(d); \ +register long __e __asm__ ("%d5") = (long)(e); \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) \ + : "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d), "d" (__e) \ + ); \ +__syscall_return(type,__res); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-m68knommu/setup.h b/trunk/include/asm-m68knommu/setup.h index fb86bb2a6078..d2b0fcce41b2 100644 --- a/trunk/include/asm-m68knommu/setup.h +++ b/trunk/include/asm-m68knommu/setup.h @@ -1,10 +1,5 @@ -#ifdef __KERNEL__ - #include /* We have a bigger command line buffer. */ #undef COMMAND_LINE_SIZE - -#endif /* __KERNEL__ */ - #define COMMAND_LINE_SIZE 512 diff --git a/trunk/include/asm-m68knommu/unistd.h b/trunk/include/asm-m68knommu/unistd.h index 82e03195f325..ebaf03197114 100644 --- a/trunk/include/asm-m68knommu/unistd.h +++ b/trunk/include/asm-m68knommu/unistd.h @@ -318,6 +318,156 @@ #ifdef __KERNEL__ #define NR_syscalls 311 +#include + +/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see + */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + /* avoid using res which is declared to be in register d0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type, name) \ +type name(void) \ +{ \ + long __res; \ + __asm__ __volatile__ ("movel %1, %%d0\n\t" \ + "trap #0\n\t" \ + "movel %%d0, %0" \ + : "=g" (__res) \ + : "i" (__NR_##name) \ + : "cc", "%d0"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall1(type, name, atype, a) \ +type name(atype a) \ +{ \ + long __res; \ + __asm__ __volatile__ ("movel %2, %%d1\n\t" \ + "movel %1, %%d0\n\t" \ + "trap #0\n\t" \ + "movel %%d0, %0" \ + : "=g" (__res) \ + : "i" (__NR_##name), \ + "g" ((long)a) \ + : "cc", "%d0", "%d1"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall2(type, name, atype, a, btype, b) \ +type name(atype a, btype b) \ +{ \ + long __res; \ + __asm__ __volatile__ ("movel %3, %%d2\n\t" \ + "movel %2, %%d1\n\t" \ + "movel %1, %%d0\n\t" \ + "trap #0\n\t" \ + "movel %%d0, %0" \ + : "=g" (__res) \ + : "i" (__NR_##name), \ + "a" ((long)a), \ + "g" ((long)b) \ + : "cc", "%d0", "%d1", "%d2"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ +type name(atype a, btype b, ctype c) \ +{ \ + long __res; \ + __asm__ __volatile__ ("movel %4, %%d3\n\t" \ + "movel %3, %%d2\n\t" \ + "movel %2, %%d1\n\t" \ + "movel %1, %%d0\n\t" \ + "trap #0\n\t" \ + "movel %%d0, %0" \ + : "=g" (__res) \ + : "i" (__NR_##name), \ + "a" ((long)a), \ + "a" ((long)b), \ + "g" ((long)c) \ + : "cc", "%d0", "%d1", "%d2", "%d3"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \ +type name(atype a, btype b, ctype c, dtype d) \ +{ \ + long __res; \ + __asm__ __volatile__ ("movel %5, %%d4\n\t" \ + "movel %4, %%d3\n\t" \ + "movel %3, %%d2\n\t" \ + "movel %2, %%d1\n\t" \ + "movel %1, %%d0\n\t" \ + "trap #0\n\t" \ + "movel %%d0, %0" \ + : "=g" (__res) \ + : "i" (__NR_##name), \ + "a" ((long)a), \ + "a" ((long)b), \ + "a" ((long)c), \ + "g" ((long)d) \ + : "cc", "%d0", "%d1", "%d2", "%d3", \ + "%d4"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ +{ \ + long __res; \ + __asm__ __volatile__ ("movel %6, %%d5\n\t" \ + "movel %5, %%d4\n\t" \ + "movel %4, %%d3\n\t" \ + "movel %3, %%d2\n\t" \ + "movel %2, %%d1\n\t" \ + "movel %1, %%d0\n\t" \ + "trap #0\n\t" \ + "movel %%d0, %0" \ + : "=g" (__res) \ + : "i" (__NR_##name), \ + "a" ((long)a), \ + "a" ((long)b), \ + "a" ((long)c), \ + "a" ((long)d), \ + "g" ((long)e) \ + : "cc", "%d0", "%d1", "%d2", "%d3", \ + "%d4", "%d5"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-mips/dma-mapping.h b/trunk/include/asm-mips/dma-mapping.h index 236d1a467cc7..43288634c38a 100644 --- a/trunk/include/asm-mips/dma-mapping.h +++ b/trunk/include/asm-mips/dma-mapping.h @@ -63,9 +63,9 @@ dma_get_cache_alignment(void) return 128; } -extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr); +extern int dma_is_consistent(dma_addr_t dma_addr); -extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +extern void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction); #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY diff --git a/trunk/include/asm-mips/futex.h b/trunk/include/asm-mips/futex.h index 47e5679c2353..927a216bd530 100644 --- a/trunk/include/asm-mips/futex.h +++ b/trunk/include/asm-mips/futex.h @@ -88,7 +88,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -115,7 +115,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-mips/highmem.h b/trunk/include/asm-mips/highmem.h index f8c8182f7f2e..c976bfaaba83 100644 --- a/trunk/include/asm-mips/highmem.h +++ b/trunk/include/asm-mips/highmem.h @@ -21,7 +21,6 @@ #include #include -#include #include /* undef for production */ @@ -71,16 +70,11 @@ static inline void *kmap(struct page *page) static inline void *kmap_atomic(struct page *page, enum km_type type) { - pagefault_disable(); return page_address(page); } -static inline void kunmap_atomic(void *kvaddr, enum km_type type) -{ - pagefault_enable(); -} - -#define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx)) +static inline void kunmap_atomic(void *kvaddr, enum km_type type) { } +#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn)) #define kmap_atomic_to_page(ptr) virt_to_page(ptr) diff --git a/trunk/include/asm-mips/setup.h b/trunk/include/asm-mips/setup.h index 70009a902639..737fa4a6912e 100644 --- a/trunk/include/asm-mips/setup.h +++ b/trunk/include/asm-mips/setup.h @@ -1,6 +1,8 @@ +#ifdef __KERNEL__ #ifndef _MIPS_SETUP_H #define _MIPS_SETUP_H #define COMMAND_LINE_SIZE 256 #endif /* __SETUP_H */ +#endif /* __KERNEL__ */ diff --git a/trunk/include/asm-mips/unistd.h b/trunk/include/asm-mips/unistd.h index 696cff39a1d3..ec56aa52f669 100644 --- a/trunk/include/asm-mips/unistd.h +++ b/trunk/include/asm-mips/unistd.h @@ -933,6 +933,268 @@ #ifndef __ASSEMBLY__ +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ + register unsigned long __a3 asm("$7"); \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %2\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "i" (__NR_##name) \ + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +/* + * DANGER: This macro isn't usable for the pipe(2) call + * which has a unusual return convention. + */ +#define _syscall1(type,name,atype,a) \ +type name(atype a) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a3 asm("$7"); \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %3\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "i" (__NR_##name) \ + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#define _syscall2(type,name,atype,a,btype,b) \ +type name(atype a, btype b) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a3 asm("$7"); \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %4\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "i" (__NR_##name) \ + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ +type name(atype a, btype b, ctype c) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7"); \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ +type name(atype a, btype b, ctype c, dtype d) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#if (_MIPS_SIM == _MIPS_SIM_ABI32) + +/* + * Using those means your brain needs more than an oil change ;-) + */ + +#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e) \ + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "lw\t$8, %7\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "sw\t$8, 20($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e), "m" ((unsigned long)f) \ + : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */ + +#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) + +#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ +type name (atype a,btype b,ctype c,dtype d,etype e) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + register unsigned long __a4 asm("$8") = (unsigned long) e; \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %6\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "i" (__NR_##name) \ + : "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ +type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ +{ \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + register unsigned long __a4 asm("$8") = (unsigned long) e; \ + register unsigned long __a5 asm("$9") = (unsigned long) f; \ + unsigned long __v0; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %7\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "move\t%0, $2\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "r" (__a5), \ + "i" (__NR_##name) \ + : "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ + "memory"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return (type) -1; \ +} + +#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */ + + #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-parisc/dma-mapping.h b/trunk/include/asm-parisc/dma-mapping.h index 66f0b408c669..1e387e1dad30 100644 --- a/trunk/include/asm-parisc/dma-mapping.h +++ b/trunk/include/asm-parisc/dma-mapping.h @@ -191,13 +191,13 @@ dma_get_cache_alignment(void) } static inline int -dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +dma_is_consistent(dma_addr_t dma_addr) { return (hppa_dma_ops->dma_sync_single_for_cpu == NULL); } static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { if(hppa_dma_ops->dma_sync_single_for_cpu) diff --git a/trunk/include/asm-parisc/futex.h b/trunk/include/asm-parisc/futex.h index dbee6e60aa81..d84bbb283fd1 100644 --- a/trunk/include/asm-parisc/futex.h +++ b/trunk/include/asm-parisc/futex.h @@ -21,7 +21,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -33,7 +33,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-powerpc/dma-mapping.h b/trunk/include/asm-powerpc/dma-mapping.h index 7c7de87bd8ae..7e38b5fddada 100644 --- a/trunk/include/asm-powerpc/dma-mapping.h +++ b/trunk/include/asm-powerpc/dma-mapping.h @@ -342,9 +342,9 @@ static inline int dma_mapping_error(dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) #ifdef CONFIG_NOT_COHERENT_CACHE -#define dma_is_consistent(d, h) (0) +#define dma_is_consistent(d) (0) #else -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) #endif static inline int dma_get_cache_alignment(void) @@ -378,7 +378,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev, dma_sync_single_for_device(dev, dma_handle, offset + size, direction); } -static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +static inline void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/trunk/include/asm-powerpc/elf.h b/trunk/include/asm-powerpc/elf.h index d36426c01b6b..b5436642a109 100644 --- a/trunk/include/asm-powerpc/elf.h +++ b/trunk/include/asm-powerpc/elf.h @@ -124,10 +124,12 @@ typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG]; # define ELF_DATA ELFDATA2MSB typedef elf_greg_t64 elf_greg_t; typedef elf_gregset_t64 elf_gregset_t; +# define elf_addr_t unsigned long #else /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */ typedef elf_greg_t32 elf_greg_t; typedef elf_gregset_t32 elf_gregset_t; +# define elf_addr_t __u32 #endif /* ELF_ARCH */ /* Floating point registers */ diff --git a/trunk/include/asm-powerpc/futex.h b/trunk/include/asm-powerpc/futex.h index 3f3673fd3ff3..936422e54891 100644 --- a/trunk/include/asm-powerpc/futex.h +++ b/trunk/include/asm-powerpc/futex.h @@ -43,7 +43,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -65,7 +65,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-powerpc/pgalloc.h b/trunk/include/asm-powerpc/pgalloc.h index b0830db68f8a..ae63db7b3e7d 100644 --- a/trunk/include/asm-powerpc/pgalloc.h +++ b/trunk/include/asm-powerpc/pgalloc.h @@ -11,7 +11,7 @@ #include #include -extern struct kmem_cache *pgtable_cache[]; +extern kmem_cache_t *pgtable_cache[]; #ifdef CONFIG_PPC_64K_PAGES #define PTE_CACHE_NUM 0 diff --git a/trunk/include/asm-powerpc/setup.h b/trunk/include/asm-powerpc/setup.h index 817fac0a0714..3d9740aae018 100644 --- a/trunk/include/asm-powerpc/setup.h +++ b/trunk/include/asm-powerpc/setup.h @@ -1,6 +1,9 @@ #ifndef _ASM_POWERPC_SETUP_H #define _ASM_POWERPC_SETUP_H +#ifdef __KERNEL__ + #define COMMAND_LINE_SIZE 512 +#endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_SETUP_H */ diff --git a/trunk/include/asm-powerpc/unistd.h b/trunk/include/asm-powerpc/unistd.h index 0ae954e3d258..04b6c17cc59b 100644 --- a/trunk/include/asm-powerpc/unistd.h +++ b/trunk/include/asm-powerpc/unistd.h @@ -334,6 +334,115 @@ #ifndef __ASSEMBLY__ +/* On powerpc a system call basically clobbers the same registers like a + * function call, with the exception of LR (which is needed for the + * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal + * an error return status). + */ + +#define __syscall_nr(nr, type, name, args...) \ + unsigned long __sc_ret, __sc_err; \ + { \ + register unsigned long __sc_0 __asm__ ("r0"); \ + register unsigned long __sc_3 __asm__ ("r3"); \ + register unsigned long __sc_4 __asm__ ("r4"); \ + register unsigned long __sc_5 __asm__ ("r5"); \ + register unsigned long __sc_6 __asm__ ("r6"); \ + register unsigned long __sc_7 __asm__ ("r7"); \ + register unsigned long __sc_8 __asm__ ("r8"); \ + \ + __sc_loadargs_##nr(name, args); \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %0 " \ + : "=&r" (__sc_0), \ + "=&r" (__sc_3), "=&r" (__sc_4), \ + "=&r" (__sc_5), "=&r" (__sc_6), \ + "=&r" (__sc_7), "=&r" (__sc_8) \ + : __sc_asm_input_##nr \ + : "cr0", "ctr", "memory", \ + "r9", "r10","r11", "r12"); \ + __sc_ret = __sc_3; \ + __sc_err = __sc_0; \ + } \ + if (__sc_err & 0x10000000) \ + { \ + errno = __sc_ret; \ + __sc_ret = -1; \ + } \ + return (type) __sc_ret + +#define __sc_loadargs_0(name, dummy...) \ + __sc_0 = __NR_##name +#define __sc_loadargs_1(name, arg1) \ + __sc_loadargs_0(name); \ + __sc_3 = (unsigned long) (arg1) +#define __sc_loadargs_2(name, arg1, arg2) \ + __sc_loadargs_1(name, arg1); \ + __sc_4 = (unsigned long) (arg2) +#define __sc_loadargs_3(name, arg1, arg2, arg3) \ + __sc_loadargs_2(name, arg1, arg2); \ + __sc_5 = (unsigned long) (arg3) +#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4) \ + __sc_loadargs_3(name, arg1, arg2, arg3); \ + __sc_6 = (unsigned long) (arg4) +#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5) \ + __sc_loadargs_4(name, arg1, arg2, arg3, arg4); \ + __sc_7 = (unsigned long) (arg5) +#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ + __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5); \ + __sc_8 = (unsigned long) (arg6) + +#define __sc_asm_input_0 "0" (__sc_0) +#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3) +#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4) +#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5) +#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6) +#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7) +#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8) + +#define _syscall0(type,name) \ +type name(void) \ +{ \ + __syscall_nr(0, type, name); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + __syscall_nr(1, type, name, arg1); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1, type2 arg2) \ +{ \ + __syscall_nr(2, type, name, arg1, arg2); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1, type2 arg2, type3 arg3) \ +{ \ + __syscall_nr(3, type, name, arg1, arg2, arg3); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + __syscall_nr(4, type, name, arg1, arg2, arg3, arg4); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ +{ \ + __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \ +} +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ +{ \ + __syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ +} + + #include #include #include diff --git a/trunk/include/asm-ppc/highmem.h b/trunk/include/asm-ppc/highmem.h index f7b21ee302b4..1d2c4ef81c22 100644 --- a/trunk/include/asm-ppc/highmem.h +++ b/trunk/include/asm-ppc/highmem.h @@ -79,7 +79,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - pagefault_disable(); + inc_preempt_count(); if (!PageHighMem(page)) return page_address(page); @@ -101,7 +101,8 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) unsigned int idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < KMAP_FIX_BEGIN) { // FIXME - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); return; } @@ -114,7 +115,8 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) pte_clear(&init_mm, vaddr, kmap_pte+idx); flush_tlb_page(NULL, vaddr); #endif - pagefault_enable(); + dec_preempt_count(); + preempt_check_resched(); } static inline struct page *kmap_atomic_to_page(void *ptr) diff --git a/trunk/include/asm-s390/setup.h b/trunk/include/asm-s390/setup.h index 9574fe80a046..7664bacdd832 100644 --- a/trunk/include/asm-s390/setup.h +++ b/trunk/include/asm-s390/setup.h @@ -8,13 +8,12 @@ #ifndef _ASM_S390_SETUP_H #define _ASM_S390_SETUP_H -#define COMMAND_LINE_SIZE 896 - #ifdef __KERNEL__ #include #define PARMAREA 0x10400 +#define COMMAND_LINE_SIZE 896 #define MEMORY_CHUNKS 16 /* max 0x7fff */ #define IPL_PARMBLOCK_ORIGIN 0x2000 diff --git a/trunk/include/asm-s390/unistd.h b/trunk/include/asm-s390/unistd.h index fb6fef97d739..71d3c21b84f0 100644 --- a/trunk/include/asm-s390/unistd.h +++ b/trunk/include/asm-s390/unistd.h @@ -345,6 +345,160 @@ #ifdef __KERNEL__ +#include + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _svc_clobber "1", "cc", "memory" + +#define _syscall0(type,name) \ +type name(void) { \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) { \ + register type1 __arg1 asm("2") = arg1; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1, type2 arg2) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2) \ + : _svc_clobber ); \ + __res = __svcres; \ + __syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1, type2 arg2, type3 arg3) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register type3 __arg3 asm("4") = arg3; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2), \ + "d" (__arg3) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3, \ + type4,name4) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register type3 __arg3 asm("4") = arg3; \ + register type4 __arg4 asm("5") = arg4; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2), \ + "d" (__arg3), \ + "d" (__arg4) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3, \ + type4,name4,type5,name5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register type3 __arg3 asm("4") = arg3; \ + register type4 __arg4 asm("5") = arg4; \ + register type5 __arg5 asm("6") = arg5; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2), \ + "d" (__arg3), \ + "d" (__arg4), \ + "d" (__arg5) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ +} + #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM diff --git a/trunk/include/asm-sh/dma-mapping.h b/trunk/include/asm-sh/dma-mapping.h index 37ab0c131a4d..56cd4b977232 100644 --- a/trunk/include/asm-sh/dma-mapping.h +++ b/trunk/include/asm-sh/dma-mapping.h @@ -53,7 +53,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, consistent_free(vaddr, size); } -static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +static inline void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction dir) { consistent_sync(vaddr, size, (int)dir); diff --git a/trunk/include/asm-sh/setup.h b/trunk/include/asm-sh/setup.h index 1583c6b7bdaa..34ca8a7f06ba 100644 --- a/trunk/include/asm-sh/setup.h +++ b/trunk/include/asm-sh/setup.h @@ -1,12 +1,10 @@ +#ifdef __KERNEL__ #ifndef _SH_SETUP_H #define _SH_SETUP_H #define COMMAND_LINE_SIZE 256 -#ifdef __KERNEL__ - int setup_early_printk(char *); -#endif /* __KERNEL__ */ - #endif /* _SH_SETUP_H */ +#endif /* __KERNEL__ */ diff --git a/trunk/include/asm-sh/unistd.h b/trunk/include/asm-sh/unistd.h index f982073dc6c6..0cae1d248761 100644 --- a/trunk/include/asm-sh/unistd.h +++ b/trunk/include/asm-sh/unistd.h @@ -332,6 +332,143 @@ #ifdef __KERNEL__ +#include + +/* user-visible error numbers are in the range -1 - -MAX_ERRNO: + * see */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + /* Avoid using "res" which is declared to be in register r0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#if defined(__sh2__) || defined(__SH2E__) || defined(__SH2A__) +#define SYSCALL_ARG0 "trapa #0x20" +#define SYSCALL_ARG1 "trapa #0x21" +#define SYSCALL_ARG2 "trapa #0x22" +#define SYSCALL_ARG3 "trapa #0x23" +#define SYSCALL_ARG4 "trapa #0x24" +#define SYSCALL_ARG5 "trapa #0x25" +#define SYSCALL_ARG6 "trapa #0x26" +#else +#define SYSCALL_ARG0 "trapa #0x10" +#define SYSCALL_ARG1 "trapa #0x11" +#define SYSCALL_ARG2 "trapa #0x12" +#define SYSCALL_ARG3 "trapa #0x13" +#define SYSCALL_ARG4 "trapa #0x14" +#define SYSCALL_ARG5 "trapa #0x15" +#define SYSCALL_ARG6 "trapa #0x16" +#endif + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ +register long __sc0 __asm__ ("r3") = __NR_##name; \ +__asm__ __volatile__ (SYSCALL_ARG0 \ + : "=z" (__sc0) \ + : "0" (__sc0) \ + : "memory" ); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +register long __sc0 __asm__ ("r3") = __NR_##name; \ +register long __sc4 __asm__ ("r4") = (long) arg1; \ +__asm__ __volatile__ (SYSCALL_ARG1 \ + : "=z" (__sc0) \ + : "0" (__sc0), "r" (__sc4) \ + : "memory"); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +register long __sc0 __asm__ ("r3") = __NR_##name; \ +register long __sc4 __asm__ ("r4") = (long) arg1; \ +register long __sc5 __asm__ ("r5") = (long) arg2; \ +__asm__ __volatile__ (SYSCALL_ARG2 \ + : "=z" (__sc0) \ + : "0" (__sc0), "r" (__sc4), "r" (__sc5) \ + : "memory"); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +register long __sc0 __asm__ ("r3") = __NR_##name; \ +register long __sc4 __asm__ ("r4") = (long) arg1; \ +register long __sc5 __asm__ ("r5") = (long) arg2; \ +register long __sc6 __asm__ ("r6") = (long) arg3; \ +__asm__ __volatile__ (SYSCALL_ARG3 \ + : "=z" (__sc0) \ + : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) \ + : "memory"); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +register long __sc0 __asm__ ("r3") = __NR_##name; \ +register long __sc4 __asm__ ("r4") = (long) arg1; \ +register long __sc5 __asm__ ("r5") = (long) arg2; \ +register long __sc6 __asm__ ("r6") = (long) arg3; \ +register long __sc7 __asm__ ("r7") = (long) arg4; \ +__asm__ __volatile__ (SYSCALL_ARG4 \ + : "=z" (__sc0) \ + : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), \ + "r" (__sc7) \ + : "memory" ); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ +{ \ +register long __sc3 __asm__ ("r3") = __NR_##name; \ +register long __sc4 __asm__ ("r4") = (long) arg1; \ +register long __sc5 __asm__ ("r5") = (long) arg2; \ +register long __sc6 __asm__ ("r6") = (long) arg3; \ +register long __sc7 __asm__ ("r7") = (long) arg4; \ +register long __sc0 __asm__ ("r0") = (long) arg5; \ +__asm__ __volatile__ (SYSCALL_ARG5 \ + : "=z" (__sc0) \ + : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \ + "r" (__sc3) \ + : "memory" ); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ +{ \ +register long __sc3 __asm__ ("r3") = __NR_##name; \ +register long __sc4 __asm__ ("r4") = (long) arg1; \ +register long __sc5 __asm__ ("r5") = (long) arg2; \ +register long __sc6 __asm__ ("r6") = (long) arg3; \ +register long __sc7 __asm__ ("r7") = (long) arg4; \ +register long __sc0 __asm__ ("r0") = (long) arg5; \ +register long __sc1 __asm__ ("r1") = (long) arg6; \ +__asm__ __volatile__ (SYSCALL_ARG6 \ + : "=z" (__sc0) \ + : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \ + "r" (__sc3), "r" (__sc1) \ + : "memory" ); \ +__syscall_return(type,__sc0); \ +} + #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/trunk/include/asm-sh64/dma-mapping.h b/trunk/include/asm-sh64/dma-mapping.h index 5efe906c59f7..68e27a8fca31 100644 --- a/trunk/include/asm-sh64/dma-mapping.h +++ b/trunk/include/asm-sh64/dma-mapping.h @@ -35,7 +35,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, consistent_free(NULL, size, vaddr, dma_handle); } -static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, +static inline void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction dir) { dma_cache_wback_inv((unsigned long)vaddr, size); diff --git a/trunk/include/asm-sh64/setup.h b/trunk/include/asm-sh64/setup.h index 5b07b14c2927..ebd42eb1b709 100644 --- a/trunk/include/asm-sh64/setup.h +++ b/trunk/include/asm-sh64/setup.h @@ -1,10 +1,6 @@ #ifndef __ASM_SH64_SETUP_H #define __ASM_SH64_SETUP_H -#define COMMAND_LINE_SIZE 256 - -#ifdef __KERNEL__ - #define PARAM ((unsigned char *)empty_zero_page) #define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) #define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) @@ -16,7 +12,5 @@ #define COMMAND_LINE ((char *) (PARAM+256)) #define COMMAND_LINE_SIZE 256 -#endif /* __KERNEL__ */ - #endif /* __ASM_SH64_SETUP_H */ diff --git a/trunk/include/asm-sh64/unistd.h b/trunk/include/asm-sh64/unistd.h index 1f38a7aacaaf..ee7828b27ad1 100644 --- a/trunk/include/asm-sh64/unistd.h +++ b/trunk/include/asm-sh64/unistd.h @@ -347,6 +347,148 @@ #ifdef __KERNEL__ #define NR_syscalls 321 +#include + +/* user-visible error numbers are in the range -1 - -MAX_ERRNO: + * see */ + +#define __syscall_return(type, res) \ +do { \ + /* Note: when returning from kernel the return value is in r9 \ + ** This prevents conflicts between return value and arg1 \ + ** when dispatching signal handler, in other words makes \ + ** life easier in the system call epilogue (see entry.S) \ + */ \ + register unsigned long __sr2 __asm__ ("r2") = res; \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + errno = -(res); \ + __sr2 = -1; \ + } \ + return (type) (__sr2); \ +} while (0) + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ + +#define _syscall0(type,name) \ +type name(void) \ +{ \ +register unsigned long __sc0 __asm__ ("r9") = ((0x10 << 16) | __NR_##name); \ +__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "()" \ + : "=r" (__sc0) \ + : "r" (__sc0) ); \ +__syscall_return(type,__sc0); \ +} + + /* + * The apparent spurious "dummy" assembler comment is *needed*, + * as without it, the compiler treats the arg variables + * as no longer live just before the asm. The compiler can + * then optimize the storage into any registers it wishes. + * The additional dummy statement forces the compiler to put + * the arguments into the correct registers before the TRAPA. + */ +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +register unsigned long __sc0 __asm__ ("r9") = ((0x11 << 16) | __NR_##name); \ +register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ +__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2)" \ + : "=r" (__sc0) \ + : "r" (__sc0), "r" (__sc2)); \ +__asm__ __volatile__ ("!dummy %0 %1" \ + : \ + : "r" (__sc0), "r" (__sc2)); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +register unsigned long __sc0 __asm__ ("r9") = ((0x12 << 16) | __NR_##name); \ +register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ +register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ +__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3)" \ + : "=r" (__sc0) \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3) ); \ +__asm__ __volatile__ ("!dummy %0 %1 %2" \ + : \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3) ); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_##name); \ +register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ +register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ +register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ +__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4)" \ + : "=r" (__sc0) \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); \ +__asm__ __volatile__ ("!dummy %0 %1 %2 %3" \ + : \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +register unsigned long __sc0 __asm__ ("r9") = ((0x14 << 16) | __NR_##name); \ +register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ +register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ +register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ +register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4; \ +__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4,%5)" \ + : "=r" (__sc0) \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5) );\ +__asm__ __volatile__ ("!dummy %0 %1 %2 %3 %4" \ + : \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5) );\ +__syscall_return(type,__sc0); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ +{ \ +register unsigned long __sc0 __asm__ ("r9") = ((0x15 << 16) | __NR_##name); \ +register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ +register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ +register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ +register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4; \ +register unsigned long __sc6 __asm__ ("r6") = (unsigned long) arg5; \ +__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4,%5,%6)" \ + : "=r" (__sc0) \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ + "r" (__sc6)); \ +__asm__ __volatile__ ("!dummy %0 %1 %2 %3 %4 %5" \ + : \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ + "r" (__sc6)); \ +__syscall_return(type,__sc0); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ +{ \ +register unsigned long __sc0 __asm__ ("r9") = ((0x16 << 16) | __NR_##name); \ +register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ +register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ +register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ +register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4; \ +register unsigned long __sc6 __asm__ ("r6") = (unsigned long) arg5; \ +register unsigned long __sc7 __asm__ ("r7") = (unsigned long) arg6; \ +__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4,%5,%6,%7)" \ + : "=r" (__sc0) \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ + "r" (__sc6), "r" (__sc7)); \ +__asm__ __volatile__ ("!dummy %0 %1 %2 %3 %4 %5 %6" \ + : \ + : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ + "r" (__sc6), "r" (__sc7)); \ +__syscall_return(type,__sc0); \ +} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-sparc/unistd.h b/trunk/include/asm-sparc/unistd.h index d5b2f8053b3b..f7827fa4cd5e 100644 --- a/trunk/include/asm-sparc/unistd.h +++ b/trunk/include/asm-sparc/unistd.h @@ -329,6 +329,136 @@ * find a free slot in the 0-302 range. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res)\ + : "r" (__g1) \ + : "o0", "cc"); \ +if (__res < -255 || __res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__g1) \ + : "cc"); \ +if (__res < -255 || __res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__g1) \ + : "cc"); \ +if (__res < -255 || __res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ + : "cc"); \ +if (__res < -255 || __res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +register long __o3 __asm__ ("o3") = (long)(arg4); \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ + : "cc"); \ +if (__res < -255 || __res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +register long __o3 __asm__ ("o3") = (long)(arg4); \ +register long __o4 __asm__ ("o4") = (long)(arg5); \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \ + : "cc"); \ +if (__res < -255 || __res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/trunk/include/asm-sparc64/dma-mapping.h b/trunk/include/asm-sparc64/dma-mapping.h index 2f858a2df94a..27c46fbeebd6 100644 --- a/trunk/include/asm-sparc64/dma-mapping.h +++ b/trunk/include/asm-sparc64/dma-mapping.h @@ -181,7 +181,7 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t siz #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) static inline int dma_get_cache_alignment(void) @@ -210,7 +210,7 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, } static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { /* could define this in terms of the dma_cache ... operations, diff --git a/trunk/include/asm-sparc64/futex.h b/trunk/include/asm-sparc64/futex.h index 876312fe82cc..7392fc4a954e 100644 --- a/trunk/include/asm-sparc64/futex.h +++ b/trunk/include/asm-sparc64/futex.h @@ -45,7 +45,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -67,7 +67,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-sparc64/pgalloc.h b/trunk/include/asm-sparc64/pgalloc.h index 5891ff7ba760..010f9cd0a672 100644 --- a/trunk/include/asm-sparc64/pgalloc.h +++ b/trunk/include/asm-sparc64/pgalloc.h @@ -13,7 +13,7 @@ #include /* Page table allocation/freeing. */ -extern struct kmem_cache *pgtable_cache; +extern kmem_cache_t *pgtable_cache; static inline pgd_t *pgd_alloc(struct mm_struct *mm) { diff --git a/trunk/include/asm-sparc64/unistd.h b/trunk/include/asm-sparc64/unistd.h index 47047536f261..63669dad0d72 100644 --- a/trunk/include/asm-sparc64/unistd.h +++ b/trunk/include/asm-sparc64/unistd.h @@ -332,6 +332,124 @@ * find a free slot in the 0-302 range. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res)\ + : "r" (__g1) \ + : "o0", "cc"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__g1) \ + : "cc"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__g1) \ + : "cc"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ + : "cc"); \ +if (__res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +register long __o3 __asm__ ("o3") = (long)(arg4); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ + : "cc"); \ +if (__res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +register long __o3 __asm__ ("o3") = (long)(arg4); \ +register long __o4 __asm__ ("o4") = (long)(arg5); \ +__asm__ __volatile__ ("t 0x6d\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "movcc %%xcc, %%o0, %0\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \ + : "cc"); \ +if (__res>=0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + /* sysconf options, for SunOS compatibility */ #define _SC_ARG_MAX 1 #define _SC_CHILD_MAX 2 diff --git a/trunk/include/asm-um/dma-mapping.h b/trunk/include/asm-um/dma-mapping.h index f0ee4fb55911..babd29895114 100644 --- a/trunk/include/asm-um/dma-mapping.h +++ b/trunk/include/asm-um/dma-mapping.h @@ -94,7 +94,7 @@ dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) static inline int dma_get_cache_alignment(void) @@ -112,7 +112,7 @@ dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, } static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { BUG(); diff --git a/trunk/include/asm-v850/irq.h b/trunk/include/asm-v850/irq.h index 88687c181f01..1bf096db8f4c 100644 --- a/trunk/include/asm-v850/irq.h +++ b/trunk/include/asm-v850/irq.h @@ -46,6 +46,8 @@ extern void init_irq_handlers (int base_irq, int num, int interval, struct hw_interrupt_type *irq_type); +typedef void (*irq_handler_t)(int irq, void *data, struct pt_regs *regs); + /* Handle interrupt IRQ. REGS are the registers at the time of ther interrupt. */ extern unsigned int handle_irq (int irq, struct pt_regs *regs); diff --git a/trunk/include/asm-v850/unistd.h b/trunk/include/asm-v850/unistd.h index 2241ed45ecfe..737401e7d3ad 100644 --- a/trunk/include/asm-v850/unistd.h +++ b/trunk/include/asm-v850/unistd.h @@ -204,8 +204,168 @@ #define __NR_gettid 201 #define __NR_tkill 202 + +/* Syscall protocol: + Syscall number in r12, args in r6-r9, r13-r14 + Return value in r10 + Trap 0 for `short' syscalls, where all the args can fit in function + call argument registers, and trap 1 when there are additional args in + r13-r14. */ + +#define SYSCALL_NUM "r12" +#define SYSCALL_ARG0 "r6" +#define SYSCALL_ARG1 "r7" +#define SYSCALL_ARG2 "r8" +#define SYSCALL_ARG3 "r9" +#define SYSCALL_ARG4 "r13" +#define SYSCALL_ARG5 "r14" +#define SYSCALL_RET "r10" + +#define SYSCALL_SHORT_TRAP "0" +#define SYSCALL_LONG_TRAP "1" + +/* Registers clobbered by any syscall. This _doesn't_ include the syscall + number (r12) or the `extended arg' registers (r13, r14), even though + they are actually clobbered too (this is because gcc's `asm' statement + doesn't allow a clobber to be used as an input or output). */ +#define SYSCALL_CLOBBERS "r1", "r5", "r11", "r15", "r16", \ + "r17", "r18", "r19" + +/* Registers clobbered by a `short' syscall. This includes all clobbers + except the syscall number (r12). */ +#define SYSCALL_SHORT_CLOBBERS SYSCALL_CLOBBERS, "r13", "r14" + #ifdef __KERNEL__ +#include +#include + +#define __syscall_return(type, res) \ + do { \ + /* user-visible error numbers are in the range -1 - -MAX_ERRNO: \ + see */ \ + if (__builtin_expect ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO), 0)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ + } while (0) + + +#define _syscall0(type, name) \ +type name (void) \ +{ \ + register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ + register unsigned long __ret __asm__ (SYSCALL_RET); \ + __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ + : "=r" (__ret), "=r" (__syscall) \ + : "1" (__syscall) \ + : SYSCALL_SHORT_CLOBBERS); \ + __syscall_return (type, __ret); \ +} + +#define _syscall1(type, name, atype, a) \ +type name (atype a) \ +{ \ + register atype __a __asm__ (SYSCALL_ARG0) = a; \ + register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ + register unsigned long __ret __asm__ (SYSCALL_RET); \ + __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ + : "=r" (__ret), "=r" (__syscall) \ + : "1" (__syscall), "r" (__a) \ + : SYSCALL_SHORT_CLOBBERS); \ + __syscall_return (type, __ret); \ +} + +#define _syscall2(type, name, atype, a, btype, b) \ +type name (atype a, btype b) \ +{ \ + register atype __a __asm__ (SYSCALL_ARG0) = a; \ + register btype __b __asm__ (SYSCALL_ARG1) = b; \ + register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ + register unsigned long __ret __asm__ (SYSCALL_RET); \ + __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ + : "=r" (__ret), "=r" (__syscall) \ + : "1" (__syscall), "r" (__a), "r" (__b) \ + : SYSCALL_SHORT_CLOBBERS); \ + __syscall_return (type, __ret); \ +} + +#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ +type name (atype a, btype b, ctype c) \ +{ \ + register atype __a __asm__ (SYSCALL_ARG0) = a; \ + register btype __b __asm__ (SYSCALL_ARG1) = b; \ + register ctype __c __asm__ (SYSCALL_ARG2) = c; \ + register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ + register unsigned long __ret __asm__ (SYSCALL_RET); \ + __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ + : "=r" (__ret), "=r" (__syscall) \ + : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) \ + : SYSCALL_SHORT_CLOBBERS); \ + __syscall_return (type, __ret); \ +} + +#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \ +type name (atype a, btype b, ctype c, dtype d) \ +{ \ + register atype __a __asm__ (SYSCALL_ARG0) = a; \ + register btype __b __asm__ (SYSCALL_ARG1) = b; \ + register ctype __c __asm__ (SYSCALL_ARG2) = c; \ + register dtype __d __asm__ (SYSCALL_ARG3) = d; \ + register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ + register unsigned long __ret __asm__ (SYSCALL_RET); \ + __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ + : "=r" (__ret), "=r" (__syscall) \ + : "1" (__syscall), \ + "r" (__a), "r" (__b), "r" (__c), "r" (__d) \ + : SYSCALL_SHORT_CLOBBERS); \ + __syscall_return (type, __ret); \ +} + +#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype,e)\ +type name (atype a, btype b, ctype c, dtype d, etype e) \ +{ \ + register atype __a __asm__ (SYSCALL_ARG0) = a; \ + register btype __b __asm__ (SYSCALL_ARG1) = b; \ + register ctype __c __asm__ (SYSCALL_ARG2) = c; \ + register dtype __d __asm__ (SYSCALL_ARG3) = d; \ + register etype __e __asm__ (SYSCALL_ARG4) = e; \ + register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ + register unsigned long __ret __asm__ (SYSCALL_RET); \ + __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \ + : "=r" (__ret), "=r" (__syscall), "=r" (__e) \ + : "1" (__syscall), \ + "r" (__a), "r" (__b), "r" (__c), "r" (__d), "2" (__e) \ + : SYSCALL_CLOBBERS); \ + __syscall_return (type, __ret); \ +} + +#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \ + __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \ + : "=r" (ret), "=r" (syscall), \ + "=r" (e), "=r" (f) \ + : "1" (syscall), \ + "r" (a), "r" (b), "r" (c), "r" (d), \ + "2" (e), "3" (f) \ + : SYSCALL_CLOBBERS); + +#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \ +type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \ +{ \ + register atype __a __asm__ (SYSCALL_ARG0) = a; \ + register btype __b __asm__ (SYSCALL_ARG1) = b; \ + register ctype __c __asm__ (SYSCALL_ARG2) = c; \ + register dtype __d __asm__ (SYSCALL_ARG3) = d; \ + register etype __e __asm__ (SYSCALL_ARG4) = e; \ + register etype __f __asm__ (SYSCALL_ARG5) = f; \ + register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ + register unsigned long __ret __asm__ (SYSCALL_RET); \ + __SYSCALL6_TRAP(__syscall, __ret, __a, __b, __c, __d, __e, __f); \ + __syscall_return (type, __ret); \ +} + + #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/trunk/include/asm-x86_64/Kbuild b/trunk/include/asm-x86_64/Kbuild index ebd7117782a6..1ee9b07f3fe6 100644 --- a/trunk/include/asm-x86_64/Kbuild +++ b/trunk/include/asm-x86_64/Kbuild @@ -6,11 +6,13 @@ ALTARCHDEF := defined __i386__ header-y += boot.h header-y += bootsetup.h +header-y += cpufeature.h header-y += debugreg.h header-y += ldt.h header-y += msr.h header-y += prctl.h header-y += ptrace-abi.h +header-y += setup.h header-y += sigcontext32.h header-y += ucontext.h header-y += vsyscall32.h diff --git a/trunk/include/asm-x86_64/alternative.h b/trunk/include/asm-x86_64/alternative.h index a6657b4f3e0e..a584826cc570 100644 --- a/trunk/include/asm-x86_64/alternative.h +++ b/trunk/include/asm-x86_64/alternative.h @@ -4,7 +4,6 @@ #ifdef __KERNEL__ #include -#include #include struct alt_instr { @@ -134,15 +133,4 @@ static inline void alternatives_smp_switch(int smp) {} #define LOCK_PREFIX "" #endif -struct paravirt_patch; -#ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end); -#else -static inline void -apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) -{} -#define __start_parainstructions NULL -#define __stop_parainstructions NULL -#endif - #endif /* _X86_64_ALTERNATIVE_H */ diff --git a/trunk/include/asm-x86_64/atomic.h b/trunk/include/asm-x86_64/atomic.h index 706ca4b60000..93849f7abc24 100644 --- a/trunk/include/asm-x86_64/atomic.h +++ b/trunk/include/asm-x86_64/atomic.h @@ -189,9 +189,9 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) { int __i = i; __asm__ __volatile__( - LOCK_PREFIX "xaddl %0, %1" - :"+r" (i), "+m" (v->counter) - : : "memory"); + LOCK_PREFIX "xaddl %0, %1;" + :"=r"(i) + :"m"(v->counter), "0"(i)); return i + __i; } diff --git a/trunk/include/asm-x86_64/calgary.h b/trunk/include/asm-x86_64/calgary.h index 7ee900645719..6b93f5a3a5c8 100644 --- a/trunk/include/asm-x86_64/calgary.h +++ b/trunk/include/asm-x86_64/calgary.h @@ -51,8 +51,6 @@ struct iommu_table { #define TCE_TABLE_SIZE_4M 6 #define TCE_TABLE_SIZE_8M 7 -extern int use_calgary; - #ifdef CONFIG_CALGARY_IOMMU extern int calgary_iommu_init(void); extern void detect_calgary(void); diff --git a/trunk/include/asm-x86_64/cpufeature.h b/trunk/include/asm-x86_64/cpufeature.h index 0b3c686139f1..ee792faaca01 100644 --- a/trunk/include/asm-x86_64/cpufeature.h +++ b/trunk/include/asm-x86_64/cpufeature.h @@ -29,7 +29,7 @@ #define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ #define X86_FEATURE_PN (0*32+18) /* Processor serial number */ #define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ -#define X86_FEATURE_DS (0*32+21) /* Debug Store */ +#define X86_FEATURE_DTES (0*32+21) /* Debug Trace Store */ #define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ #define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ #define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ @@ -68,8 +68,6 @@ #define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */ #define X86_FEATURE_UP (3*32+8) /* SMP kernel running on UP */ #define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */ -#define X86_FEATURE_PEBS (3*32+10) /* Precise-Event Based Sampling */ -#define X86_FEATURE_BTS (3*32+11) /* Branch Trace Store */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ @@ -114,8 +112,5 @@ #define cpu_has_cyrix_arr 0 #define cpu_has_centaur_mcr 0 #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) -#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) -#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) -#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) #endif /* __ASM_X8664_CPUFEATURE_H */ diff --git a/trunk/include/asm-x86_64/delay.h b/trunk/include/asm-x86_64/delay.h index c2669f1f5529..65f64acc5319 100644 --- a/trunk/include/asm-x86_64/delay.h +++ b/trunk/include/asm-x86_64/delay.h @@ -7,21 +7,18 @@ * Delay routines calling functions in arch/x86_64/lib/delay.c */ -/* Undefined functions to get compile-time errors */ extern void __bad_udelay(void); extern void __bad_ndelay(void); extern void __udelay(unsigned long usecs); -extern void __ndelay(unsigned long nsecs); +extern void __ndelay(unsigned long usecs); extern void __const_udelay(unsigned long usecs); extern void __delay(unsigned long loops); -/* 0x10c7 is 2**32 / 1000000 (rounded up) */ #define udelay(n) (__builtin_constant_p(n) ? \ - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \ __udelay(n)) -/* 0x5 is 2**32 / 1000000000 (rounded up) */ #define ndelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) diff --git a/trunk/include/asm-x86_64/desc.h b/trunk/include/asm-x86_64/desc.h index 913d6ac00033..eb7723a46790 100644 --- a/trunk/include/asm-x86_64/desc.h +++ b/trunk/include/asm-x86_64/desc.h @@ -9,13 +9,64 @@ #include #include -#include #include #include +// 8 byte segment descriptor +struct desc_struct { + u16 limit0; + u16 base0; + unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; + unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8; +} __attribute__((packed)); + +struct n_desc_struct { + unsigned int a,b; +}; + extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; +enum { + GATE_INTERRUPT = 0xE, + GATE_TRAP = 0xF, + GATE_CALL = 0xC, +}; + +// 16byte gate +struct gate_struct { + u16 offset_low; + u16 segment; + unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; + u16 offset_middle; + u32 offset_high; + u32 zero1; +} __attribute__((packed)); + +#define PTR_LOW(x) ((unsigned long)(x) & 0xFFFF) +#define PTR_MIDDLE(x) (((unsigned long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH(x) ((unsigned long)(x) >> 32) + +enum { + DESC_TSS = 0x9, + DESC_LDT = 0x2, +}; + +// LDT or TSS descriptor in the GDT. 16 bytes. +struct ldttss_desc { + u16 limit0; + u16 base0; + unsigned base1 : 8, type : 5, dpl : 2, p : 1; + unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; + u32 base3; + u32 zero1; +} __attribute__((packed)); + +struct desc_ptr { + unsigned short size; + unsigned long address; +} __attribute__((packed)) ; + #define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8)) #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8)) #define clear_LDT() asm volatile("lldt %w0"::"r" (0)) diff --git a/trunk/include/asm-x86_64/desc_defs.h b/trunk/include/asm-x86_64/desc_defs.h deleted file mode 100644 index 089004070099..000000000000 --- a/trunk/include/asm-x86_64/desc_defs.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Written 2000 by Andi Kleen */ -#ifndef __ARCH_DESC_DEFS_H -#define __ARCH_DESC_DEFS_H - -/* - * Segment descriptor structure definitions, usable from both x86_64 and i386 - * archs. - */ - -#ifndef __ASSEMBLY__ - -#include - -// 8 byte segment descriptor -struct desc_struct { - u16 limit0; - u16 base0; - unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; - unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8; -} __attribute__((packed)); - -struct n_desc_struct { - unsigned int a,b; -}; - -enum { - GATE_INTERRUPT = 0xE, - GATE_TRAP = 0xF, - GATE_CALL = 0xC, -}; - -// 16byte gate -struct gate_struct { - u16 offset_low; - u16 segment; - unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; - u16 offset_middle; - u32 offset_high; - u32 zero1; -} __attribute__((packed)); - -#define PTR_LOW(x) ((unsigned long)(x) & 0xFFFF) -#define PTR_MIDDLE(x) (((unsigned long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH(x) ((unsigned long)(x) >> 32) - -enum { - DESC_TSS = 0x9, - DESC_LDT = 0x2, -}; - -// LDT or TSS descriptor in the GDT. 16 bytes. -struct ldttss_desc { - u16 limit0; - u16 base0; - unsigned base1 : 8, type : 5, dpl : 2, p : 1; - unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; - u32 base3; - u32 zero1; -} __attribute__((packed)); - -struct desc_ptr { - unsigned short size; - unsigned long address; -} __attribute__((packed)) ; - - -#endif /* !__ASSEMBLY__ */ - -#endif diff --git a/trunk/include/asm-x86_64/dma-mapping.h b/trunk/include/asm-x86_64/dma-mapping.h index be9ec6890723..10174b110a5c 100644 --- a/trunk/include/asm-x86_64/dma-mapping.h +++ b/trunk/include/asm-x86_64/dma-mapping.h @@ -180,13 +180,12 @@ static inline int dma_get_cache_alignment(void) return boot_cpu_data.x86_clflush_size; } -#define dma_is_consistent(d, h) 1 +#define dma_is_consistent(h) 1 extern int dma_set_mask(struct device *dev, u64 mask); static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction dir) +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction dir) { flush_write_buffers(); } diff --git a/trunk/include/asm-x86_64/futex.h b/trunk/include/asm-x86_64/futex.h index 5cdfb08013c3..9804bf07b092 100644 --- a/trunk/include/asm-x86_64/futex.h +++ b/trunk/include/asm-x86_64/futex.h @@ -55,7 +55,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - pagefault_disable(); + inc_preempt_count(); switch (op) { case FUTEX_OP_SET: @@ -78,7 +78,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + dec_preempt_count(); if (!ret) { switch (cmp) { diff --git a/trunk/include/asm-x86_64/genapic.h b/trunk/include/asm-x86_64/genapic.h index b80f4bb5f273..a0e9a4b93484 100644 --- a/trunk/include/asm-x86_64/genapic.h +++ b/trunk/include/asm-x86_64/genapic.h @@ -30,6 +30,6 @@ struct genapic { }; -extern struct genapic *genapic, *genapic_force, apic_flat; +extern struct genapic *genapic; #endif diff --git a/trunk/include/asm-x86_64/msr.h b/trunk/include/asm-x86_64/msr.h index 952783d35c7b..37e194169fac 100644 --- a/trunk/include/asm-x86_64/msr.h +++ b/trunk/include/asm-x86_64/msr.h @@ -169,8 +169,8 @@ static inline unsigned int cpuid_edx(unsigned int op) #define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ #define MSR_CSTAR 0xc0000083 /* compatibility mode SYSCALL target */ #define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ -#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ -#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ +#define MSR_FS_BASE 0xc0000100 /* 64bit GS base */ +#define MSR_GS_BASE 0xc0000101 /* 64bit FS base */ #define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow (or USER_GS from kernel) */ /* EFER bits: */ #define _EFER_SCE 0 /* SYSCALL/SYSRET */ @@ -210,10 +210,6 @@ static inline unsigned int cpuid_edx(unsigned int op) #define MSR_IA32_LASTINTFROMIP 0x1dd #define MSR_IA32_LASTINTTOIP 0x1de -#define MSR_IA32_PEBS_ENABLE 0x3f1 -#define MSR_IA32_DS_AREA 0x600 -#define MSR_IA32_PERF_CAPABILITIES 0x345 - #define MSR_MTRRfix64K_00000 0x250 #define MSR_MTRRfix16K_80000 0x258 #define MSR_MTRRfix16K_A0000 0x259 @@ -411,13 +407,4 @@ static inline unsigned int cpuid_edx(unsigned int op) #define MSR_P4_U2L_ESCR0 0x3b0 #define MSR_P4_U2L_ESCR1 0x3b1 -/* Intel Core-based CPU performance counters */ -#define MSR_CORE_PERF_FIXED_CTR0 0x309 -#define MSR_CORE_PERF_FIXED_CTR1 0x30a -#define MSR_CORE_PERF_FIXED_CTR2 0x30b -#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x38d -#define MSR_CORE_PERF_GLOBAL_STATUS 0x38e -#define MSR_CORE_PERF_GLOBAL_CTRL 0x38f -#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x390 - #endif diff --git a/trunk/include/asm-x86_64/nmi.h b/trunk/include/asm-x86_64/nmi.h index 72375e7d32a8..f367d4014b42 100644 --- a/trunk/include/asm-x86_64/nmi.h +++ b/trunk/include/asm-x86_64/nmi.h @@ -77,7 +77,4 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, extern int unknown_nmi_panic; -void __trigger_all_cpu_backtrace(void); -#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() - #endif /* ASM_NMI_H */ diff --git a/trunk/include/asm-x86_64/pci-direct.h b/trunk/include/asm-x86_64/pci-direct.h index 6823fa4f1afa..eba9cb471df3 100644 --- a/trunk/include/asm-x86_64/pci-direct.h +++ b/trunk/include/asm-x86_64/pci-direct.h @@ -10,7 +10,6 @@ extern u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset); extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset); extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset); extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val); -extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val); extern int early_pci_allowed(void); diff --git a/trunk/include/asm-x86_64/pgtable.h b/trunk/include/asm-x86_64/pgtable.h index 59901c690a0d..0555c1c4d8fa 100644 --- a/trunk/include/asm-x86_64/pgtable.h +++ b/trunk/include/asm-x86_64/pgtable.h @@ -221,19 +221,20 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define __S110 PAGE_SHARED_EXEC #define __S111 PAGE_SHARED_EXEC -static inline unsigned long pgd_bad(pgd_t pgd) -{ - return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); -} +static inline unsigned long pgd_bad(pgd_t pgd) +{ + unsigned long val = pgd_val(pgd); + val &= ~PTE_MASK; + val &= ~(_PAGE_USER | _PAGE_DIRTY); + return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED); +} static inline unsigned long pud_bad(pud_t pud) { - return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); -} - -static inline unsigned long pmd_bad(pmd_t pmd) -{ - return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); + unsigned long val = pud_val(pud); + val &= ~PTE_MASK; + val &= ~(_PAGE_USER | _PAGE_DIRTY); + return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED); } #define pte_none(x) (!pte_val(x)) @@ -346,6 +347,7 @@ static inline int pmd_large(pmd_t pte) { #define pmd_none(x) (!pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x) ((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE ) #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot))) #define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) diff --git a/trunk/include/asm-x86_64/processor.h b/trunk/include/asm-x86_64/processor.h index 76552d72804c..cef17e0f828c 100644 --- a/trunk/include/asm-x86_64/processor.h +++ b/trunk/include/asm-x86_64/processor.h @@ -475,14 +475,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx) : :"a" (eax), "c" (ecx)); } -static inline void __sti_mwait(unsigned long eax, unsigned long ecx) -{ - /* "mwait %eax,%ecx;" */ - asm volatile( - "sti; .byte 0x0f,0x01,0xc9;" - : :"a" (eax), "c" (ecx)); -} - extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); #define stack_current() \ diff --git a/trunk/include/asm-x86_64/proto.h b/trunk/include/asm-x86_64/proto.h index 6d324b838972..e72cfcdf5344 100644 --- a/trunk/include/asm-x86_64/proto.h +++ b/trunk/include/asm-x86_64/proto.h @@ -61,6 +61,7 @@ extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); extern unsigned long numa_free_all_bootmem(void); extern void reserve_bootmem_generic(unsigned long phys, unsigned len); +extern void free_bootmem_generic(unsigned long phys, unsigned len); extern void load_gs_index(unsigned gs); @@ -87,7 +88,6 @@ extern void syscall32_cpu_init(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); extern void early_quirks(void); -extern void quirk_intel_irqbalance(void); extern void check_efer(void); extern int unhandled_signal(struct task_struct *tsk, int sig); diff --git a/trunk/include/asm-x86_64/rio.h b/trunk/include/asm-x86_64/rio.h deleted file mode 100644 index c7350f6d2015..000000000000 --- a/trunk/include/asm-x86_64/rio.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Derived from include/asm-i386/mach-summit/mach_mpparse.h - * and include/asm-i386/mach-default/bios_ebda.h - * - * Author: Laurent Vivier - */ - -#ifndef __ASM_RIO_H -#define __ASM_RIO_H - -#define RIO_TABLE_VERSION 3 - -struct rio_table_hdr { - u8 version; /* Version number of this data structure */ - u8 num_scal_dev; /* # of Scalability devices */ - u8 num_rio_dev; /* # of RIO I/O devices */ -} __attribute__((packed)); - -struct scal_detail { - u8 node_id; /* Scalability Node ID */ - u32 CBAR; /* Address of 1MB register space */ - u8 port0node; /* Node ID port connected to: 0xFF=None */ - u8 port0port; /* Port num port connected to: 0,1,2, or */ - /* 0xFF=None */ - u8 port1node; /* Node ID port connected to: 0xFF = None */ - u8 port1port; /* Port num port connected to: 0,1,2, or */ - /* 0xFF=None */ - u8 port2node; /* Node ID port connected to: 0xFF = None */ - u8 port2port; /* Port num port connected to: 0,1,2, or */ - /* 0xFF=None */ - u8 chassis_num; /* 1 based Chassis number (1 = boot node) */ -} __attribute__((packed)); - -struct rio_detail { - u8 node_id; /* RIO Node ID */ - u32 BBAR; /* Address of 1MB register space */ - u8 type; /* Type of device */ - u8 owner_id; /* Node ID of Hurricane that owns this */ - /* node */ - u8 port0node; /* Node ID port connected to: 0xFF=None */ - u8 port0port; /* Port num port connected to: 0,1,2, or */ - /* 0xFF=None */ - u8 port1node; /* Node ID port connected to: 0xFF=None */ - u8 port1port; /* Port num port connected to: 0,1,2, or */ - /* 0xFF=None */ - u8 first_slot; /* Lowest slot number below this Calgary */ - u8 status; /* Bit 0 = 1 : the XAPIC is used */ - /* = 0 : the XAPIC is not used, ie: */ - /* ints fwded to another XAPIC */ - /* Bits1:7 Reserved */ - u8 WP_index; /* instance index - lower ones have */ - /* lower slot numbers/PCI bus numbers */ - u8 chassis_num; /* 1 based Chassis number */ -} __attribute__((packed)); - -enum { - HURR_SCALABILTY = 0, /* Hurricane Scalability info */ - HURR_RIOIB = 2, /* Hurricane RIOIB info */ - COMPAT_CALGARY = 4, /* Compatibility Calgary */ - ALT_CALGARY = 5, /* Second Planar Calgary */ -}; - -/* - * there is a real-mode segmented pointer pointing to the - * 4K EBDA area at 0x40E. - */ -static inline unsigned long get_bios_ebda(void) -{ - unsigned long address = *(unsigned short *)phys_to_virt(0x40EUL); - address <<= 4; - return address; -} - -#endif /* __ASM_RIO_H */ diff --git a/trunk/include/asm-x86_64/smp.h b/trunk/include/asm-x86_64/smp.h index e17b9ec42e98..d6b7c057edba 100644 --- a/trunk/include/asm-x86_64/smp.h +++ b/trunk/include/asm-x86_64/smp.h @@ -82,6 +82,11 @@ extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */ extern u8 x86_cpu_to_log_apicid[NR_CPUS]; extern u8 bios_cpu_apicid[]; +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) +{ + return cpus_addr(cpumask)[0]; +} + static inline int cpu_present_to_apicid(int mps_cpu) { if (mps_cpu < NR_CPUS) @@ -113,6 +118,13 @@ static __inline int logical_smp_processor_id(void) #define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu] #else #define cpu_physical_id(cpu) boot_cpu_id +static inline int smp_call_function_single(int cpuid, void (*func) (void *info), + void *info, int retry, int wait) +{ + /* Disable interrupts here? */ + func(info); + return 0; +} #endif /* !CONFIG_SMP */ #endif diff --git a/trunk/include/asm-x86_64/spinlock.h b/trunk/include/asm-x86_64/spinlock.h index 88bf981e73cf..05ef097ba55b 100644 --- a/trunk/include/asm-x86_64/spinlock.h +++ b/trunk/include/asm-x86_64/spinlock.h @@ -36,34 +36,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) "2:\t" : "=m" (lock->slock) : : "memory"); } -/* - * Same as __raw_spin_lock, but reenable interrupts during spinning. - */ -#ifndef CONFIG_PROVE_LOCKING -static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) -{ - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; decl %0\n\t" - "jns 5f\n" - "testl $0x200, %1\n\t" /* interrupts were disabled? */ - "jz 4f\n\t" - "sti\n" - "3:\t" - "rep;nop\n\t" - "cmpl $0, %0\n\t" - "jle 3b\n\t" - "cli\n\t" - "jmp 1b\n" - "4:\t" - "rep;nop\n\t" - "cmpl $0, %0\n\t" - "jg 1b\n\t" - "jmp 4b\n" - "5:\n\t" - : "+m" (lock->slock) : "r" ((unsigned)flags) : "memory"); -} -#endif +#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) static inline int __raw_spin_trylock(raw_spinlock_t *lock) { diff --git a/trunk/include/asm-x86_64/stacktrace.h b/trunk/include/asm-x86_64/stacktrace.h index 6f0b54594307..5eb9799bef76 100644 --- a/trunk/include/asm-x86_64/stacktrace.h +++ b/trunk/include/asm-x86_64/stacktrace.h @@ -1,8 +1,6 @@ #ifndef _ASM_STACKTRACE_H #define _ASM_STACKTRACE_H 1 -extern int kstack_depth_to_print; - /* Generic stack tracer with callbacks */ struct stacktrace_ops { diff --git a/trunk/include/asm-x86_64/unistd.h b/trunk/include/asm-x86_64/unistd.h index c5f596e71faa..777288eb7e75 100644 --- a/trunk/include/asm-x86_64/unistd.h +++ b/trunk/include/asm-x86_64/unistd.h @@ -622,7 +622,25 @@ __SYSCALL(__NR_move_pages, sys_move_pages) #define __NR_syscall_max __NR_move_pages +#ifdef __KERNEL__ +#include +#endif + #ifndef __NO_STUBS + +/* user-visible error numbers are in the range -1 - -MAX_ERRNO */ + +#define __syscall_clobber "r11","rcx","memory" + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_SYS_ALARM @@ -646,6 +664,87 @@ __SYSCALL(__NR_move_pages, sys_move_pages) #define __ARCH_WANT_SYS_TIME #define __ARCH_WANT_COMPAT_SYS_TIME +#define __syscall "syscall" + +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name) : __syscall_clobber ); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" ((long)(arg1)) : __syscall_clobber ); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)) : __syscall_clobber ); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ + "d" ((long)(arg3)) : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("movq %5,%%r10 ;" __syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ + "d" ((long)(arg3)),"g" ((long)(arg4)) : __syscall_clobber,"r10" ); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ + "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5)) : \ + __syscall_clobber,"r8","r10" ); \ +__syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ +__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9 ; " __syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ + "d" ((long)(arg3)), "g" ((long)(arg4)), "g" ((long)(arg5)), \ + "g" ((long)(arg6)) : \ + __syscall_clobber,"r8","r10","r9" ); \ +__syscall_return(type,__res); \ +} + #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/trunk/include/asm-x86_64/unwind.h b/trunk/include/asm-x86_64/unwind.h index 2f6349e48717..2e7ff10fd775 100644 --- a/trunk/include/asm-x86_64/unwind.h +++ b/trunk/include/asm-x86_64/unwind.h @@ -87,10 +87,14 @@ extern int arch_unwind_init_running(struct unwind_frame_info *, static inline int arch_unw_user_mode(const struct unwind_frame_info *info) { - return user_mode(&info->regs) - || (long)info->regs.rip >= 0 +#if 0 /* This can only work when selector register saves/restores + are properly annotated (and tracked in UNW_REGISTER_INFO). */ + return user_mode(&info->regs); +#else + return (long)info->regs.rip >= 0 || (info->regs.rip >= VSYSCALL_START && info->regs.rip < VSYSCALL_END) || (long)info->regs.rsp >= 0; +#endif } #else diff --git a/trunk/include/asm-x86_64/vsyscall.h b/trunk/include/asm-x86_64/vsyscall.h index 05cb8dd200de..01d1c17e2849 100644 --- a/trunk/include/asm-x86_64/vsyscall.h +++ b/trunk/include/asm-x86_64/vsyscall.h @@ -10,7 +10,6 @@ enum vsyscall_num { #define VSYSCALL_START (-10UL << 20) #define VSYSCALL_SIZE 1024 #define VSYSCALL_END (-2UL << 20) -#define VSYSCALL_MAPPED_PAGES 1 #define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) #ifdef __KERNEL__ diff --git a/trunk/include/asm-xtensa/dma-mapping.h b/trunk/include/asm-xtensa/dma-mapping.h index 82b03b3a2ee6..c39c91dfcc69 100644 --- a/trunk/include/asm-xtensa/dma-mapping.h +++ b/trunk/include/asm-xtensa/dma-mapping.h @@ -170,10 +170,10 @@ dma_get_cache_alignment(void) return L1_CACHE_BYTES; } -#define dma_is_consistent(d, h) (1) +#define dma_is_consistent(d) (1) static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, +dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) { consistent_sync(vaddr, size, direction); diff --git a/trunk/include/asm-xtensa/unistd.h b/trunk/include/asm-xtensa/unistd.h index 2e1a1b997e7d..411f810a55c6 100644 --- a/trunk/include/asm-xtensa/unistd.h +++ b/trunk/include/asm-xtensa/unistd.h @@ -218,6 +218,190 @@ #define SYSXTENSA_COUNT 5 /* count of syscall0 functions*/ +#ifdef __KERNEL__ +#include + +#define __syscall_return(type, res) return ((type)(res)) + +/* Tensilica's xt-xcc compiler is much more agressive at code + * optimization than gcc. Multiple __asm__ statements are + * insufficient for xt-xcc because subsequent optimization passes + * (beyond the front-end that knows of __asm__ statements and other + * such GNU Extensions to C) can modify the register selection for + * containment of C variables. + * + * xt-xcc cannot modify the contents of a single __asm__ statement, so + * we create single-asm versions of the syscall macros that are + * suitable and optimal for both xt-xcc and gcc. + * + * Linux takes system-call arguments in registers. The following + * design is optimized for user-land apps (e.g., glibc) which + * typically have a function wrapper around the "syscall" assembly + * instruction. It satisfies the Xtensa ABI while minizing argument + * shifting. + * + * The Xtensa ABI and software conventions require the system-call + * number in a2. If an argument exists in a2, we move it to the next + * available register. Note that for improved efficiency, we do NOT + * shift all parameters down one register to maintain the original + * order. + * + * At best case (zero arguments), we just write the syscall number to + * a2. At worst case (1 to 6 arguments), we move the argument in a2 + * to the next available register, then write the syscall number to + * a2. + * + * For clarity, the following truth table enumerates all possibilities. + * + * arguments syscall number arg0, arg1, arg2, arg3, arg4, arg5 + * --------- -------------- ---------------------------------- + * 0 a2 + * 1 a2 a3 + * 2 a2 a4, a3 + * 3 a2 a5, a3, a4 + * 4 a2 a6, a3, a4, a5 + * 5 a2 a7, a3, a4, a5, a6 + * 6 a2 a8, a3, a4, a5, a6, a7 + */ + +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +__asm__ __volatile__ ( \ + " movi a2, %1 \n" \ + " syscall \n" \ + " mov %0, a2 \n" \ + : "=a" (__res) \ + : "i" (__NR_##name) \ + : "a2" \ + ); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type0,arg0) \ +type name(type0 arg0) \ +{ \ +long __res; \ +__asm__ __volatile__ ( \ + " mov a3, %2 \n" \ + " movi a2, %1 \n" \ + " syscall \n" \ + " mov %0, a2 \n" \ + : "=a" (__res) \ + : "i" (__NR_##name), "a" (arg0) \ + : "a2", "a3" \ + ); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type0,arg0,type1,arg1) \ +type name(type0 arg0,type1 arg1) \ +{ \ +long __res; \ +__asm__ __volatile__ ( \ + " mov a4, %2 \n" \ + " mov a3, %3 \n" \ + " movi a2, %1 \n" \ + " syscall \n" \ + " mov %0, a2 \n" \ + : "=a" (__res) \ + : "i" (__NR_##name), "a" (arg0), "a" (arg1) \ + : "a2", "a3", "a4" \ + ); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type0,arg0,type1,arg1,type2,arg2) \ +type name(type0 arg0,type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ __volatile__ ( \ + " mov a5, %2 \n" \ + " mov a4, %4 \n" \ + " mov a3, %3 \n" \ + " movi a2, %1 \n" \ + " syscall \n" \ + " mov %0, a2 \n" \ + : "=a" (__res) \ + : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2) \ + : "a2", "a3", "a4", "a5" \ + ); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3) \ +type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ __volatile__ ( \ + " mov a6, %2 \n" \ + " mov a5, %5 \n" \ + " mov a4, %4 \n" \ + " mov a3, %3 \n" \ + " movi a2, %1 \n" \ + " syscall \n" \ + " mov %0, a2 \n" \ + : "=a" (__res) \ + : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), "a" (arg3) \ + : "a2", "a3", "a4", "a5", "a6" \ + ); \ +__syscall_return(type,__res); \ +} + +/* Note that we save and restore the a7 frame pointer. + * Including a7 in the clobber list doesn't do what you'd expect. + */ +#define _syscall5(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ +{ \ +long __res; \ +__asm__ __volatile__ ( \ + " mov a9, a7 \n" \ + " mov a7, %2 \n" \ + " mov a6, %6 \n" \ + " mov a5, %5 \n" \ + " mov a4, %4 \n" \ + " mov a3, %3 \n" \ + " movi a2, %1 \n" \ + " syscall \n" \ + " mov a7, a9 \n" \ + " mov %0, a2 \n" \ + : "=a" (__res) \ + : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \ + "a" (arg3), "a" (arg4) \ + : "a2", "a3", "a4", "a5", "a6", "a9" \ + ); \ +__syscall_return(type,__res); \ +} + +/* Note that we save and restore the a7 frame pointer. + * Including a7 in the clobber list doesn't do what you'd expect. + */ +#define _syscall6(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ __volatile__ ( \ + " mov a9, a7 \n" \ + " mov a8, %2 \n" \ + " mov a7, %7 \n" \ + " mov a6, %6 \n" \ + " mov a5, %5 \n" \ + " mov a4, %4 \n" \ + " mov a3, %3 \n" \ + " movi a2, %1 \n" \ + " syscall \n" \ + " mov a7, a9 \n" \ + " mov %0, a2 \n" \ + : "=a" (__res) \ + : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \ + "a" (arg3), "a" (arg4), "a" (arg5) \ + : "a2", "a3", "a4", "a5", "a6", "a8", "a9" \ + ); \ +__syscall_return(type,__res); \ +} + /* * "Conditional" syscalls * diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index e618b25b5add..ff433126361f 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -221,7 +221,6 @@ unifdef-y += if_bridge.h unifdef-y += if_ec.h unifdef-y += if_eql.h unifdef-y += if_ether.h -unifdef-y += if_fddi.h unifdef-y += if_frad.h unifdef-y += if_ltalk.h unifdef-y += if_pppox.h @@ -283,7 +282,6 @@ unifdef-y += nvram.h unifdef-y += parport.h unifdef-y += patchkey.h unifdef-y += pci.h -unifdef-y += personality.h unifdef-y += pktcdvd.h unifdef-y += pmu.h unifdef-y += poll.h @@ -339,7 +337,6 @@ unifdef-y += videodev.h unifdef-y += wait.h unifdef-y += wanrouter.h unifdef-y += watchdog.h -unifdef-y += wireless.h unifdef-y += xfrm.h objhdr-y += version.h diff --git a/trunk/include/linux/aio.h b/trunk/include/linux/aio.h index 3372ec6bf53a..9e350fd44d77 100644 --- a/trunk/include/linux/aio.h +++ b/trunk/include/linux/aio.h @@ -111,6 +111,7 @@ struct kiocb { size_t ki_nbytes; /* copy of iocb->aio_nbytes */ char __user *ki_buf; /* remaining iocb->aio_buf */ size_t ki_left; /* remaining bytes */ + long ki_retried; /* just for testing */ struct iovec ki_inline_vec; /* inline vector */ struct iovec *ki_iovec; unsigned long ki_nr_segs; @@ -237,6 +238,7 @@ do { \ } while (0) #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait) +#define is_retried_kiocb(iocb) ((iocb)->ki_retried > 1) #include diff --git a/trunk/include/linux/bootmem.h b/trunk/include/linux/bootmem.h index 2275f2748708..31e9abb6d977 100644 --- a/trunk/include/linux/bootmem.h +++ b/trunk/include/linux/bootmem.h @@ -119,7 +119,8 @@ extern void *alloc_large_system_hash(const char *tablename, unsigned int *_hash_mask, unsigned long limit); -#define HASH_EARLY 0x00000001 /* Allocating during early boot? */ +#define HASH_HIGHMEM 0x00000001 /* Consider highmem? */ +#define HASH_EARLY 0x00000002 /* Allocating during early boot? */ /* Only NUMA needs hash distribution. * IA64 is known to have sufficient vmalloc space. diff --git a/trunk/include/linux/bottom_half.h b/trunk/include/linux/bottom_half.h deleted file mode 100644 index 777dbf695d44..000000000000 --- a/trunk/include/linux/bottom_half.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _LINUX_BH_H -#define _LINUX_BH_H - -extern void local_bh_disable(void); -extern void __local_bh_enable(void); -extern void _local_bh_enable(void); -extern void local_bh_enable(void); -extern void local_bh_enable_ip(unsigned long ip); - -#endif /* _LINUX_BH_H */ diff --git a/trunk/include/linux/carta_random32.h b/trunk/include/linux/carta_random32.h new file mode 100644 index 000000000000..f6f3bd9f20b5 --- /dev/null +++ b/trunk/include/linux/carta_random32.h @@ -0,0 +1,29 @@ +/* + * Fast, simple, yet decent quality random number generator based on + * a paper by David G. Carta ("Two Fast Implementations of the + * `Minimal Standard' Random Number Generator," Communications of the + * ACM, January, 1990). + * + * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P. + * Contributed by Stephane Eranian + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ +#ifndef _LINUX_CARTA_RANDOM32_H_ +#define _LINUX_CARTA_RANDOM32_H_ + +u64 carta_random32(u64 seed); + +#endif /* _LINUX_CARTA_RANDOM32_H_ */ diff --git a/trunk/include/linux/cciss_ioctl.h b/trunk/include/linux/cciss_ioctl.h index cb57c30081a8..6e27f42e3a57 100644 --- a/trunk/include/linux/cciss_ioctl.h +++ b/trunk/include/linux/cciss_ioctl.h @@ -80,7 +80,7 @@ typedef __u32 DriverVer_type; #define HWORD __u16 #define DWORD __u32 -#define CISS_MAX_LUN 1024 +#define CISS_MAX_LUN 16 #define LEVEL2LUN 1 // index into Target(x) structure, due to byte swapping #define LEVEL3LUN 0 diff --git a/trunk/include/linux/cdev.h b/trunk/include/linux/cdev.h index f309b00e986e..ee5f53f2ca15 100644 --- a/trunk/include/linux/cdev.h +++ b/trunk/include/linux/cdev.h @@ -2,10 +2,6 @@ #define _LINUX_CDEV_H #ifdef __KERNEL__ -#include -#include -#include - struct cdev { struct kobject kobj; struct module *owner; diff --git a/trunk/include/linux/cpu.h b/trunk/include/linux/cpu.h index bfb520212d71..f02d71bf6894 100644 --- a/trunk/include/linux/cpu.h +++ b/trunk/include/linux/cpu.h @@ -24,11 +24,10 @@ #include #include #include -#include struct cpu { int node_id; /* The node which contains the CPU */ - int hotpluggable; /* creates sysfs control file if hotpluggable */ + int no_control; /* Should the sysfs control file be created? */ struct sys_device sysdev; }; @@ -75,17 +74,6 @@ extern struct sysdev_class cpu_sysdev_class; #ifdef CONFIG_HOTPLUG_CPU /* Stop CPUs going up and down. */ - -static inline void cpuhotplug_mutex_lock(struct mutex *cpu_hp_mutex) -{ - mutex_lock(cpu_hp_mutex); -} - -static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex) -{ - mutex_unlock(cpu_hp_mutex); -} - extern void lock_cpu_hotplug(void); extern void unlock_cpu_hotplug(void); #define hotcpu_notifier(fn, pri) { \ @@ -97,24 +85,17 @@ extern void unlock_cpu_hotplug(void); #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) int cpu_down(unsigned int cpu); #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) - -#else /* CONFIG_HOTPLUG_CPU */ - -static inline void cpuhotplug_mutex_lock(struct mutex *cpu_hp_mutex) -{ } -static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex) -{ } - +#else #define lock_cpu_hotplug() do { } while (0) #define unlock_cpu_hotplug() do { } while (0) #define lock_cpu_hotplug_interruptible() 0 -#define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) -#define register_hotcpu_notifier(nb) do { (void)(nb); } while (0) -#define unregister_hotcpu_notifier(nb) do { (void)(nb); } while (0) +#define hotcpu_notifier(fn, pri) do { } while (0) +#define register_hotcpu_notifier(nb) do { } while (0) +#define unregister_hotcpu_notifier(nb) do { } while (0) /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */ static inline int cpu_is_offline(int cpu) { return 0; } -#endif /* CONFIG_HOTPLUG_CPU */ +#endif #ifdef CONFIG_SUSPEND_SMP extern int disable_nonboot_cpus(void); diff --git a/trunk/include/linux/cpuset.h b/trunk/include/linux/cpuset.h index 8821e1f75b44..4d8adf663681 100644 --- a/trunk/include/linux/cpuset.h +++ b/trunk/include/linux/cpuset.h @@ -23,7 +23,6 @@ extern void cpuset_fork(struct task_struct *p); extern void cpuset_exit(struct task_struct *p); extern cpumask_t cpuset_cpus_allowed(struct task_struct *p); extern nodemask_t cpuset_mems_allowed(struct task_struct *p); -#define cpuset_current_mems_allowed (current->mems_allowed) void cpuset_init_current_mems_allowed(void); void cpuset_update_task_memory_state(void); #define cpuset_nodes_subset_current_mems_allowed(nodes) \ @@ -46,7 +45,7 @@ extern int cpuset_excl_nodes_overlap(const struct task_struct *p); extern int cpuset_memory_pressure_enabled; extern void __cpuset_memory_pressure_bump(void); -extern const struct file_operations proc_cpuset_operations; +extern struct file_operations proc_cpuset_operations; extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer); extern void cpuset_lock(void); @@ -84,7 +83,6 @@ static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) return node_possible_map; } -#define cpuset_current_mems_allowed (node_online_map) static inline void cpuset_init_current_mems_allowed(void) {} static inline void cpuset_update_task_memory_state(void) {} #define cpuset_nodes_subset_current_mems_allowed(nodes) (1) diff --git a/trunk/include/linux/debug_locks.h b/trunk/include/linux/debug_locks.h index a1c10b0c4cf0..952bee79a8f3 100644 --- a/trunk/include/linux/debug_locks.h +++ b/trunk/include/linux/debug_locks.h @@ -24,7 +24,7 @@ extern int debug_locks_off(void); int __ret = 0; \ \ if (unlikely(c)) { \ - if (debug_locks_silent || debug_locks_off()) \ + if (debug_locks_off()) \ WARN_ON(1); \ __ret = 1; \ } \ diff --git a/trunk/include/linux/delayacct.h b/trunk/include/linux/delayacct.h index 55d1ca5e60f5..561e2a77805c 100644 --- a/trunk/include/linux/delayacct.h +++ b/trunk/include/linux/delayacct.h @@ -30,7 +30,7 @@ #ifdef CONFIG_TASK_DELAY_ACCT extern int delayacct_on; /* Delay accounting turned on/off */ -extern struct kmem_cache *delayacct_cache; +extern kmem_cache_t *delayacct_cache; extern void delayacct_init(void); extern void __delayacct_tsk_init(struct task_struct *); extern void __delayacct_tsk_exit(struct task_struct *); diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 49ab53ce92dc..583a341e016c 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -371,9 +371,6 @@ struct device { core doesn't touch it */ struct dev_pm_info power; -#ifdef CONFIG_NUMA - int numa_node; /* NUMA node this device is close to */ -#endif u64 *dma_mask; /* dma mask (if dma'able device) */ u64 coherent_dma_mask;/* Like dma_mask, but for alloc_coherent mappings as @@ -397,25 +394,6 @@ struct device { void (*release)(struct device * dev); }; -#ifdef CONFIG_NUMA -static inline int dev_to_node(struct device *dev) -{ - return dev->numa_node; -} -static inline void set_dev_node(struct device *dev, int node) -{ - dev->numa_node = node; -} -#else -static inline int dev_to_node(struct device *dev) -{ - return -1; -} -static inline void set_dev_node(struct device *dev, int node) -{ -} -#endif - static inline void * dev_get_drvdata (struct device *dev) { diff --git a/trunk/include/linux/efi.h b/trunk/include/linux/efi.h index df1c91855f0e..66d621dbcb6c 100644 --- a/trunk/include/linux/efi.h +++ b/trunk/include/linux/efi.h @@ -300,9 +300,8 @@ extern int efi_mem_attribute_range (unsigned long phys_addr, unsigned long size, extern int __init efi_uart_console_only (void); extern void efi_initialize_iomem_resources(struct resource *code_resource, struct resource *data_resource); -extern unsigned long efi_get_time(void); +extern unsigned long __init efi_get_time(void); extern int __init efi_set_rtc_mmss(unsigned long nowtime); -extern int is_available_memory(efi_memory_desc_t * md); extern struct efi_memory_map memmap; /** diff --git a/trunk/include/linux/elf.h b/trunk/include/linux/elf.h index 60713e6ea297..743d5c8e6d36 100644 --- a/trunk/include/linux/elf.h +++ b/trunk/include/linux/elf.h @@ -6,8 +6,6 @@ #include #include -struct file; - #ifndef elf_read_implies_exec /* Executables for which elf_read_implies_exec() returns TRUE will have the READ_IMPLIES_EXEC personality flag set automatically. @@ -360,7 +358,6 @@ extern Elf32_Dyn _DYNAMIC []; #define elfhdr elf32_hdr #define elf_phdr elf32_phdr #define elf_note elf32_note -#define elf_addr_t Elf32_Off #else @@ -368,7 +365,6 @@ extern Elf64_Dyn _DYNAMIC []; #define elfhdr elf64_hdr #define elf_phdr elf64_phdr #define elf_note elf64_note -#define elf_addr_t Elf64_Off #endif diff --git a/trunk/include/linux/ext3_jbd.h b/trunk/include/linux/ext3_jbd.h index 8c43b13a02fe..ce0e6109aff0 100644 --- a/trunk/include/linux/ext3_jbd.h +++ b/trunk/include/linux/ext3_jbd.h @@ -109,32 +109,74 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); * been done yet. */ -static inline void ext3_journal_release_buffer(handle_t *handle, - struct buffer_head *bh) +void ext3_journal_abort_handle(const char *caller, const char *err_fn, + struct buffer_head *bh, handle_t *handle, int err); + +static inline int +__ext3_journal_get_undo_access(const char *where, handle_t *handle, + struct buffer_head *bh) { - journal_release_buffer(handle, bh); + int err = journal_get_undo_access(handle, bh); + if (err) + ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; } -void ext3_journal_abort_handle(const char *caller, const char *err_fn, - struct buffer_head *bh, handle_t *handle, int err); +static inline int +__ext3_journal_get_write_access(const char *where, handle_t *handle, + struct buffer_head *bh) +{ + int err = journal_get_write_access(handle, bh); + if (err) + ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext3_journal_get_undo_access(const char *where, handle_t *handle, - struct buffer_head *bh); +static inline void +ext3_journal_release_buffer(handle_t *handle, struct buffer_head *bh) +{ + journal_release_buffer(handle, bh); +} -int __ext3_journal_get_write_access(const char *where, handle_t *handle, - struct buffer_head *bh); +static inline int +__ext3_journal_forget(const char *where, handle_t *handle, struct buffer_head *bh) +{ + int err = journal_forget(handle, bh); + if (err) + ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext3_journal_forget(const char *where, handle_t *handle, - struct buffer_head *bh); +static inline int +__ext3_journal_revoke(const char *where, handle_t *handle, + unsigned long blocknr, struct buffer_head *bh) +{ + int err = journal_revoke(handle, blocknr, bh); + if (err) + ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext3_journal_revoke(const char *where, handle_t *handle, - unsigned long blocknr, struct buffer_head *bh); +static inline int +__ext3_journal_get_create_access(const char *where, + handle_t *handle, struct buffer_head *bh) +{ + int err = journal_get_create_access(handle, bh); + if (err) + ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext3_journal_get_create_access(const char *where, - handle_t *handle, struct buffer_head *bh); +static inline int +__ext3_journal_dirty_metadata(const char *where, + handle_t *handle, struct buffer_head *bh) +{ + int err = journal_dirty_metadata(handle, bh); + if (err) + ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext3_journal_dirty_metadata(const char *where, - handle_t *handle, struct buffer_head *bh); #define ext3_journal_get_undo_access(handle, bh) \ __ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh)) diff --git a/trunk/include/linux/ext4_jbd2.h b/trunk/include/linux/ext4_jbd2.h index d716e6392cf6..72dd631912e4 100644 --- a/trunk/include/linux/ext4_jbd2.h +++ b/trunk/include/linux/ext4_jbd2.h @@ -114,32 +114,74 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode); * been done yet. */ -static inline void ext4_journal_release_buffer(handle_t *handle, - struct buffer_head *bh) +void ext4_journal_abort_handle(const char *caller, const char *err_fn, + struct buffer_head *bh, handle_t *handle, int err); + +static inline int +__ext4_journal_get_undo_access(const char *where, handle_t *handle, + struct buffer_head *bh) { - jbd2_journal_release_buffer(handle, bh); + int err = jbd2_journal_get_undo_access(handle, bh); + if (err) + ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; } -void ext4_journal_abort_handle(const char *caller, const char *err_fn, - struct buffer_head *bh, handle_t *handle, int err); +static inline int +__ext4_journal_get_write_access(const char *where, handle_t *handle, + struct buffer_head *bh) +{ + int err = jbd2_journal_get_write_access(handle, bh); + if (err) + ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext4_journal_get_undo_access(const char *where, handle_t *handle, - struct buffer_head *bh); +static inline void +ext4_journal_release_buffer(handle_t *handle, struct buffer_head *bh) +{ + jbd2_journal_release_buffer(handle, bh); +} -int __ext4_journal_get_write_access(const char *where, handle_t *handle, - struct buffer_head *bh); +static inline int +__ext4_journal_forget(const char *where, handle_t *handle, struct buffer_head *bh) +{ + int err = jbd2_journal_forget(handle, bh); + if (err) + ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext4_journal_forget(const char *where, handle_t *handle, - struct buffer_head *bh); +static inline int +__ext4_journal_revoke(const char *where, handle_t *handle, + ext4_fsblk_t blocknr, struct buffer_head *bh) +{ + int err = jbd2_journal_revoke(handle, blocknr, bh); + if (err) + ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext4_journal_revoke(const char *where, handle_t *handle, - ext4_fsblk_t blocknr, struct buffer_head *bh); +static inline int +__ext4_journal_get_create_access(const char *where, + handle_t *handle, struct buffer_head *bh) +{ + int err = jbd2_journal_get_create_access(handle, bh); + if (err) + ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext4_journal_get_create_access(const char *where, - handle_t *handle, struct buffer_head *bh); +static inline int +__ext4_journal_dirty_metadata(const char *where, + handle_t *handle, struct buffer_head *bh) +{ + int err = jbd2_journal_dirty_metadata(handle, bh); + if (err) + ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); + return err; +} -int __ext4_journal_dirty_metadata(const char *where, - handle_t *handle, struct buffer_head *bh); #define ext4_journal_get_undo_access(handle, bh) \ __ext4_journal_get_undo_access(__FUNCTION__, (handle), (bh)) diff --git a/trunk/include/linux/file.h b/trunk/include/linux/file.h index 6e77b9177f9e..74183e6f7f45 100644 --- a/trunk/include/linux/file.h +++ b/trunk/include/linux/file.h @@ -64,8 +64,6 @@ struct files_struct { #define files_fdtable(files) (rcu_dereference((files)->fdt)) -extern struct kmem_cache *filp_cachep; - extern void FASTCALL(__fput(struct file *)); extern void FASTCALL(fput(struct file *)); @@ -116,6 +114,4 @@ struct files_struct *get_files_struct(struct task_struct *); void FASTCALL(put_files_struct(struct files_struct *fs)); void reset_files_struct(struct task_struct *, struct files_struct *); -extern struct kmem_cache *files_cachep; - #endif /* __LINUX_FILE_H */ diff --git a/trunk/include/linux/freezer.h b/trunk/include/linux/freezer.h deleted file mode 100644 index 6e05e3e7ce39..000000000000 --- a/trunk/include/linux/freezer.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Freezer declarations */ - -#ifdef CONFIG_PM -/* - * Check if a process has been frozen - */ -static inline int frozen(struct task_struct *p) -{ - return p->flags & PF_FROZEN; -} - -/* - * Check if there is a request to freeze a process - */ -static inline int freezing(struct task_struct *p) -{ - return p->flags & PF_FREEZE; -} - -/* - * Request that a process be frozen - * FIXME: SMP problem. We may not modify other process' flags! - */ -static inline void freeze(struct task_struct *p) -{ - p->flags |= PF_FREEZE; -} - -/* - * Sometimes we may need to cancel the previous 'freeze' request - */ -static inline void do_not_freeze(struct task_struct *p) -{ - p->flags &= ~PF_FREEZE; -} - -/* - * Wake up a frozen process - */ -static inline int thaw_process(struct task_struct *p) -{ - if (frozen(p)) { - p->flags &= ~PF_FROZEN; - wake_up_process(p); - return 1; - } - return 0; -} - -/* - * freezing is complete, mark process as frozen - */ -static inline void frozen_process(struct task_struct *p) -{ - p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN; -} - -extern void refrigerator(void); -extern int freeze_processes(void); -extern void thaw_processes(void); - -static inline int try_to_freeze(void) -{ - if (freezing(current)) { - refrigerator(); - return 1; - } else - return 0; -} - -extern void thaw_some_processes(int all); - -#else -static inline int frozen(struct task_struct *p) { return 0; } -static inline int freezing(struct task_struct *p) { return 0; } -static inline void freeze(struct task_struct *p) { BUG(); } -static inline int thaw_process(struct task_struct *p) { return 1; } -static inline void frozen_process(struct task_struct *p) { BUG(); } - -static inline void refrigerator(void) {} -static inline int freeze_processes(void) { BUG(); return 0; } -static inline void thaw_processes(void) {} - -static inline int try_to_freeze(void) { return 0; } - - -#endif diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 70b99fbb560b..cac7b1ef9543 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -543,22 +543,19 @@ struct inode { struct list_head i_dentry; unsigned long i_ino; atomic_t i_count; + umode_t i_mode; unsigned int i_nlink; uid_t i_uid; gid_t i_gid; dev_t i_rdev; - unsigned long i_version; loff_t i_size; -#ifdef __NEED_I_SIZE_ORDERED - seqcount_t i_size_seqcount; -#endif struct timespec i_atime; struct timespec i_mtime; struct timespec i_ctime; unsigned int i_blkbits; + unsigned long i_version; blkcnt_t i_blocks; unsigned short i_bytes; - umode_t i_mode; spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ struct mutex i_mutex; struct rw_semaphore i_alloc_sem; @@ -601,6 +598,9 @@ struct inode { void *i_security; #endif void *i_private; /* fs or device private pointer */ +#ifdef __NEED_I_SIZE_ORDERED + seqcount_t i_size_seqcount; +#endif }; /* @@ -636,7 +636,7 @@ extern void inode_double_unlock(struct inode *inode1, struct inode *inode2); * cmpxchg8b without the need of the lock prefix). For SMP compiles * and 64bit archs it makes no difference if preempt is enabled or not. */ -static inline loff_t i_size_read(const struct inode *inode) +static inline loff_t i_size_read(struct inode *inode) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) loff_t i_size; @@ -679,12 +679,12 @@ static inline void i_size_write(struct inode *inode, loff_t i_size) #endif } -static inline unsigned iminor(const struct inode *inode) +static inline unsigned iminor(struct inode *inode) { return MINOR(inode->i_rdev); } -static inline unsigned imajor(const struct inode *inode) +static inline unsigned imajor(struct inode *inode) { return MAJOR(inode->i_rdev); } @@ -1481,9 +1481,7 @@ extern char * getname(const char __user *); extern void __init vfs_caches_init_early(void); extern void __init vfs_caches_init(unsigned long); -extern struct kmem_cache *names_cachep; - -#define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL) +#define __getname() kmem_cache_alloc(names_cachep, SLAB_KERNEL) #define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) #ifndef CONFIG_AUDITSYSCALL #define putname(name) __putname(name) diff --git a/trunk/include/linux/fs_struct.h b/trunk/include/linux/fs_struct.h index 11a36ceddf73..c623d12a486e 100644 --- a/trunk/include/linux/fs_struct.h +++ b/trunk/include/linux/fs_struct.h @@ -18,8 +18,6 @@ struct fs_struct { .umask = 0022, \ } -extern struct kmem_cache *fs_cachep; - extern void exit_fs(struct task_struct *); extern void set_fs_altroot(void); extern void set_fs_root(struct fs_struct *, struct vfsmount *, struct dentry *); diff --git a/trunk/include/linux/fuse.h b/trunk/include/linux/fuse.h index 534744efe30d..9fc48a674b82 100644 --- a/trunk/include/linux/fuse.h +++ b/trunk/include/linux/fuse.h @@ -15,7 +15,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 8 +#define FUSE_KERNEL_MINOR_VERSION 7 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -92,11 +92,6 @@ struct fuse_file_lock { #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) -/** - * Release flags - */ -#define FUSE_RELEASE_FLUSH (1 << 0) - enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ @@ -132,8 +127,6 @@ enum fuse_opcode { FUSE_ACCESS = 34, FUSE_CREATE = 35, FUSE_INTERRUPT = 36, - FUSE_BMAP = 37, - FUSE_DESTROY = 38, }; /* The read buffer is required to be at least 8k, but may be much larger */ @@ -212,13 +205,12 @@ struct fuse_open_out { struct fuse_release_in { __u64 fh; __u32 flags; - __u32 release_flags; - __u64 lock_owner; + __u32 padding; }; struct fuse_flush_in { __u64 fh; - __u32 unused; + __u32 flush_flags; __u32 padding; __u64 lock_owner; }; @@ -304,16 +296,6 @@ struct fuse_interrupt_in { __u64 unique; }; -struct fuse_bmap_in { - __u64 block; - __u32 blocksize; - __u32 padding; -}; - -struct fuse_bmap_out { - __u64 block; -}; - struct fuse_in_header { __u32 len; __u32 opcode; diff --git a/trunk/include/linux/genetlink.h b/trunk/include/linux/genetlink.h index 9049dc65ae51..f7a93770e1be 100644 --- a/trunk/include/linux/genetlink.h +++ b/trunk/include/linux/genetlink.h @@ -17,6 +17,9 @@ struct genlmsghdr { #define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) #define GENL_ADMIN_PERM 0x01 +#define GENL_CMD_CAP_DO 0x02 +#define GENL_CMD_CAP_DUMP 0x04 +#define GENL_CMD_CAP_HASPOL 0x08 /* * List of reserved static generic netlink identifiers: @@ -58,9 +61,6 @@ enum { CTRL_ATTR_OP_UNSPEC, CTRL_ATTR_OP_ID, CTRL_ATTR_OP_FLAGS, - CTRL_ATTR_OP_POLICY, - CTRL_ATTR_OP_DOIT, - CTRL_ATTR_OP_DUMPIT, __CTRL_ATTR_OP_MAX, }; diff --git a/trunk/include/linux/gfp.h b/trunk/include/linux/gfp.h index 00c314aedab7..bf2b6bc3f6fd 100644 --- a/trunk/include/linux/gfp.h +++ b/trunk/include/linux/gfp.h @@ -116,9 +116,6 @@ static inline enum zone_type gfp_zone(gfp_t flags) #ifndef HAVE_ARCH_FREE_PAGE static inline void arch_free_page(struct page *page, int order) { } #endif -#ifndef HAVE_ARCH_ALLOC_PAGE -static inline void arch_alloc_page(struct page *page, int order) { } -#endif extern struct page * FASTCALL(__alloc_pages(gfp_t, unsigned int, struct zonelist *)); diff --git a/trunk/include/linux/highmem.h b/trunk/include/linux/highmem.h index 3d8768b619e9..fd7d12daa94f 100644 --- a/trunk/include/linux/highmem.h +++ b/trunk/include/linux/highmem.h @@ -3,7 +3,6 @@ #include #include -#include #include @@ -42,10 +41,9 @@ static inline void *kmap(struct page *page) #define kunmap(page) do { (void) (page); } while (0) -#define kmap_atomic(page, idx) \ - ({ pagefault_disable(); page_address(page); }) -#define kunmap_atomic(addr, idx) do { pagefault_enable(); } while (0) -#define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx)) +#define kmap_atomic(page, idx) page_address(page) +#define kunmap_atomic(addr, idx) do { } while (0) +#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn)) #define kmap_atomic_to_page(ptr) virt_to_page(ptr) #endif diff --git a/trunk/include/linux/hugetlb.h b/trunk/include/linux/hugetlb.h index a60995afe334..ace64e57e17f 100644 --- a/trunk/include/linux/hugetlb.h +++ b/trunk/include/linux/hugetlb.h @@ -35,7 +35,6 @@ extern int sysctl_hugetlb_shm_group; pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr); pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr); -int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep); struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, int write); struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, diff --git a/trunk/include/linux/i2o.h b/trunk/include/linux/i2o.h index 52f53e2e70c3..1fb02e17f6f6 100644 --- a/trunk/include/linux/i2o.h +++ b/trunk/include/linux/i2o.h @@ -490,7 +490,7 @@ struct i2o_dma { */ struct i2o_pool { char *name; - struct kmem_cache *slab; + kmem_cache_t *slab; mempool_t *mempool; }; @@ -986,8 +986,7 @@ extern void i2o_driver_unregister(struct i2o_driver *); /** * i2o_driver_notify_controller_add - Send notification of added controller - * @drv: I2O driver - * @c: I2O controller + * to a single I2O driver * * Send notification of added controller to a single registered driver. */ @@ -999,9 +998,8 @@ static inline void i2o_driver_notify_controller_add(struct i2o_driver *drv, }; /** - * i2o_driver_notify_controller_remove - Send notification of removed controller - * @drv: I2O driver - * @c: I2O controller + * i2o_driver_notify_controller_remove - Send notification of removed + * controller to a single I2O driver * * Send notification of removed controller to a single registered driver. */ @@ -1013,9 +1011,8 @@ static inline void i2o_driver_notify_controller_remove(struct i2o_driver *drv, }; /** - * i2o_driver_notify_device_add - Send notification of added device - * @drv: I2O driver - * @i2o_dev: the added i2o_device + * i2o_driver_notify_device_add - Send notification of added device to a + * single I2O driver * * Send notification of added device to a single registered driver. */ @@ -1028,8 +1025,7 @@ static inline void i2o_driver_notify_device_add(struct i2o_driver *drv, /** * i2o_driver_notify_device_remove - Send notification of removed device - * @drv: I2O driver - * @i2o_dev: the added i2o_device + * to a single I2O driver * * Send notification of removed device to a single registered driver. */ @@ -1152,7 +1148,7 @@ static inline void i2o_msg_post(struct i2o_controller *c, /** * i2o_msg_post_wait - Post and wait a message and wait until return * @c: controller - * @msg: message to post + * @m: message to post * @timeout: time in seconds to wait * * This API allows an OSM to post a message and then be told whether or diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index 733790d4f7db..33c5daacc743 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -73,7 +73,7 @@ extern struct nsproxy init_nsproxy; #define INIT_NSPROXY(nsproxy) { \ .count = ATOMIC_INIT(1), \ - .nslock = __SPIN_LOCK_UNLOCKED(nsproxy.nslock), \ + .nslock = SPIN_LOCK_UNLOCKED, \ .uts_ns = &init_uts_ns, \ .namespace = NULL, \ INIT_IPC_NS(ipc_ns) \ diff --git a/trunk/include/linux/interrupt.h b/trunk/include/linux/interrupt.h index de7593f4e895..5b83e7b59621 100644 --- a/trunk/include/linux/interrupt.h +++ b/trunk/include/linux/interrupt.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -218,6 +217,12 @@ static inline void __deprecated save_and_cli(unsigned long *x) #define save_and_cli(x) save_and_cli(&x) #endif /* CONFIG_SMP */ +extern void local_bh_disable(void); +extern void __local_bh_enable(void); +extern void _local_bh_enable(void); +extern void local_bh_enable(void); +extern void local_bh_enable_ip(unsigned long ip); + /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high frequency threaded job scheduling. For almost all the purposes tasklets are more than enough. F.e. all serial device BHs et diff --git a/trunk/include/linux/ipmi.h b/trunk/include/linux/ipmi.h index 7a9db390c56a..796ca009fd46 100644 --- a/trunk/include/linux/ipmi.h +++ b/trunk/include/linux/ipmi.h @@ -208,15 +208,6 @@ struct kernel_ipmi_msg code as the first byte of the incoming data, unlike a response. */ -/* - * Modes for ipmi_set_maint_mode() and the userland IOCTL. The AUTO - * setting is the default and means it will be set on certain - * commands. Hard setting it on and off will override automatic - * operation. - */ -#define IPMI_MAINTENANCE_MODE_AUTO 0 -#define IPMI_MAINTENANCE_MODE_OFF 1 -#define IPMI_MAINTENANCE_MODE_ON 2 #ifdef __KERNEL__ @@ -382,35 +373,6 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, unsigned char cmd, unsigned int chans); -/* - * Go into a mode where the driver will not autonomously attempt to do - * things with the interface. It will still respond to attentions and - * interrupts, and it will expect that commands will complete. It - * will not automatcially check for flags, events, or things of that - * nature. - * - * This is primarily used for firmware upgrades. The idea is that - * when you go into firmware upgrade mode, you do this operation - * and the driver will not attempt to do anything but what you tell - * it or what the BMC asks for. - * - * Note that if you send a command that resets the BMC, the driver - * will still expect a response from that command. So the BMC should - * reset itself *after* the response is sent. Resetting before the - * response is just silly. - * - * If in auto maintenance mode, the driver will automatically go into - * maintenance mode for 30 seconds if it sees a cold reset, a warm - * reset, or a firmware NetFN. This means that code that uses only - * firmware NetFN commands to do upgrades will work automatically - * without change, assuming it sends a message every 30 seconds or - * less. - * - * See the IPMI_MAINTENANCE_MODE_xxx defines for what the mode means. - */ -int ipmi_get_maintenance_mode(ipmi_user_t user); -int ipmi_set_maintenance_mode(ipmi_user_t user, int mode); - /* * Allow run-to-completion mode to be set for the interface of * a specific user. @@ -694,11 +656,4 @@ struct ipmi_timing_parms #define IPMICTL_GET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 23, \ struct ipmi_timing_parms) -/* - * Set the maintenance mode. See ipmi_set_maintenance_mode() above - * for a description of what this does. - */ -#define IPMICTL_GET_MAINTENANCE_MODE_CMD _IOR(IPMI_IOC_MAGIC, 30, int) -#define IPMICTL_SET_MAINTENANCE_MODE_CMD _IOW(IPMI_IOC_MAGIC, 31, int) - #endif /* __LINUX_IPMI_H */ diff --git a/trunk/include/linux/ipmi_msgdefs.h b/trunk/include/linux/ipmi_msgdefs.h index b56a158d587a..4d04d8b58a0a 100644 --- a/trunk/include/linux/ipmi_msgdefs.h +++ b/trunk/include/linux/ipmi_msgdefs.h @@ -46,8 +46,6 @@ #define IPMI_NETFN_APP_REQUEST 0x06 #define IPMI_NETFN_APP_RESPONSE 0x07 #define IPMI_GET_DEVICE_ID_CMD 0x01 -#define IPMI_COLD_RESET_CMD 0x02 -#define IPMI_WARM_RESET_CMD 0x03 #define IPMI_CLEAR_MSG_FLAGS_CMD 0x30 #define IPMI_GET_DEVICE_GUID_CMD 0x08 #define IPMI_GET_MSG_FLAGS_CMD 0x31 @@ -62,27 +60,20 @@ #define IPMI_NETFN_STORAGE_RESPONSE 0x0b #define IPMI_ADD_SEL_ENTRY_CMD 0x44 -#define IPMI_NETFN_FIRMWARE_REQUEST 0x08 -#define IPMI_NETFN_FIRMWARE_RESPONSE 0x09 - /* The default slave address */ #define IPMI_BMC_SLAVE_ADDR 0x20 /* The BT interface on high-end HP systems supports up to 255 bytes in * one transfer. Its "virtual" BMC supports some commands that are longer * than 128 bytes. Use the full 256, plus NetFn/LUN, Cmd, cCode, plus - * some overhead; it's not worth the effort to dynamically size this based - * on the results of the "Get BT Capabilities" command. */ + * some overhead. It would be nice to base this on the "BT Capabilities" + * but that's too hard to propagate to the rest of the driver. */ #define IPMI_MAX_MSG_LENGTH 272 /* multiple of 16 */ #define IPMI_CC_NO_ERROR 0x00 #define IPMI_NODE_BUSY_ERR 0xc0 #define IPMI_INVALID_COMMAND_ERR 0xc1 -#define IPMI_TIMEOUT_ERR 0xc3 #define IPMI_ERR_MSG_TRUNCATED 0xc6 -#define IPMI_REQ_LEN_INVALID_ERR 0xc7 -#define IPMI_REQ_LEN_EXCEEDED_ERR 0xc8 -#define IPMI_NOT_IN_MY_STATE_ERR 0xd5 /* IPMI 2.0 */ #define IPMI_LOST_ARBITRATION_ERR 0x81 #define IPMI_BUS_ERR 0x82 #define IPMI_NAK_ON_WRITE_ERR 0x83 diff --git a/trunk/include/linux/ipmi_smi.h b/trunk/include/linux/ipmi_smi.h index c0633108d05d..6d9c7e4da472 100644 --- a/trunk/include/linux/ipmi_smi.h +++ b/trunk/include/linux/ipmi_smi.h @@ -115,13 +115,6 @@ struct ipmi_smi_handlers poll for operations during things like crash dumps. */ void (*poll)(void *send_info); - /* Enable/disable firmware maintenance mode. Note that this - is *not* the modes defined, this is simply an on/off - setting. The message handler does the mode handling. Note - that this is called from interupt context, so it cannot - block. */ - void (*set_maintenance_mode)(void *send_info, int enable); - /* Tell the handler that we are using it/not using it. The message handler get the modules that this handler belongs to; this function lets the SMI claim any modules that it @@ -180,7 +173,6 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, void *send_info, struct ipmi_device_id *device_id, struct device *dev, - const char *sysfs_name, unsigned char slave_addr); /* diff --git a/trunk/include/linux/jbd.h b/trunk/include/linux/jbd.h index 452737551260..fe89444b1c6f 100644 --- a/trunk/include/linux/jbd.h +++ b/trunk/include/linux/jbd.h @@ -839,6 +839,7 @@ struct journal_s */ /* Filing buffers */ +extern void __journal_temp_unlink_buffer(struct journal_head *jh); extern void journal_unfile_buffer(journal_t *, struct journal_head *); extern void __journal_unfile_buffer(struct journal_head *); extern void __journal_refile_buffer(struct journal_head *); @@ -948,7 +949,7 @@ void journal_put_journal_head(struct journal_head *jh); /* * handle management */ -extern struct kmem_cache *jbd_handle_cache; +extern kmem_cache_t *jbd_handle_cache; static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags) { diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h index 0e0fedd2039a..ddb128795781 100644 --- a/trunk/include/linux/jbd2.h +++ b/trunk/include/linux/jbd2.h @@ -848,6 +848,7 @@ struct journal_s */ /* Filing buffers */ +extern void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); extern void jbd2_journal_unfile_buffer(journal_t *, struct journal_head *); extern void __jbd2_journal_unfile_buffer(struct journal_head *); extern void __jbd2_journal_refile_buffer(struct journal_head *); @@ -957,7 +958,7 @@ void jbd2_journal_put_journal_head(struct journal_head *jh); /* * handle management */ -extern struct kmem_cache *jbd2_handle_cache; +extern kmem_cache_t *jbd2_handle_cache; static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags) { diff --git a/trunk/include/linux/kexec.h b/trunk/include/linux/kexec.h index e3abcec6c51c..a4ede62b339d 100644 --- a/trunk/include/linux/kexec.h +++ b/trunk/include/linux/kexec.h @@ -105,7 +105,6 @@ extern struct page *kimage_alloc_control_pages(struct kimage *image, unsigned int order); extern void crash_kexec(struct pt_regs *); int kexec_should_crash(struct task_struct *); -void crash_save_cpu(struct pt_regs *regs, int cpu); extern struct kimage *kexec_image; extern struct kimage *kexec_crash_image; diff --git a/trunk/include/linux/kprobes.h b/trunk/include/linux/kprobes.h index 769be39b9681..ac4c0559f751 100644 --- a/trunk/include/linux/kprobes.h +++ b/trunk/include/linux/kprobes.h @@ -165,7 +165,7 @@ extern void arch_disarm_kprobe(struct kprobe *p); extern int arch_init_kprobes(void); extern void show_registers(struct pt_regs *regs); extern kprobe_opcode_t *get_insn_slot(void); -extern void free_insn_slot(kprobe_opcode_t *slot, int dirty); +extern void free_insn_slot(kprobe_opcode_t *slot); extern void kprobes_inc_nmissed_count(struct kprobe *p); /* Get the kprobe at this addr (if any) - called with preemption disabled */ diff --git a/trunk/include/linux/ktime.h b/trunk/include/linux/ktime.h index 611f17f79eef..84eeecd60a02 100644 --- a/trunk/include/linux/ktime.h +++ b/trunk/include/linux/ktime.h @@ -248,9 +248,9 @@ static inline struct timeval ktime_to_timeval(const ktime_t kt) * * Returns the scalar nanoseconds representation of kt */ -static inline s64 ktime_to_ns(const ktime_t kt) +static inline u64 ktime_to_ns(const ktime_t kt) { - return (s64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec; + return (u64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec; } #endif diff --git a/trunk/include/linux/lockd/lockd.h b/trunk/include/linux/lockd/lockd.h index 8c39654549d8..862d9730a60d 100644 --- a/trunk/include/linux/lockd/lockd.h +++ b/trunk/include/linux/lockd/lockd.h @@ -164,12 +164,14 @@ void nlmclnt_next_cookie(struct nlm_cookie *); */ struct nlm_host * nlmclnt_lookup_host(const struct sockaddr_in *, int, int, const char *, int); struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *, const char *, int); +struct nlm_host * nlm_lookup_host(int server, const struct sockaddr_in *, int, int, const char *, int); struct rpc_clnt * nlm_bind_host(struct nlm_host *); void nlm_rebind_host(struct nlm_host *); struct nlm_host * nlm_get_host(struct nlm_host *); void nlm_release_host(struct nlm_host *); void nlm_shutdown_hosts(void); extern void nlm_host_rebooted(const struct sockaddr_in *, const char *, int, u32); +struct nsm_handle *nsm_find(const struct sockaddr_in *, const char *, int); void nsm_release(struct nsm_handle *); diff --git a/trunk/include/linux/lockdep.h b/trunk/include/linux/lockdep.h index 498bfbd3b4e1..819f08f1310d 100644 --- a/trunk/include/linux/lockdep.h +++ b/trunk/include/linux/lockdep.h @@ -193,6 +193,7 @@ extern void lockdep_free_key_range(void *start, unsigned long size); extern void lockdep_off(void); extern void lockdep_on(void); +extern int lockdep_internal(void); /* * These methods are used by specific locking variants (spinlocks, @@ -242,8 +243,6 @@ extern void lock_release(struct lockdep_map *lock, int nested, # define INIT_LOCKDEP .lockdep_recursion = 0, -#define lockdep_depth(tsk) ((tsk)->lockdep_depth) - #else /* !LOCKDEP */ static inline void lockdep_off(void) @@ -254,6 +253,11 @@ static inline void lockdep_on(void) { } +static inline int lockdep_internal(void) +{ + return 0; +} + # define lock_acquire(l, s, t, r, c, i) do { } while (0) # define lock_release(l, n, i) do { } while (0) # define lockdep_init() do { } while (0) @@ -273,9 +277,6 @@ static inline void lockdep_on(void) * The class key takes no space if lockdep is disabled: */ struct lock_class_key { }; - -#define lockdep_depth(tsk) (0) - #endif /* !LOCKDEP */ #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS) diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index a17b147c61e7..d538de901965 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -114,8 +114,6 @@ struct vm_area_struct { #endif }; -extern struct kmem_cache *vm_area_cachep; - /* * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is * disabled, then there's a single shared list of VMAs maintained by the @@ -295,24 +293,6 @@ void put_pages_list(struct list_head *pages); void split_page(struct page *page, unsigned int order); -/* - * Compound pages have a destructor function. Provide a - * prototype for that function and accessor functions. - * These are _only_ valid on the head of a PG_compound page. - */ -typedef void compound_page_dtor(struct page *); - -static inline void set_compound_page_dtor(struct page *page, - compound_page_dtor *dtor) -{ - page[1].lru.next = (void *)dtor; -} - -static inline compound_page_dtor *get_compound_page_dtor(struct page *page) -{ - return (compound_page_dtor *)page[1].lru.next; -} - /* * Multiple processes may "see" the same page. E.g. for untouched * mappings of /dev/null, all processes see the same page full of @@ -416,9 +396,7 @@ static inline compound_page_dtor *get_compound_page_dtor(struct page *page) * We are going to use the flags for the page to node mapping if its in * there. This includes the case where there is no node, so it is implicit. */ -#if !(NODES_WIDTH > 0 || NODES_SHIFT == 0) -#define NODE_NOT_IN_PAGE_FLAGS -#endif +#define FLAGS_HAS_NODE (NODES_WIDTH > 0 || NODES_SHIFT == 0) #ifndef PFN_SECTION_SHIFT #define PFN_SECTION_SHIFT 0 @@ -433,18 +411,13 @@ static inline compound_page_dtor *get_compound_page_dtor(struct page *page) #define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0)) #define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0)) -/* NODE:ZONE or SECTION:ZONE is used to ID a zone for the buddy allcator */ -#ifdef NODE_NOT_IN_PAGEFLAGS -#define ZONEID_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT) -#else -#define ZONEID_SHIFT (NODES_SHIFT + ZONES_SHIFT) -#endif - -#if ZONES_WIDTH > 0 -#define ZONEID_PGSHIFT ZONES_PGSHIFT +/* NODE:ZONE or SECTION:ZONE is used to lookup the zone from a page. */ +#if FLAGS_HAS_NODE +#define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT) #else -#define ZONEID_PGSHIFT NODES_PGOFF +#define ZONETABLE_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT) #endif +#define ZONETABLE_PGSHIFT ZONES_PGSHIFT #if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED #error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED @@ -453,28 +426,26 @@ static inline compound_page_dtor *get_compound_page_dtor(struct page *page) #define ZONES_MASK ((1UL << ZONES_WIDTH) - 1) #define NODES_MASK ((1UL << NODES_WIDTH) - 1) #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) -#define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) +#define ZONETABLE_MASK ((1UL << ZONETABLE_SHIFT) - 1) static inline enum zone_type page_zonenum(struct page *page) { return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK; } -/* - * The identification function is only used by the buddy allocator for - * determining if two pages could be buddies. We are not really - * identifying a zone since we could be using a the section number - * id if we have not node id available in page flags. - * We guarantee only that it will return the same value for two - * combinable pages in a zone. - */ +struct zone; +extern struct zone *zone_table[]; + static inline int page_zone_id(struct page *page) { - BUILD_BUG_ON(ZONEID_PGSHIFT == 0 && ZONEID_MASK); - return (page->flags >> ZONEID_PGSHIFT) & ZONEID_MASK; + return (page->flags >> ZONETABLE_PGSHIFT) & ZONETABLE_MASK; +} +static inline struct zone *page_zone(struct page *page) +{ + return zone_table[page_zone_id(page)]; } -static inline int zone_to_nid(struct zone *zone) +static inline unsigned long zone_to_nid(struct zone *zone) { #ifdef CONFIG_NUMA return zone->node; @@ -483,20 +454,13 @@ static inline int zone_to_nid(struct zone *zone) #endif } -#ifdef NODE_NOT_IN_PAGE_FLAGS -extern int page_to_nid(struct page *page); -#else -static inline int page_to_nid(struct page *page) -{ - return (page->flags >> NODES_PGSHIFT) & NODES_MASK; -} -#endif - -static inline struct zone *page_zone(struct page *page) +static inline unsigned long page_to_nid(struct page *page) { - return &NODE_DATA(page_to_nid(page))->node_zones[page_zonenum(page)]; + if (FLAGS_HAS_NODE) + return (page->flags >> NODES_PGSHIFT) & NODES_MASK; + else + return zone_to_nid(page_zone(page)); } - static inline unsigned long page_to_section(struct page *page) { return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK; @@ -513,7 +477,6 @@ static inline void set_page_node(struct page *page, unsigned long node) page->flags &= ~(NODES_MASK << NODES_PGSHIFT); page->flags |= (node & NODES_MASK) << NODES_PGSHIFT; } - static inline void set_page_section(struct page *page, unsigned long section) { page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT); @@ -984,6 +947,8 @@ extern void mem_init(void); extern void show_mem(void); extern void si_meminfo(struct sysinfo * val); extern void si_meminfo_node(struct sysinfo *val, int nid); +extern void zonetable_add(struct zone *zone, int nid, enum zone_type zid, + unsigned long pfn, unsigned long size); #ifdef CONFIG_NUMA extern void setup_per_cpu_pageset(void); diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index e339a7345f25..e06683e2bea3 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -278,7 +278,7 @@ struct zone { /* * rarely used fields: */ - const char *name; + char *name; } ____cacheline_internodealigned_in_smp; /* @@ -288,94 +288,19 @@ struct zone { */ #define DEF_PRIORITY 12 -/* Maximum number of zones on a zonelist */ -#define MAX_ZONES_PER_ZONELIST (MAX_NUMNODES * MAX_NR_ZONES) - -#ifdef CONFIG_NUMA -/* - * We cache key information from each zonelist for smaller cache - * footprint when scanning for free pages in get_page_from_freelist(). - * - * 1) The BITMAP fullzones tracks which zones in a zonelist have come - * up short of free memory since the last time (last_fullzone_zap) - * we zero'd fullzones. - * 2) The array z_to_n[] maps each zone in the zonelist to its node - * id, so that we can efficiently evaluate whether that node is - * set in the current tasks mems_allowed. - * - * Both fullzones and z_to_n[] are one-to-one with the zonelist, - * indexed by a zones offset in the zonelist zones[] array. - * - * The get_page_from_freelist() routine does two scans. During the - * first scan, we skip zones whose corresponding bit in 'fullzones' - * is set or whose corresponding node in current->mems_allowed (which - * comes from cpusets) is not set. During the second scan, we bypass - * this zonelist_cache, to ensure we look methodically at each zone. - * - * Once per second, we zero out (zap) fullzones, forcing us to - * reconsider nodes that might have regained more free memory. - * The field last_full_zap is the time we last zapped fullzones. - * - * This mechanism reduces the amount of time we waste repeatedly - * reexaming zones for free memory when they just came up low on - * memory momentarilly ago. - * - * The zonelist_cache struct members logically belong in struct - * zonelist. However, the mempolicy zonelists constructed for - * MPOL_BIND are intentionally variable length (and usually much - * shorter). A general purpose mechanism for handling structs with - * multiple variable length members is more mechanism than we want - * here. We resort to some special case hackery instead. - * - * The MPOL_BIND zonelists don't need this zonelist_cache (in good - * part because they are shorter), so we put the fixed length stuff - * at the front of the zonelist struct, ending in a variable length - * zones[], as is needed by MPOL_BIND. - * - * Then we put the optional zonelist cache on the end of the zonelist - * struct. This optional stuff is found by a 'zlcache_ptr' pointer in - * the fixed length portion at the front of the struct. This pointer - * both enables us to find the zonelist cache, and in the case of - * MPOL_BIND zonelists, (which will just set the zlcache_ptr to NULL) - * to know that the zonelist cache is not there. - * - * The end result is that struct zonelists come in two flavors: - * 1) The full, fixed length version, shown below, and - * 2) The custom zonelists for MPOL_BIND. - * The custom MPOL_BIND zonelists have a NULL zlcache_ptr and no zlcache. - * - * Even though there may be multiple CPU cores on a node modifying - * fullzones or last_full_zap in the same zonelist_cache at the same - * time, we don't lock it. This is just hint data - if it is wrong now - * and then, the allocator will still function, perhaps a bit slower. - */ - - -struct zonelist_cache { - unsigned short z_to_n[MAX_ZONES_PER_ZONELIST]; /* zone->nid */ - DECLARE_BITMAP(fullzones, MAX_ZONES_PER_ZONELIST); /* zone full? */ - unsigned long last_full_zap; /* when last zap'd (jiffies) */ -}; -#else -struct zonelist_cache; -#endif - /* * One allocation request operates on a zonelist. A zonelist * is a list of zones, the first one is the 'goal' of the * allocation, the other zones are fallback zones, in decreasing * priority. * - * If zlcache_ptr is not NULL, then it is just the address of zlcache, - * as explained above. If zlcache_ptr is NULL, there is no zlcache. + * Right now a zonelist takes up less than a cacheline. We never + * modify it apart from boot-up, and only a few indices are used, + * so despite the zonelist table being relatively big, the cache + * footprint of this construct is very small. */ - struct zonelist { - struct zonelist_cache *zlcache_ptr; // NULL or &zlcache - struct zone *zones[MAX_ZONES_PER_ZONELIST + 1]; // NULL delimited -#ifdef CONFIG_NUMA - struct zonelist_cache zlcache; // optional ... -#endif + struct zone *zones[MAX_NUMNODES * MAX_NR_ZONES + 1]; // NULL delimited }; #ifdef CONFIG_ARCH_POPULATES_NODE_MAP diff --git a/trunk/include/linux/moduleparam.h b/trunk/include/linux/moduleparam.h index 4a189dadb160..7c0c2c198f1f 100644 --- a/trunk/include/linux/moduleparam.h +++ b/trunk/include/linux/moduleparam.h @@ -63,9 +63,6 @@ struct kparam_array not there, read bits mean it's readable, write bits mean it's writable. */ #define __module_param_call(prefix, name, set, get, arg, perm) \ - /* Default value instead of permissions? */ \ - static int __param_perm_check_##name __attribute__((unused)) = \ - BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \ static char __param_str_##name[] = prefix #name; \ static struct kernel_param const __param_##name \ __attribute_used__ \ diff --git a/trunk/include/linux/msg.h b/trunk/include/linux/msg.h index f1b60740d641..acc7c174ff00 100644 --- a/trunk/include/linux/msg.h +++ b/trunk/include/linux/msg.h @@ -92,12 +92,6 @@ struct msg_queue { struct list_head q_senders; }; -/* Helper routines for sys_msgsnd and sys_msgrcv */ -extern long do_msgsnd(int msqid, long mtype, void __user *mtext, - size_t msgsz, int msgflg); -extern long do_msgrcv(int msqid, long *pmtype, void __user *mtext, - size_t msgsz, long msgtyp, int msgflg); - #endif /* __KERNEL__ */ #endif /* _LINUX_MSG_H */ diff --git a/trunk/include/linux/mutex.h b/trunk/include/linux/mutex.h index b2b91c477563..27c48daa3183 100644 --- a/trunk/include/linux/mutex.h +++ b/trunk/include/linux/mutex.h @@ -94,7 +94,7 @@ do { \ #define __MUTEX_INITIALIZER(lockname) \ { .count = ATOMIC_INIT(1) \ - , .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \ + , .wait_lock = SPIN_LOCK_UNLOCKED \ , .wait_list = LIST_HEAD_INIT(lockname.wait_list) \ __DEBUG_MUTEX_INITIALIZER(lockname) \ __DEP_MAP_MUTEX_INITIALIZER(lockname) } diff --git a/trunk/include/linux/nbd.h b/trunk/include/linux/nbd.h index 0f3e69302540..d6b6dc09ad97 100644 --- a/trunk/include/linux/nbd.h +++ b/trunk/include/linux/nbd.h @@ -64,7 +64,6 @@ struct nbd_device { struct gendisk *disk; int blksize; u64 bytesize; - pid_t pid; /* pid of nbd-client, if attached */ }; #endif diff --git a/trunk/include/linux/nmi.h b/trunk/include/linux/nmi.h index acb4ed130247..e16904e28c3a 100644 --- a/trunk/include/linux/nmi.h +++ b/trunk/include/linux/nmi.h @@ -15,14 +15,9 @@ * disables interrupts for a long time. This call is stateless. */ #ifdef ARCH_HAS_NMI_WATCHDOG -#include extern void touch_nmi_watchdog(void); #else # define touch_nmi_watchdog() touch_softlockup_watchdog() #endif -#ifndef trigger_all_cpu_backtrace -#define trigger_all_cpu_backtrace() do { } while (0) -#endif - #endif diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index ff2dcb436cd0..c09da1e30c54 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -390,7 +390,7 @@ #define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d #define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e #define PCI_DEVICE_ID_NS_CS5535_USB 0x002f -#define PCI_DEVICE_ID_NS_GX_VIDEO 0x0030 +#define PCI_DEVICE_ID_NS_CS5535_VIDEO 0x0030 #define PCI_DEVICE_ID_NS_SATURN 0x0035 #define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500 #define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501 @@ -403,7 +403,8 @@ #define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 #define PCI_DEVICE_ID_NS_87410 0xd001 -#define PCI_DEVICE_ID_NS_GX_HOST_BRIDGE 0x0028 +#define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE 0x0028 +#define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE 0x002b #define PCI_VENDOR_ID_TSENG 0x100c #define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 @@ -1863,7 +1864,6 @@ #define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 #define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513 #define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521 -#define PCI_DEVICE_ID_OXSEMI_16PCI952PP 0x9523 #define PCI_VENDOR_ID_SAMSUNG 0x144d diff --git a/trunk/include/linux/profile.h b/trunk/include/linux/profile.h index 5670b340c4ef..acce53fd38b6 100644 --- a/trunk/include/linux/profile.h +++ b/trunk/include/linux/profile.h @@ -6,15 +6,10 @@ #include #include #include -#include - #include -extern int prof_on __read_mostly; - #define CPU_PROFILING 1 #define SCHED_PROFILING 2 -#define SLEEP_PROFILING 3 struct proc_dir_entry; struct pt_regs; @@ -23,24 +18,7 @@ struct notifier_block; /* init basic kernel profiler */ void __init profile_init(void); void profile_tick(int); - -/* - * Add multiple profiler hits to a given address: - */ -void profile_hits(int, void *ip, unsigned int nr_hits); - -/* - * Single profiler hit: - */ -static inline void profile_hit(int type, void *ip) -{ - /* - * Speedup for the common (no profiling enabled) case: - */ - if (unlikely(prof_on == type)) - profile_hits(type, ip, 1); -} - +void profile_hit(int, void *); #ifdef CONFIG_PROC_FS void create_prof_cpu_mask(struct proc_dir_entry *); #else diff --git a/trunk/include/linux/quotaops.h b/trunk/include/linux/quotaops.h index 90c23f690c0d..5110201a4159 100644 --- a/trunk/include/linux/quotaops.h +++ b/trunk/include/linux/quotaops.h @@ -37,9 +37,6 @@ extern int dquot_release(struct dquot *dquot); extern int dquot_commit_info(struct super_block *sb, int type); extern int dquot_mark_dquot_dirty(struct dquot *dquot); -int remove_inode_dquot_ref(struct inode *inode, int type, - struct list_head *tofree_head); - extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path); extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name, int format_id, int type); diff --git a/trunk/include/linux/radix-tree.h b/trunk/include/linux/radix-tree.h index 0deb842541ac..cbfa11537421 100644 --- a/trunk/include/linux/radix-tree.h +++ b/trunk/include/linux/radix-tree.h @@ -1,7 +1,6 @@ /* * Copyright (C) 2001 Momchil Velikov * Portions Copyright (C) 2001 Christoph Hellwig - * Copyright (C) 2006 Nick Piggin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,35 +21,6 @@ #include #include -#include -#include - -/* - * A direct pointer (root->rnode pointing directly to a data item, - * rather than another radix_tree_node) is signalled by the low bit - * set in the root->rnode pointer. - * - * In this case root->height is also NULL, but the direct pointer tests are - * needed for RCU lookups when root->height is unreliable. - */ -#define RADIX_TREE_DIRECT_PTR 1 - -static inline void *radix_tree_ptr_to_direct(void *ptr) -{ - return (void *)((unsigned long)ptr | RADIX_TREE_DIRECT_PTR); -} - -static inline void *radix_tree_direct_to_ptr(void *ptr) -{ - return (void *)((unsigned long)ptr & ~RADIX_TREE_DIRECT_PTR); -} - -static inline int radix_tree_is_direct_ptr(void *ptr) -{ - return (int)((unsigned long)ptr & RADIX_TREE_DIRECT_PTR); -} - -/*** radix-tree API starts here ***/ #define RADIX_TREE_MAX_TAGS 2 @@ -77,77 +47,6 @@ do { \ (root)->rnode = NULL; \ } while (0) -/** - * Radix-tree synchronization - * - * The radix-tree API requires that users provide all synchronisation (with - * specific exceptions, noted below). - * - * Synchronization of access to the data items being stored in the tree, and - * management of their lifetimes must be completely managed by API users. - * - * For API usage, in general, - * - any function _modifying_ the the tree or tags (inserting or deleting - * items, setting or clearing tags must exclude other modifications, and - * exclude any functions reading the tree. - * - any function _reading_ the the tree or tags (looking up items or tags, - * gang lookups) must exclude modifications to the tree, but may occur - * concurrently with other readers. - * - * The notable exceptions to this rule are the following functions: - * radix_tree_lookup - * radix_tree_tag_get - * radix_tree_gang_lookup - * radix_tree_gang_lookup_tag - * radix_tree_tagged - * - * The first 4 functions are able to be called locklessly, using RCU. The - * caller must ensure calls to these functions are made within rcu_read_lock() - * regions. Other readers (lock-free or otherwise) and modifications may be - * running concurrently. - * - * It is still required that the caller manage the synchronization and lifetimes - * of the items. So if RCU lock-free lookups are used, typically this would mean - * that the items have their own locks, or are amenable to lock-free access; and - * that the items are freed by RCU (or only freed after having been deleted from - * the radix tree *and* a synchronize_rcu() grace period). - * - * (Note, rcu_assign_pointer and rcu_dereference are not needed to control - * access to data items when inserting into or looking up from the radix tree) - * - * radix_tree_tagged is able to be called without locking or RCU. - */ - -/** - * radix_tree_deref_slot - dereference a slot - * @pslot: pointer to slot, returned by radix_tree_lookup_slot - * Returns: item that was stored in that slot with any direct pointer flag - * removed. - * - * For use with radix_tree_lookup_slot(). Caller must hold tree at least read - * locked across slot lookup and dereference. More likely, will be used with - * radix_tree_replace_slot(), as well, so caller will hold tree write locked. - */ -static inline void *radix_tree_deref_slot(void **pslot) -{ - return radix_tree_direct_to_ptr(*pslot); -} -/** - * radix_tree_replace_slot - replace item in a slot - * @pslot: pointer to slot, returned by radix_tree_lookup_slot - * @item: new item to store in the slot. - * - * For use with radix_tree_lookup_slot(). Caller must hold tree write locked - * across slot lookup and replacement. - */ -static inline void radix_tree_replace_slot(void **pslot, void *item) -{ - BUG_ON(radix_tree_is_direct_ptr(item)); - rcu_assign_pointer(*pslot, - (void *)((unsigned long)item | - ((unsigned long)*pslot & RADIX_TREE_DIRECT_PTR))); -} - int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); void *radix_tree_lookup(struct radix_tree_root *, unsigned long); void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); diff --git a/trunk/include/linux/raid/raid5.h b/trunk/include/linux/raid/raid5.h index 03636d7918fe..f13299a15591 100644 --- a/trunk/include/linux/raid/raid5.h +++ b/trunk/include/linux/raid/raid5.h @@ -235,7 +235,7 @@ struct raid5_private_data { */ int active_name; char cache_name[2][20]; - struct kmem_cache *slab_cache; /* for allocating stripes */ + kmem_cache_t *slab_cache; /* for allocating stripes */ int seq_flush, seq_write; int quiesce; diff --git a/trunk/include/linux/reiserfs_fs.h b/trunk/include/linux/reiserfs_fs.h index d0e4dce33ad5..7bc6bfb86253 100644 --- a/trunk/include/linux/reiserfs_fs.h +++ b/trunk/include/linux/reiserfs_fs.h @@ -739,7 +739,7 @@ struct block_head { #define PUT_B_FREE_SPACE(p_s_bh,val) do { set_blkh_free_space(B_BLK_HEAD(p_s_bh),val); } while (0) /* Get right delimiting key. -- little endian */ -#define B_PRIGHT_DELIM_KEY(p_s_bh) (&(blk_right_delim_key(B_BLK_HEAD(p_s_bh)))) +#define B_PRIGHT_DELIM_KEY(p_s_bh) (&(blk_right_delim_key(B_BLK_HEAD(p_s_bh)) /* Does the buffer contain a disk leaf. */ #define B_IS_ITEMS_LEVEL(p_s_bh) (B_LEVEL(p_s_bh) == DISK_LEAF_NODE_LEVEL) diff --git a/trunk/include/linux/relay.h b/trunk/include/linux/relay.h index c6a48bfc8b14..0e3d91b76996 100644 --- a/trunk/include/linux/relay.h +++ b/trunk/include/linux/relay.h @@ -274,7 +274,7 @@ static inline void subbuf_start_reserve(struct rchan_buf *buf, /* * exported relay file operations, kernel/relay.c */ -extern const struct file_operations relay_file_operations; +extern struct file_operations relay_file_operations; #endif /* _LINUX_RELAY_H */ diff --git a/trunk/include/linux/rmap.h b/trunk/include/linux/rmap.h index 36f850373d2c..db2c1df4fef9 100644 --- a/trunk/include/linux/rmap.h +++ b/trunk/include/linux/rmap.h @@ -30,11 +30,11 @@ struct anon_vma { #ifdef CONFIG_MMU -extern struct kmem_cache *anon_vma_cachep; +extern kmem_cache_t *anon_vma_cachep; static inline struct anon_vma *anon_vma_alloc(void) { - return kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); + return kmem_cache_alloc(anon_vma_cachep, SLAB_KERNEL); } static inline void anon_vma_free(struct anon_vma *anon_vma) diff --git a/trunk/include/linux/rtmutex.h b/trunk/include/linux/rtmutex.h index b0090e9f7884..5d41dee82f80 100644 --- a/trunk/include/linux/rtmutex.h +++ b/trunk/include/linux/rtmutex.h @@ -63,7 +63,7 @@ struct hrtimer_sleeper; #endif #define __RT_MUTEX_INITIALIZER(mutexname) \ - { .wait_lock = __SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ + { .wait_lock = SPIN_LOCK_UNLOCKED \ , .wait_list = PLIST_HEAD_INIT(mutexname.wait_list, mutexname.wait_lock) \ , .owner = NULL \ __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} diff --git a/trunk/include/linux/rwsem-spinlock.h b/trunk/include/linux/rwsem-spinlock.h index 813cee13da0d..ae1fcadd598e 100644 --- a/trunk/include/linux/rwsem-spinlock.h +++ b/trunk/include/linux/rwsem-spinlock.h @@ -44,8 +44,7 @@ struct rw_semaphore { #endif #define __RWSEM_INITIALIZER(name) \ -{ 0, __SPIN_LOCK_UNLOCKED(name.wait_lock), LIST_HEAD_INIT((name).wait_list) \ - __RWSEM_DEP_MAP_INIT(name) } +{ 0, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } #define DECLARE_RWSEM(name) \ struct rw_semaphore name = __RWSEM_INITIALIZER(name) diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index dede82c63445..eafe4a7b8237 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -194,16 +194,7 @@ extern void init_idle(struct task_struct *idle, int cpu); extern cpumask_t nohz_cpu_mask; -/* - * Only dump TASK_* tasks. (-1 for all tasks) - */ -extern void show_state_filter(unsigned long state_filter); - -static inline void show_state(void) -{ - show_state_filter(-1); -} - +extern void show_state(void); extern void show_regs(struct pt_regs *); /* @@ -347,23 +338,15 @@ struct mm_struct { unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ + unsigned dumpable:2; cpumask_t cpu_vm_mask; /* Architecture-specific MM context */ mm_context_t context; - /* Swap token stuff */ - /* - * Last value of global fault stamp as seen by this process. - * In other words, this value gives an indication of how long - * it has been since this task got the token. - * Look at mm/thrash.c - */ - unsigned int faultstamp; - unsigned int token_priority; - unsigned int last_interval; - - unsigned char dumpable:2; + /* Token based thrashing protection. */ + unsigned long swap_token_time; + char recent_pagein; /* coredumping support */ int core_waiters; @@ -573,7 +556,7 @@ struct sched_info { #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ #ifdef CONFIG_SCHEDSTATS -extern const struct file_operations proc_schedstat_operations; +extern struct file_operations proc_schedstat_operations; #endif /* CONFIG_SCHEDSTATS */ #ifdef CONFIG_TASK_DELAY_ACCT @@ -1305,6 +1288,7 @@ extern int kill_pgrp(struct pid *pid, int sig, int priv); extern int kill_pid(struct pid *pid, int sig, int priv); extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp); extern int kill_pg_info(int, struct siginfo *, pid_t); +extern int kill_proc_info(int, struct siginfo *, pid_t); extern void do_notify_parent(struct task_struct *, int); extern void force_sig(int, struct task_struct *); extern void force_sig_specific(int, struct task_struct *); @@ -1626,6 +1610,87 @@ extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls); extern void normalize_rt_tasks(void); +#ifdef CONFIG_PM +/* + * Check if a process has been frozen + */ +static inline int frozen(struct task_struct *p) +{ + return p->flags & PF_FROZEN; +} + +/* + * Check if there is a request to freeze a process + */ +static inline int freezing(struct task_struct *p) +{ + return p->flags & PF_FREEZE; +} + +/* + * Request that a process be frozen + * FIXME: SMP problem. We may not modify other process' flags! + */ +static inline void freeze(struct task_struct *p) +{ + p->flags |= PF_FREEZE; +} + +/* + * Sometimes we may need to cancel the previous 'freeze' request + */ +static inline void do_not_freeze(struct task_struct *p) +{ + p->flags &= ~PF_FREEZE; +} + +/* + * Wake up a frozen process + */ +static inline int thaw_process(struct task_struct *p) +{ + if (frozen(p)) { + p->flags &= ~PF_FROZEN; + wake_up_process(p); + return 1; + } + return 0; +} + +/* + * freezing is complete, mark process as frozen + */ +static inline void frozen_process(struct task_struct *p) +{ + p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN; +} + +extern void refrigerator(void); +extern int freeze_processes(void); +extern void thaw_processes(void); + +static inline int try_to_freeze(void) +{ + if (freezing(current)) { + refrigerator(); + return 1; + } else + return 0; +} +#else +static inline int frozen(struct task_struct *p) { return 0; } +static inline int freezing(struct task_struct *p) { return 0; } +static inline void freeze(struct task_struct *p) { BUG(); } +static inline int thaw_process(struct task_struct *p) { return 1; } +static inline void frozen_process(struct task_struct *p) { BUG(); } + +static inline void refrigerator(void) {} +static inline int freeze_processes(void) { BUG(); return 0; } +static inline void thaw_processes(void) {} + +static inline int try_to_freeze(void) { return 0; } + +#endif /* CONFIG_PM */ #endif /* __KERNEL__ */ #endif diff --git a/trunk/include/linux/screen_info.h b/trunk/include/linux/screen_info.h index b02308ee7667..2925e66a6732 100644 --- a/trunk/include/linux/screen_info.h +++ b/trunk/include/linux/screen_info.h @@ -42,8 +42,7 @@ struct screen_info { u16 pages; /* 0x32 */ u16 vesa_attributes; /* 0x34 */ u32 capabilities; /* 0x36 */ - /* 0x3a -- 0x3b reserved for future expansion */ - /* 0x3c -- 0x3f micro stack for relocatable kernels */ + /* 0x3a -- 0x3f reserved for future expansion */ }; extern struct screen_info screen_info; diff --git a/trunk/include/linux/seq_file.h b/trunk/include/linux/seq_file.h index 3e3cccbb1cac..b95f6eb7254c 100644 --- a/trunk/include/linux/seq_file.h +++ b/trunk/include/linux/seq_file.h @@ -20,7 +20,7 @@ struct seq_file { loff_t index; loff_t version; struct mutex lock; - const struct seq_operations *op; + struct seq_operations *op; void *private; }; @@ -31,7 +31,7 @@ struct seq_operations { int (*show) (struct seq_file *m, void *v); }; -int seq_open(struct file *, const struct seq_operations *); +int seq_open(struct file *, struct seq_operations *); ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); loff_t seq_lseek(struct file *, loff_t, int); int seq_release(struct inode *, struct file *); diff --git a/trunk/include/linux/serial_8250.h b/trunk/include/linux/serial_8250.h index 71310d80c09a..8e9681413726 100644 --- a/trunk/include/linux/serial_8250.h +++ b/trunk/include/linux/serial_8250.h @@ -41,7 +41,6 @@ enum { PLAT8250_DEV_FOURPORT, PLAT8250_DEV_ACCENT, PLAT8250_DEV_BOCA, - PLAT8250_DEV_EXAR_ST16C554, PLAT8250_DEV_HUB6, PLAT8250_DEV_MCA, PLAT8250_DEV_AU1X00, diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index 827672136646..463ab953b092 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -132,8 +132,6 @@ #define PORT_S3C2412 73 -/* Xilinx uartlite */ -#define PORT_UARTLITE 74 #ifdef __KERNEL__ diff --git a/trunk/include/linux/signal.h b/trunk/include/linux/signal.h index 14749056dd63..117135e33d67 100644 --- a/trunk/include/linux/signal.h +++ b/trunk/include/linux/signal.h @@ -241,8 +241,6 @@ extern int sigprocmask(int, sigset_t *, sigset_t *); struct pt_regs; extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); -extern struct kmem_cache *sighand_cachep; - #endif /* __KERNEL__ */ #endif /* _LINUX_SIGNAL_H */ diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 4ff3940210d8..a05a5f7c0b73 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -332,20 +332,20 @@ struct sk_buff { extern void kfree_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); extern struct sk_buff *__alloc_skb(unsigned int size, - gfp_t priority, int fclone, int node); + gfp_t priority, int fclone); static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 0, -1); + return __alloc_skb(size, priority, 0); } static inline struct sk_buff *alloc_skb_fclone(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 1, -1); + return __alloc_skb(size, priority, 1); } -extern struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp, +extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, unsigned int size, gfp_t priority); extern void kfree_skbmem(struct sk_buff *skb); diff --git a/trunk/include/linux/slab.h b/trunk/include/linux/slab.h index 2271886744f8..c4947b8a2c03 100644 --- a/trunk/include/linux/slab.h +++ b/trunk/include/linux/slab.h @@ -7,17 +7,27 @@ #ifndef _LINUX_SLAB_H #define _LINUX_SLAB_H -#ifdef __KERNEL__ +#if defined(__KERNEL__) -#include -#include -#include -#include /* kmalloc_sizes.h needs PAGE_SIZE */ -#include /* kmalloc_sizes.h needs L1_CACHE_BYTES */ -#include +typedef struct kmem_cache kmem_cache_t; -/* kmem_cache_t exists for legacy reasons and is not used by code in mm */ -typedef struct kmem_cache kmem_cache_t __deprecated; +#include +#include +#include +#include /* kmalloc_sizes.h needs PAGE_SIZE */ +#include /* kmalloc_sizes.h needs L1_CACHE_BYTES */ + +/* flags for kmem_cache_alloc() */ +#define SLAB_NOFS GFP_NOFS +#define SLAB_NOIO GFP_NOIO +#define SLAB_ATOMIC GFP_ATOMIC +#define SLAB_USER GFP_USER +#define SLAB_KERNEL GFP_KERNEL +#define SLAB_DMA GFP_DMA + +#define SLAB_LEVEL_MASK GFP_LEVEL_MASK + +#define SLAB_NO_GROW __GFP_NO_GROW /* don't grow a cache */ /* flags to pass to kmem_cache_create(). * The first 3 are only valid when the allocator as been build @@ -47,23 +57,22 @@ typedef struct kmem_cache kmem_cache_t __deprecated; /* prototypes */ extern void __init kmem_cache_init(void); -extern struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, - unsigned long, - void (*)(void *, struct kmem_cache *, unsigned long), - void (*)(void *, struct kmem_cache *, unsigned long)); -extern void kmem_cache_destroy(struct kmem_cache *); -extern int kmem_cache_shrink(struct kmem_cache *); -extern void *kmem_cache_alloc(struct kmem_cache *, gfp_t); +extern kmem_cache_t *kmem_cache_create(const char *, size_t, size_t, unsigned long, + void (*)(void *, kmem_cache_t *, unsigned long), + void (*)(void *, kmem_cache_t *, unsigned long)); +extern void kmem_cache_destroy(kmem_cache_t *); +extern int kmem_cache_shrink(kmem_cache_t *); +extern void *kmem_cache_alloc(kmem_cache_t *, gfp_t); extern void *kmem_cache_zalloc(struct kmem_cache *, gfp_t); -extern void kmem_cache_free(struct kmem_cache *, void *); -extern unsigned int kmem_cache_size(struct kmem_cache *); -extern const char *kmem_cache_name(struct kmem_cache *); +extern void kmem_cache_free(kmem_cache_t *, void *); +extern unsigned int kmem_cache_size(kmem_cache_t *); +extern const char *kmem_cache_name(kmem_cache_t *); /* Size description struct for general caches. */ struct cache_sizes { - size_t cs_size; - struct kmem_cache *cs_cachep; - struct kmem_cache *cs_dmacachep; + size_t cs_size; + kmem_cache_t *cs_cachep; + kmem_cache_t *cs_dmacachep; }; extern struct cache_sizes malloc_sizes[]; @@ -202,7 +211,7 @@ extern unsigned int ksize(const void *); extern int slab_is_available(void); #ifdef CONFIG_NUMA -extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); +extern void *kmem_cache_alloc_node(kmem_cache_t *, gfp_t flags, int node); extern void *__kmalloc_node(size_t size, gfp_t flags, int node); static inline void *kmalloc_node(size_t size, gfp_t flags, int node) @@ -227,27 +236,8 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node) } return __kmalloc_node(size, flags, node); } - -/* - * kmalloc_node_track_caller is a special version of kmalloc_node that - * records the calling function of the routine calling it for slab leak - * tracking instead of just the calling function (confusing, eh?). - * It's useful when the call to kmalloc_node comes from a widely-used - * standard allocator where we care about the real place the memory - * allocation request comes from. - */ -#ifndef CONFIG_DEBUG_SLAB -#define kmalloc_node_track_caller(size, flags, node) \ - __kmalloc_node(size, flags, node) #else -extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *); -#define kmalloc_node_track_caller(size, flags, node) \ - __kmalloc_node_track_caller(size, flags, node, \ - __builtin_return_address(0)) -#endif -#else /* CONFIG_NUMA */ -static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep, - gfp_t flags, int node) +static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int node) { return kmem_cache_alloc(cachep, flags); } @@ -255,13 +245,10 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node) { return kmalloc(size, flags); } - -#define kmalloc_node_track_caller(size, flags, node) \ - kmalloc_track_caller(size, flags) #endif extern int FASTCALL(kmem_cache_reap(int)); -extern int FASTCALL(kmem_ptr_validate(struct kmem_cache *cachep, void *ptr)); +extern int FASTCALL(kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)); #else /* CONFIG_SLOB */ @@ -296,10 +283,17 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) #define kzalloc(s, f) __kzalloc(s, f) #define kmalloc_track_caller kmalloc -#define kmalloc_node_track_caller kmalloc_node - #endif /* CONFIG_SLOB */ +/* System wide caches */ +extern kmem_cache_t *vm_area_cachep; +extern kmem_cache_t *names_cachep; +extern kmem_cache_t *files_cachep; +extern kmem_cache_t *filp_cachep; +extern kmem_cache_t *fs_cachep; +extern kmem_cache_t *sighand_cachep; +extern kmem_cache_t *bio_cachep; + #endif /* __KERNEL__ */ #endif /* _LINUX_SLAB_H */ diff --git a/trunk/include/linux/smp.h b/trunk/include/linux/smp.h index 7ba23ec8211b..51649987f691 100644 --- a/trunk/include/linux/smp.h +++ b/trunk/include/linux/smp.h @@ -99,13 +99,6 @@ static inline int up_smp_call_function(void) static inline void smp_send_reschedule(int cpu) { } #define num_booting_cpus() 1 #define smp_prepare_boot_cpu() do {} while (0) -static inline int smp_call_function_single(int cpuid, void (*func) (void *info), - void *info, int retry, int wait) -{ - /* Disable interrupts here? */ - func(info); - return 0; -} #endif /* !SMP */ diff --git a/trunk/include/linux/spinlock.h b/trunk/include/linux/spinlock.h index 94b767d64275..8451052ca66f 100644 --- a/trunk/include/linux/spinlock.h +++ b/trunk/include/linux/spinlock.h @@ -52,7 +52,6 @@ #include #include #include -#include #include diff --git a/trunk/include/linux/start_kernel.h b/trunk/include/linux/start_kernel.h deleted file mode 100644 index d3e5f2756545..000000000000 --- a/trunk/include/linux/start_kernel.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _LINUX_START_KERNEL_H -#define _LINUX_START_KERNEL_H - -#include -#include - -/* Define the prototype for start_kernel here, rather than cluttering - up something else. */ - -extern asmlinkage void __init start_kernel(void); - -#endif /* _LINUX_START_KERNEL_H */ diff --git a/trunk/include/linux/sunrpc/sched.h b/trunk/include/linux/sunrpc/sched.h index 0746c3b16f3a..f399c138f79d 100644 --- a/trunk/include/linux/sunrpc/sched.h +++ b/trunk/include/linux/sunrpc/sched.h @@ -222,7 +222,7 @@ struct rpc_wait_queue { #ifndef RPC_DEBUG # define RPC_WAITQ_INIT(var,qname) { \ - .lock = __SPIN_LOCK_UNLOCKED(var.lock), \ + .lock = SPIN_LOCK_UNLOCKED, \ .tasks = { \ [0] = LIST_HEAD_INIT(var.tasks[0]), \ [1] = LIST_HEAD_INIT(var.tasks[1]), \ @@ -231,7 +231,7 @@ struct rpc_wait_queue { } #else # define RPC_WAITQ_INIT(var,qname) { \ - .lock = __SPIN_LOCK_UNLOCKED(var.lock), \ + .lock = SPIN_LOCK_UNLOCKED, \ .tasks = { \ [0] = LIST_HEAD_INIT(var.tasks[0]), \ [1] = LIST_HEAD_INIT(var.tasks[1]), \ diff --git a/trunk/include/linux/suspend.h b/trunk/include/linux/suspend.h index bf99bd49f8ef..b1237f16ecde 100644 --- a/trunk/include/linux/suspend.h +++ b/trunk/include/linux/suspend.h @@ -9,13 +9,10 @@ #include #include -/* struct pbe is used for creating lists of pages that should be restored - * atomically during the resume from disk, because the page frames they have - * occupied before the suspend are in use. - */ +/* page backup entry */ struct pbe { - void *address; /* address of the copy */ - void *orig_address; /* original address of a page */ + unsigned long address; /* address of the copy */ + unsigned long orig_address; /* original address of page */ struct pbe *next; }; diff --git a/trunk/include/linux/swap.h b/trunk/include/linux/swap.h index add51cebc8d9..e7c36ba2a2db 100644 --- a/trunk/include/linux/swap.h +++ b/trunk/include/linux/swap.h @@ -218,6 +218,8 @@ extern void swap_unplug_io_fn(struct backing_dev_info *, struct page *); /* linux/mm/page_io.c */ extern int swap_readpage(struct file *, struct page *); extern int swap_writepage(struct page *page, struct writeback_control *wbc); +extern int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page, + struct bio **bio_chain); extern int end_swap_bio_read(struct bio *bio, unsigned int bytes_done, int err); /* linux/mm/swap_state.c */ @@ -245,10 +247,9 @@ extern int swap_duplicate(swp_entry_t); extern int valid_swaphandles(swp_entry_t, unsigned long *); extern void swap_free(swp_entry_t); extern void free_swap_and_cache(swp_entry_t); -extern int swap_type_of(dev_t, sector_t); +extern int swap_type_of(dev_t); extern unsigned int count_swap_pages(int, int); extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t); -extern sector_t swapdev_block(int, pgoff_t); extern struct swap_info_struct *get_swap_info_struct(unsigned); extern int can_share_swap_page(struct page *); extern int remove_exclusive_swap_page(struct page *); @@ -258,6 +259,7 @@ extern spinlock_t swap_lock; /* linux/mm/thrash.c */ extern struct mm_struct * swap_token_mm; +extern unsigned long swap_token_default_timeout; extern void grab_swap_token(void); extern void __put_swap_token(struct mm_struct *); diff --git a/trunk/include/linux/taskstats_kern.h b/trunk/include/linux/taskstats_kern.h index 7e9680f4afdd..6562a2050a25 100644 --- a/trunk/include/linux/taskstats_kern.h +++ b/trunk/include/linux/taskstats_kern.h @@ -12,27 +12,64 @@ #include #ifdef CONFIG_TASKSTATS -extern struct kmem_cache *taskstats_cache; +extern kmem_cache_t *taskstats_cache; extern struct mutex taskstats_exit_mutex; +static inline void taskstats_exit_free(struct taskstats *tidstats) +{ + if (tidstats) + kmem_cache_free(taskstats_cache, tidstats); +} + static inline void taskstats_tgid_init(struct signal_struct *sig) { sig->stats = NULL; } +static inline void taskstats_tgid_alloc(struct task_struct *tsk) +{ + struct signal_struct *sig = tsk->signal; + struct taskstats *stats; + + if (sig->stats != NULL) + return; + + /* No problem if kmem_cache_zalloc() fails */ + stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL); + + spin_lock_irq(&tsk->sighand->siglock); + if (!sig->stats) { + sig->stats = stats; + stats = NULL; + } + spin_unlock_irq(&tsk->sighand->siglock); + + if (stats) + kmem_cache_free(taskstats_cache, stats); +} + static inline void taskstats_tgid_free(struct signal_struct *sig) { if (sig->stats) kmem_cache_free(taskstats_cache, sig->stats); } -extern void taskstats_exit(struct task_struct *, int group_dead); +extern void taskstats_exit_alloc(struct taskstats **, unsigned int *); +extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int); extern void taskstats_init_early(void); #else -static inline void taskstats_exit(struct task_struct *tsk, int group_dead) +static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu) +{} +static inline void taskstats_exit_free(struct taskstats *ptidstats) +{} +static inline void taskstats_exit_send(struct task_struct *tsk, + struct taskstats *tidstats, + int group_dead, unsigned int cpu) {} static inline void taskstats_tgid_init(struct signal_struct *sig) {} +static inline void taskstats_tgid_alloc(struct task_struct *tsk) +{} static inline void taskstats_tgid_free(struct signal_struct *sig) {} static inline void taskstats_init_early(void) diff --git a/trunk/include/linux/uaccess.h b/trunk/include/linux/uaccess.h index 975c963e5789..a48d7f11c7be 100644 --- a/trunk/include/linux/uaccess.h +++ b/trunk/include/linux/uaccess.h @@ -1,43 +1,8 @@ #ifndef __LINUX_UACCESS_H__ #define __LINUX_UACCESS_H__ -#include #include -/* - * These routines enable/disable the pagefault handler in that - * it will not take any locks and go straight to the fixup table. - * - * They have great resemblance to the preempt_disable/enable calls - * and in fact they are identical; this is because currently there is - * no other way to make the pagefault handlers do this. So we do - * disable preemption but we don't necessarily care about that. - */ -static inline void pagefault_disable(void) -{ - inc_preempt_count(); - /* - * make sure to have issued the store before a pagefault - * can hit. - */ - barrier(); -} - -static inline void pagefault_enable(void) -{ - /* - * make sure to issue those last loads/stores before enabling - * the pagefault handler again. - */ - barrier(); - dec_preempt_count(); - /* - * make sure we do.. - */ - barrier(); - preempt_check_resched(); -} - #ifndef ARCH_HAS_NOCACHE_UACCESS static inline unsigned long __copy_from_user_inatomic_nocache(void *to, @@ -65,22 +30,14 @@ static inline unsigned long __copy_from_user_nocache(void *to, * do_page_fault() doesn't attempt to take mmap_sem. This makes * probe_kernel_address() suitable for use within regions where the caller * already holds mmap_sem, or other locks which nest inside mmap_sem. - * This must be a macro because __get_user() needs to know the types of the - * args. - * - * We don't include enough header files to be able to do the set_fs(). We - * require that the probe_kernel_address() caller will do that. */ #define probe_kernel_address(addr, retval) \ ({ \ long ret; \ - mm_segment_t old_fs = get_fs(); \ \ - set_fs(KERNEL_DS); \ - pagefault_disable(); \ - ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \ - pagefault_enable(); \ - set_fs(old_fs); \ + inc_preempt_count(); \ + ret = __get_user(retval, addr); \ + dec_preempt_count(); \ ret; \ }) diff --git a/trunk/include/linux/workqueue.h b/trunk/include/linux/workqueue.h index f0cb1df7b475..4a3ea83c6d16 100644 --- a/trunk/include/linux/workqueue.h +++ b/trunk/include/linux/workqueue.h @@ -147,11 +147,9 @@ struct execute_work { extern struct workqueue_struct *__create_workqueue(const char *name, - int singlethread, - int freezeable); -#define create_workqueue(name) __create_workqueue((name), 0, 0) -#define create_freezeable_workqueue(name) __create_workqueue((name), 0, 1) -#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0) + int singlethread); +#define create_workqueue(name) __create_workqueue((name), 0) +#define create_singlethread_workqueue(name) __create_workqueue((name), 1) extern void destroy_workqueue(struct workqueue_struct *wq); diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 62b7e7598e9a..e156e38e4ac3 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -98,7 +98,7 @@ struct dst_ops int entry_size; atomic_t entries; - struct kmem_cache *kmem_cachep; + kmem_cache_t *kmem_cachep; }; #ifdef __KERNEL__ diff --git a/trunk/include/net/inet_hashtables.h b/trunk/include/net/inet_hashtables.h index 34cc76e3ddb4..a9eb2eaf094e 100644 --- a/trunk/include/net/inet_hashtables.h +++ b/trunk/include/net/inet_hashtables.h @@ -125,7 +125,7 @@ struct inet_hashinfo { rwlock_t lhash_lock ____cacheline_aligned; atomic_t lhash_users; wait_queue_head_t lhash_wait; - struct kmem_cache *bind_bucket_cachep; + kmem_cache_t *bind_bucket_cachep; }; static inline struct inet_ehash_bucket *inet_ehash_bucket( @@ -136,10 +136,10 @@ static inline struct inet_ehash_bucket *inet_ehash_bucket( } extern struct inet_bind_bucket * - inet_bind_bucket_create(struct kmem_cache *cachep, + inet_bind_bucket_create(kmem_cache_t *cachep, struct inet_bind_hashbucket *head, const unsigned short snum); -extern void inet_bind_bucket_destroy(struct kmem_cache *cachep, +extern void inet_bind_bucket_destroy(kmem_cache_t *cachep, struct inet_bind_bucket *tb); static inline int inet_bhashfn(const __u16 lport, const int bhash_size) diff --git a/trunk/include/net/neighbour.h b/trunk/include/net/neighbour.h index 23967031ddb7..c8aacbd2e333 100644 --- a/trunk/include/net/neighbour.h +++ b/trunk/include/net/neighbour.h @@ -160,7 +160,7 @@ struct neigh_table atomic_t entries; rwlock_t lock; unsigned long last_rand; - struct kmem_cache *kmem_cachep; + kmem_cache_t *kmem_cachep; struct neigh_statistics *stats; struct neighbour **hash_buckets; unsigned int hash_mask; diff --git a/trunk/include/net/netfilter/nf_conntrack_expect.h b/trunk/include/net/netfilter/nf_conntrack_expect.h index 41bcc9eb4206..cef3136e22a3 100644 --- a/trunk/include/net/netfilter/nf_conntrack_expect.h +++ b/trunk/include/net/netfilter/nf_conntrack_expect.h @@ -7,7 +7,7 @@ #include extern struct list_head nf_conntrack_expect_list; -extern struct kmem_cache *nf_conntrack_expect_cachep; +extern kmem_cache_t *nf_conntrack_expect_cachep; extern struct file_operations exp_file_ops; struct nf_conntrack_expect diff --git a/trunk/include/net/request_sock.h b/trunk/include/net/request_sock.h index 7aed02ce2b65..e37baaf2080b 100644 --- a/trunk/include/net/request_sock.h +++ b/trunk/include/net/request_sock.h @@ -29,7 +29,7 @@ struct proto; struct request_sock_ops { int family; int obj_size; - struct kmem_cache *slab; + kmem_cache_t *slab; int (*rtx_syn_ack)(struct sock *sk, struct request_sock *req, struct dst_entry *dst); @@ -60,7 +60,7 @@ struct request_sock { static inline struct request_sock *reqsk_alloc(const struct request_sock_ops *ops) { - struct request_sock *req = kmem_cache_alloc(ops->slab, GFP_ATOMIC); + struct request_sock *req = kmem_cache_alloc(ops->slab, SLAB_ATOMIC); if (req != NULL) req->rsk_ops = ops; diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 03684e702d13..fe3a33fad03f 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -571,7 +571,7 @@ struct proto { int *sysctl_rmem; int max_header; - struct kmem_cache *slab; + kmem_cache_t *slab; unsigned int obj_size; atomic_t *orphan_count; @@ -746,25 +746,6 @@ static inline int sk_stream_wmem_schedule(struct sock *sk, int size) */ #define sock_owned_by_user(sk) ((sk)->sk_lock.owner) -/* - * Macro so as to not evaluate some arguments when - * lockdep is not enabled. - * - * Mark both the sk_lock and the sk_lock.slock as a - * per-address-family lock class. - */ -#define sock_lock_init_class_and_name(sk, sname, skey, name, key) \ -do { \ - sk->sk_lock.owner = NULL; \ - init_waitqueue_head(&sk->sk_lock.wq); \ - spin_lock_init(&(sk)->sk_lock.slock); \ - debug_check_no_locks_freed((void *)&(sk)->sk_lock, \ - sizeof((sk)->sk_lock)); \ - lockdep_set_class_and_name(&(sk)->sk_lock.slock, \ - (skey), (sname)); \ - lockdep_init_map(&(sk)->sk_lock.dep_map, (name), (key), 0); \ -} while (0) - extern void FASTCALL(lock_sock_nested(struct sock *sk, int subclass)); static inline void lock_sock(struct sock *sk) diff --git a/trunk/include/net/timewait_sock.h b/trunk/include/net/timewait_sock.h index 1e1ee3253fd8..d7a306ea560d 100644 --- a/trunk/include/net/timewait_sock.h +++ b/trunk/include/net/timewait_sock.h @@ -15,7 +15,7 @@ #include struct timewait_sock_ops { - struct kmem_cache *twsk_slab; + kmem_cache_t *twsk_slab; unsigned int twsk_obj_size; int (*twsk_unique)(struct sock *sk, struct sock *sktw, void *twp); diff --git a/trunk/include/scsi/libsas.h b/trunk/include/scsi/libsas.h index 0c775fceb675..9233ed5de664 100644 --- a/trunk/include/scsi/libsas.h +++ b/trunk/include/scsi/libsas.h @@ -557,7 +557,7 @@ struct sas_task { static inline struct sas_task *sas_alloc_task(gfp_t flags) { - extern struct kmem_cache *sas_task_cache; + extern kmem_cache_t *sas_task_cache; struct sas_task *task = kmem_cache_alloc(sas_task_cache, flags); if (task) { @@ -575,7 +575,7 @@ static inline struct sas_task *sas_alloc_task(gfp_t flags) static inline void sas_free_task(struct sas_task *task) { if (task) { - extern struct kmem_cache *sas_task_cache; + extern kmem_cache_t *sas_task_cache; BUG_ON(!list_empty(&task->list)); kmem_cache_free(sas_task_cache, task); } diff --git a/trunk/init/do_mounts_initrd.c b/trunk/init/do_mounts_initrd.c index 2cfd7cb36e79..919a80cb322e 100644 --- a/trunk/init/do_mounts_initrd.c +++ b/trunk/init/do_mounts_initrd.c @@ -6,7 +6,6 @@ #include #include #include -#include #include "do_mounts.h" diff --git a/trunk/init/initramfs.c b/trunk/init/initramfs.c index 85f04037ade1..d28c1094d7e5 100644 --- a/trunk/init/initramfs.c +++ b/trunk/init/initramfs.c @@ -182,10 +182,6 @@ static int __init do_collect(void) static int __init do_header(void) { - if (memcmp(collected, "070707", 6)==0) { - error("incorrect cpio method used: use -H newc option"); - return 1; - } if (memcmp(collected, "070701", 6)) { error("no cpio magic"); return 1; diff --git a/trunk/init/main.c b/trunk/init/main.c index 1174ae3aec8c..36f608a7cfba 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -74,10 +73,6 @@ #error Sorry, your GCC is too old. It builds incorrect kernels. #endif -#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0 -#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended. -#endif - static int init(void *); extern void init_IRQ(void); diff --git a/trunk/ipc/compat.c b/trunk/ipc/compat.c index fa18141539fb..4d20cfd38f0a 100644 --- a/trunk/ipc/compat.c +++ b/trunk/ipc/compat.c @@ -115,6 +115,7 @@ struct compat_shm_info { extern int sem_ctls[]; #define sc_semopm (sem_ctls[2]) +#define MAXBUF (64*1024) static inline int compat_ipc_parse_version(int *cmd) { @@ -306,30 +307,35 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr) long compat_sys_msgsnd(int first, int second, int third, void __user *uptr) { + struct msgbuf __user *p; struct compat_msgbuf __user *up = uptr; long type; if (first < 0) return -EINVAL; - if (second < 0) + if (second < 0 || (second >= MAXBUF - sizeof(struct msgbuf))) return -EINVAL; - if (get_user(type, &up->mtype)) + p = compat_alloc_user_space(second + sizeof(struct msgbuf)); + if (get_user(type, &up->mtype) || + put_user(type, &p->mtype) || + copy_in_user(p->mtext, up->mtext, second)) return -EFAULT; - return do_msgsnd(first, type, up->mtext, second, third); + return sys_msgsnd(first, p, second, third); } long compat_sys_msgrcv(int first, int second, int msgtyp, int third, int version, void __user *uptr) { + struct msgbuf __user *p; struct compat_msgbuf __user *up; long type; int err; if (first < 0) return -EINVAL; - if (second < 0) + if (second < 0 || (second >= MAXBUF - sizeof(struct msgbuf))) return -EINVAL; if (!version) { @@ -343,11 +349,14 @@ long compat_sys_msgrcv(int first, int second, int msgtyp, int third, uptr = compat_ptr(ipck.msgp); msgtyp = ipck.msgtyp; } - up = uptr; - err = do_msgrcv(first, &type, up->mtext, second, msgtyp, third); + p = compat_alloc_user_space(second + sizeof(struct msgbuf)); + err = sys_msgrcv(first, p, second, msgtyp, third); if (err < 0) goto out; - if (put_user(type, &up->mtype)) + up = uptr; + if (get_user(type, &p->mtype) || + put_user(type, &up->mtype) || + copy_in_user(up->mtext, p->mtext, err)) err = -EFAULT; out: return err; diff --git a/trunk/ipc/mqueue.c b/trunk/ipc/mqueue.c index 3acc1661e517..7c274002c9f5 100644 --- a/trunk/ipc/mqueue.c +++ b/trunk/ipc/mqueue.c @@ -90,7 +90,7 @@ static struct super_operations mqueue_super_ops; static void remove_notification(struct mqueue_inode_info *info); static spinlock_t mq_lock; -static struct kmem_cache *mqueue_inode_cachep; +static kmem_cache_t *mqueue_inode_cachep; static struct vfsmount *mqueue_mnt; static unsigned int queues_count; @@ -211,7 +211,7 @@ static int mqueue_get_sb(struct file_system_type *fs_type, return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); } -static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; @@ -224,7 +224,7 @@ static struct inode *mqueue_alloc_inode(struct super_block *sb) { struct mqueue_inode_info *ei; - ei = kmem_cache_alloc(mqueue_inode_cachep, GFP_KERNEL); + ei = kmem_cache_alloc(mqueue_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; diff --git a/trunk/ipc/msg.c b/trunk/ipc/msg.c index a388824740e7..1266b1d0c8e3 100644 --- a/trunk/ipc/msg.c +++ b/trunk/ipc/msg.c @@ -626,11 +626,12 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) return 0; } -long do_msgsnd(int msqid, long mtype, void __user *mtext, - size_t msgsz, int msgflg) +asmlinkage long +sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) { struct msg_queue *msq; struct msg_msg *msg; + long mtype; int err; struct ipc_namespace *ns; @@ -638,10 +639,12 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0) return -EINVAL; + if (get_user(mtype, &msgp->mtype)) + return -EFAULT; if (mtype < 1) return -EINVAL; - msg = load_msg(mtext, msgsz); + msg = load_msg(msgp->mtext, msgsz); if (IS_ERR(msg)) return PTR_ERR(msg); @@ -720,16 +723,6 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, return err; } -asmlinkage long -sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) -{ - long mtype; - - if (get_user(mtype, &msgp->mtype)) - return -EFAULT; - return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); -} - static inline int convert_mode(long *msgtyp, int msgflg) { /* @@ -749,8 +742,8 @@ static inline int convert_mode(long *msgtyp, int msgflg) return SEARCH_EQUAL; } -long do_msgrcv(int msqid, long *pmtype, void __user *mtext, - size_t msgsz, long msgtyp, int msgflg) +asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, + long msgtyp, int msgflg) { struct msg_queue *msq; struct msg_msg *msg; @@ -896,30 +889,15 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, return PTR_ERR(msg); msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; - *pmtype = msg->m_type; - if (store_msg(mtext, msg, msgsz)) + if (put_user (msg->m_type, &msgp->mtype) || + store_msg(msgp->mtext, msg, msgsz)) { msgsz = -EFAULT; - + } free_msg(msg); return msgsz; } -asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, - long msgtyp, int msgflg) -{ - long err, mtype; - - err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); - if (err < 0) - goto out; - - if (put_user(mtype, &msgp->mtype)) - err = -EFAULT; -out: - return err; -} - #ifdef CONFIG_PROC_FS static int sysvipc_msg_proc_show(struct seq_file *s, void *it) { diff --git a/trunk/ipc/sem.c b/trunk/ipc/sem.c index d3e12efd55cb..21b3289d640c 100644 --- a/trunk/ipc/sem.c +++ b/trunk/ipc/sem.c @@ -1070,13 +1070,14 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid) ipc_rcu_getref(sma); sem_unlock(sma); - new = kzalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL); + new = (struct sem_undo *) kmalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL); if (!new) { ipc_lock_by_ptr(&sma->sem_perm); ipc_rcu_putref(sma); sem_unlock(sma); return ERR_PTR(-ENOMEM); } + memset(new, 0, sizeof(struct sem_undo) + sizeof(short)*nsems); new->semadj = (short *) &new[1]; new->semid = semid; diff --git a/trunk/kernel/Kconfig.hz b/trunk/kernel/Kconfig.hz index 4af15802ccd4..248e1c396f8b 100644 --- a/trunk/kernel/Kconfig.hz +++ b/trunk/kernel/Kconfig.hz @@ -7,7 +7,7 @@ choice default HZ_250 help Allows the configuration of the timer frequency. It is customary - to have the timer interrupt run at 1000 Hz but 100 Hz may be more + to have the timer interrupt run at 1000 HZ but 100 HZ may be more beneficial for servers and NUMA systems that do not need to have a fast response for user interaction and that may experience bus contention and cacheline bounces as a result of timer interrupts. @@ -19,30 +19,21 @@ choice config HZ_100 bool "100 HZ" help - 100 Hz is a typical choice for servers, SMP and NUMA systems + 100 HZ is a typical choice for servers, SMP and NUMA systems with lots of processors that may show reduced performance if too many timer interrupts are occurring. config HZ_250 bool "250 HZ" help - 250 Hz is a good compromise choice allowing server performance + 250 HZ is a good compromise choice allowing server performance while also showing good interactive responsiveness even - on SMP and NUMA systems. If you are going to be using NTSC video - or multimedia, selected 300Hz instead. - - config HZ_300 - bool "300 HZ" - help - 300 Hz is a good compromise choice allowing server performance - while also showing good interactive responsiveness even - on SMP and NUMA systems and exactly dividing by both PAL and - NTSC frame rates for video and multimedia work. + on SMP and NUMA systems. config HZ_1000 bool "1000 HZ" help - 1000 Hz is the preferred choice for desktop systems and other + 1000 HZ is the preferred choice for desktop systems and other systems requiring fast interactive responses to events. endchoice @@ -51,6 +42,5 @@ config HZ int default 100 if HZ_100 default 250 if HZ_250 - default 300 if HZ_300 default 1000 if HZ_1000 diff --git a/trunk/kernel/acct.c b/trunk/kernel/acct.c index dc12db8600e7..0aad5ca36a81 100644 --- a/trunk/kernel/acct.c +++ b/trunk/kernel/acct.c @@ -89,8 +89,7 @@ struct acct_glbs { struct timer_list timer; }; -static struct acct_glbs acct_globals __cacheline_aligned = - {__SPIN_LOCK_UNLOCKED(acct_globals.lock)}; +static struct acct_glbs acct_globals __cacheline_aligned = {SPIN_LOCK_UNLOCKED}; /* * Called whenever the timer says to check the free space. diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index d9b690ac684b..98106f6078b0 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -57,7 +57,6 @@ #include #include #include -#include #include "audit.h" diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index 2e896f8ae29e..4f40d923af8e 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -636,9 +636,10 @@ static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule) struct audit_rule *rule; int i; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kmalloc(sizeof(*rule), GFP_KERNEL); if (unlikely(!rule)) return NULL; + memset(rule, 0, sizeof(*rule)); rule->flags = krule->flags | krule->listnr; rule->action = krule->action; diff --git a/trunk/kernel/configs.c b/trunk/kernel/configs.c index 8fa1fb28f8a7..f9e31974f4ad 100644 --- a/trunk/kernel/configs.c +++ b/trunk/kernel/configs.c @@ -75,7 +75,7 @@ ikconfig_read_current(struct file *file, char __user *buf, return count; } -static const struct file_operations ikconfig_file_ops = { +static struct file_operations ikconfig_file_ops = { .owner = THIS_MODULE, .read = ikconfig_read_current, }; diff --git a/trunk/kernel/cpu.c b/trunk/kernel/cpu.c index 9124669f4586..272254f20d97 100644 --- a/trunk/kernel/cpu.c +++ b/trunk/kernel/cpu.c @@ -270,7 +270,11 @@ int disable_nonboot_cpus(void) goto out; } } - + error = set_cpus_allowed(current, cpumask_of_cpu(first_cpu)); + if (error) { + printk(KERN_ERR "Could not run on CPU%d\n", first_cpu); + goto out; + } /* We take down all of the non-boot CPUs in one shot to avoid races * with the userspace trying to use the CPU hotplug at the same time */ diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 0a6b4d89f9a0..6313c38c930e 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -729,11 +729,9 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) } /* Remaining checks don't apply to root cpuset */ - if (cur == &top_cpuset) + if ((par = cur->parent) == NULL) return 0; - par = cur->parent; - /* We must be a subset of our parent cpuset */ if (!is_cpuset_subset(trial, par)) return -EACCES; @@ -1062,7 +1060,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf) cpu_exclusive_changed = (is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs)); mutex_lock(&callback_mutex); - cs->flags = trialcs.flags; + if (turning_on) + set_bit(bit, &cs->flags); + else + clear_bit(bit, &cs->flags); mutex_unlock(&callback_mutex); if (cpu_exclusive_changed) @@ -1280,8 +1281,7 @@ typedef enum { FILE_TASKLIST, } cpuset_filetype_t; -static ssize_t cpuset_common_file_write(struct file *file, - const char __user *userbuf, +static ssize_t cpuset_common_file_write(struct file *file, const char __user *userbuf, size_t nbytes, loff_t *unused_ppos) { struct cpuset *cs = __d_cs(file->f_dentry->d_parent); @@ -1292,7 +1292,7 @@ static ssize_t cpuset_common_file_write(struct file *file, int retval = 0; /* Crude upper limit on largest legitimate cpulist user might write. */ - if (nbytes > 100 + 6 * max(NR_CPUS, MAX_NUMNODES)) + if (nbytes > 100 + 6 * NR_CPUS) return -E2BIG; /* +1 for nul-terminator */ @@ -1532,7 +1532,7 @@ static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry, return simple_rename(old_dir, old_dentry, new_dir, new_dentry); } -static const struct file_operations cpuset_file_operations = { +static struct file_operations cpuset_file_operations = { .read = cpuset_file_read, .write = cpuset_file_write, .llseek = generic_file_llseek, @@ -2045,6 +2045,7 @@ int __init cpuset_init(void) return err; } +#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_MEMORY_HOTPLUG) /* * If common_cpu_mem_hotplug_unplug(), below, unplugs any CPUs * or memory nodes, we need to walk over the cpuset hierarchy, @@ -2108,7 +2109,9 @@ static void common_cpu_mem_hotplug_unplug(void) mutex_unlock(&callback_mutex); mutex_unlock(&manage_mutex); } +#endif +#ifdef CONFIG_HOTPLUG_CPU /* * The top_cpuset tracks what CPUs and Memory Nodes are online, * period. This is necessary in order to make cpusets transparent @@ -2125,6 +2128,7 @@ static int cpuset_handle_cpuhp(struct notifier_block *nb, common_cpu_mem_hotplug_unplug(); return 0; } +#endif #ifdef CONFIG_MEMORY_HOTPLUG /* @@ -2606,7 +2610,7 @@ static int cpuset_open(struct inode *inode, struct file *file) return single_open(file, proc_cpuset_show, pid); } -const struct file_operations proc_cpuset_operations = { +struct file_operations proc_cpuset_operations = { .open = cpuset_open, .read = seq_read, .llseek = seq_lseek, diff --git a/trunk/kernel/delayacct.c b/trunk/kernel/delayacct.c index 766d5912b26a..66a0ea48751d 100644 --- a/trunk/kernel/delayacct.c +++ b/trunk/kernel/delayacct.c @@ -20,7 +20,7 @@ #include int delayacct_on __read_mostly = 1; /* Delay accounting turned on/off */ -struct kmem_cache *delayacct_cache; +kmem_cache_t *delayacct_cache; static int __init delayacct_setup_disable(char *str) { @@ -41,7 +41,7 @@ void delayacct_init(void) void __delayacct_tsk_init(struct task_struct *tsk) { - tsk->delays = kmem_cache_zalloc(delayacct_cache, GFP_KERNEL); + tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL); if (tsk->delays) spin_lock_init(&tsk->delays->lock); } diff --git a/trunk/kernel/dma.c b/trunk/kernel/dma.c index 937b13ca33ba..2020644c938a 100644 --- a/trunk/kernel/dma.c +++ b/trunk/kernel/dma.c @@ -140,7 +140,7 @@ static int proc_dma_open(struct inode *inode, struct file *file) return single_open(file, proc_dma_show, NULL); } -static const struct file_operations proc_dma_operations = { +static struct file_operations proc_dma_operations = { .open = proc_dma_open, .read = seq_read, .llseek = seq_lseek, diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 4e3f919edc48..06de6c4e8ca3 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -850,7 +850,9 @@ static void exit_notify(struct task_struct *tsk) fastcall NORET_TYPE void do_exit(long code) { struct task_struct *tsk = current; + struct taskstats *tidstats; int group_dead; + unsigned int mycpu; profile_task_exit(tsk); @@ -888,6 +890,8 @@ fastcall NORET_TYPE void do_exit(long code) current->comm, current->pid, preempt_count()); + taskstats_exit_alloc(&tidstats, &mycpu); + acct_update_integrals(tsk); if (tsk->mm) { update_hiwater_rss(tsk->mm); @@ -907,8 +911,8 @@ fastcall NORET_TYPE void do_exit(long code) #endif if (unlikely(tsk->audit_context)) audit_free(tsk); - - taskstats_exit(tsk, group_dead); + taskstats_exit_send(tsk, tidstats, group_dead, mycpu); + taskstats_exit_free(tidstats); exit_mm(tsk); diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 7f2e31ba33af..8cdd3e72ba55 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -82,26 +82,26 @@ int nr_processes(void) #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR # define alloc_task_struct() kmem_cache_alloc(task_struct_cachep, GFP_KERNEL) # define free_task_struct(tsk) kmem_cache_free(task_struct_cachep, (tsk)) -static struct kmem_cache *task_struct_cachep; +static kmem_cache_t *task_struct_cachep; #endif /* SLAB cache for signal_struct structures (tsk->signal) */ -static struct kmem_cache *signal_cachep; +static kmem_cache_t *signal_cachep; /* SLAB cache for sighand_struct structures (tsk->sighand) */ -struct kmem_cache *sighand_cachep; +kmem_cache_t *sighand_cachep; /* SLAB cache for files_struct structures (tsk->files) */ -struct kmem_cache *files_cachep; +kmem_cache_t *files_cachep; /* SLAB cache for fs_struct structures (tsk->fs) */ -struct kmem_cache *fs_cachep; +kmem_cache_t *fs_cachep; /* SLAB cache for vm_area_struct structures */ -struct kmem_cache *vm_area_cachep; +kmem_cache_t *vm_area_cachep; /* SLAB cache for mm_struct structures (tsk->mm) */ -static struct kmem_cache *mm_cachep; +static kmem_cache_t *mm_cachep; void free_task(struct task_struct *tsk) { @@ -237,7 +237,7 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) goto fail_nomem; charge = len; } - tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!tmp) goto fail_nomem; *tmp = *mpnt; @@ -319,7 +319,7 @@ static inline void mm_free_pgd(struct mm_struct * mm) __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); -#define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) +#define allocate_mm() (kmem_cache_alloc(mm_cachep, SLAB_KERNEL)) #define free_mm(mm) (kmem_cache_free(mm_cachep, (mm))) #include @@ -448,16 +448,7 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) tsk->vfork_done = NULL; complete(vfork_done); } - - /* - * If we're exiting normally, clear a user-space tid field if - * requested. We leave this alone when dying by signal, to leave - * the value intact in a core dump, and to save the unnecessary - * trouble otherwise. Userland only wants this done for a sys_exit. - */ - if (tsk->clear_child_tid - && !(tsk->flags & PF_SIGNALED) - && atomic_read(&mm->mm_users) > 1) { + if (tsk->clear_child_tid && atomic_read(&mm->mm_users) > 1) { u32 __user * tidptr = tsk->clear_child_tid; tsk->clear_child_tid = NULL; @@ -488,10 +479,6 @@ static struct mm_struct *dup_mm(struct task_struct *tsk) memcpy(mm, oldmm, sizeof(*mm)); - /* Initializing for Swap token stuff */ - mm->token_priority = 0; - mm->last_interval = 0; - if (!mm_init(mm)) goto fail_nomem; @@ -555,10 +542,6 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) goto fail_nomem; good_mm: - /* Initializing for Swap token stuff */ - mm->token_priority = 0; - mm->last_interval = 0; - tsk->mm = mm; tsk->active_mm = mm; return 0; @@ -630,7 +613,7 @@ static struct files_struct *alloc_files(void) struct files_struct *newf; struct fdtable *fdt; - newf = kmem_cache_alloc(files_cachep, GFP_KERNEL); + newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL); if (!newf) goto out; @@ -847,6 +830,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts if (clone_flags & CLONE_THREAD) { atomic_inc(¤t->signal->count); atomic_inc(¤t->signal->live); + taskstats_tgid_alloc(current); return 0; } sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); @@ -1319,7 +1303,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, return ERR_PTR(retval); } -noinline struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs) +struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs) { memset(regs, 0, sizeof(struct pt_regs)); return regs; @@ -1429,7 +1413,7 @@ long do_fork(unsigned long clone_flags, #define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif -static void sighand_ctor(void *data, struct kmem_cache *cachep, unsigned long flags) +static void sighand_ctor(void *data, kmem_cache_t *cachep, unsigned long flags) { struct sighand_struct *sighand = data; diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 95989a3b4168..93ef30ba209f 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -282,9 +282,9 @@ static inline int get_futex_value_locked(u32 *dest, u32 __user *from) { int ret; - pagefault_disable(); + inc_preempt_count(); ret = __copy_from_user_inatomic(dest, from, sizeof(u32)); - pagefault_enable(); + dec_preempt_count(); return ret ? -EFAULT : 0; } @@ -324,11 +324,12 @@ static int refill_pi_state_cache(void) if (likely(current->pi_state_cache)) return 0; - pi_state = kzalloc(sizeof(*pi_state), GFP_KERNEL); + pi_state = kmalloc(sizeof(*pi_state), GFP_KERNEL); if (!pi_state) return -ENOMEM; + memset(pi_state, 0, sizeof(*pi_state)); INIT_LIST_HEAD(&pi_state->list); /* pi_mutex gets initialized later */ pi_state->owner = NULL; @@ -552,7 +553,7 @@ static void wake_futex(struct futex_q *q) * at the end of wake_up_all() does not prevent this store from * moving. */ - smp_wmb(); + wmb(); q->lock_ptr = NULL; } @@ -584,9 +585,9 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) if (!(uval & FUTEX_OWNER_DIED)) { newval = FUTEX_WAITERS | new_owner->pid; - pagefault_disable(); + inc_preempt_count(); curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); - pagefault_enable(); + dec_preempt_count(); if (curval == -EFAULT) return -EFAULT; if (curval != uval) @@ -617,9 +618,9 @@ static int unlock_futex_pi(u32 __user *uaddr, u32 uval) * There is no waiter, so we unlock the futex. The owner died * bit has not to be preserved here. We are the owner: */ - pagefault_disable(); + inc_preempt_count(); oldval = futex_atomic_cmpxchg_inatomic(uaddr, uval, 0); - pagefault_enable(); + dec_preempt_count(); if (oldval == -EFAULT) return oldval; @@ -1157,9 +1158,9 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, */ newval = current->pid; - pagefault_disable(); + inc_preempt_count(); curval = futex_atomic_cmpxchg_inatomic(uaddr, 0, newval); - pagefault_enable(); + dec_preempt_count(); if (unlikely(curval == -EFAULT)) goto uaddr_faulted; @@ -1182,9 +1183,9 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, uval = curval; newval = uval | FUTEX_WAITERS; - pagefault_disable(); + inc_preempt_count(); curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); - pagefault_enable(); + dec_preempt_count(); if (unlikely(curval == -EFAULT)) goto uaddr_faulted; @@ -1214,10 +1215,10 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, newval = current->pid | FUTEX_OWNER_DIED | FUTEX_WAITERS; - pagefault_disable(); + inc_preempt_count(); curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); - pagefault_enable(); + dec_preempt_count(); if (unlikely(curval == -EFAULT)) goto uaddr_faulted; @@ -1389,9 +1390,9 @@ static int futex_unlock_pi(u32 __user *uaddr) * anyone else up: */ if (!(uval & FUTEX_OWNER_DIED)) { - pagefault_disable(); + inc_preempt_count(); uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0); - pagefault_enable(); + dec_preempt_count(); } if (unlikely(uval == -EFAULT)) @@ -1492,7 +1493,7 @@ static unsigned int futex_poll(struct file *filp, return ret; } -static const struct file_operations futex_fops = { +static struct file_operations futex_fops = { .release = futex_close, .poll = futex_poll, }; @@ -1857,16 +1858,10 @@ static struct file_system_type futex_fs_type = { static int __init init(void) { - int i = register_filesystem(&futex_fs_type); - - if (i) - return i; + unsigned int i; + register_filesystem(&futex_fs_type); futex_mnt = kern_mount(&futex_fs_type); - if (IS_ERR(futex_mnt)) { - unregister_filesystem(&futex_fs_type); - return PTR_ERR(futex_mnt); - } for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { INIT_LIST_HEAD(&futex_queues[i].chain); diff --git a/trunk/kernel/irq/handle.c b/trunk/kernel/irq/handle.c index aff1f0fabb0d..a681912bc89a 100644 --- a/trunk/kernel/irq/handle.c +++ b/trunk/kernel/irq/handle.c @@ -54,7 +54,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = { .chip = &no_irq_chip, .handle_irq = handle_bad_irq, .depth = 1, - .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), + .lock = SPIN_LOCK_UNLOCKED, #ifdef CONFIG_SMP .affinity = CPU_MASK_ALL #endif diff --git a/trunk/kernel/kallsyms.c b/trunk/kernel/kallsyms.c index ab63cfc42992..eeac3e313b2b 100644 --- a/trunk/kernel/kallsyms.c +++ b/trunk/kernel/kallsyms.c @@ -20,7 +20,6 @@ #include #include /* for cond_resched */ #include -#include #include @@ -302,6 +301,13 @@ struct kallsym_iter char name[KSYM_NAME_LEN+1]; }; +/* Only label it "global" if it is exported. */ +static void upcase_if_global(struct kallsym_iter *iter) +{ + if (is_exported(iter->name, iter->owner)) + iter->type += 'A' - 'a'; +} + static int get_ksymbol_mod(struct kallsym_iter *iter) { iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms, @@ -310,10 +316,7 @@ static int get_ksymbol_mod(struct kallsym_iter *iter) if (iter->owner == NULL) return 0; - /* Label it "global" if it is exported, "local" if not exported. */ - iter->type = is_exported(iter->name, iter->owner) - ? toupper(iter->type) : tolower(iter->type); - + upcase_if_global(iter); return 1; } @@ -398,7 +401,7 @@ static int s_show(struct seq_file *m, void *p) return 0; } -static const struct seq_operations kallsyms_op = { +static struct seq_operations kallsyms_op = { .start = s_start, .next = s_next, .stop = s_stop, @@ -433,7 +436,7 @@ static int kallsyms_release(struct inode *inode, struct file *file) return seq_release(inode, file); } -static const struct file_operations kallsyms_operations = { +static struct file_operations kallsyms_operations = { .open = kallsyms_open, .read = seq_read, .llseek = seq_lseek, diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index afbbbe981be2..fcdd5d2bc3f4 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include @@ -110,10 +108,11 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, /* Allocate a controlling structure */ result = -ENOMEM; - image = kzalloc(sizeof(*image), GFP_KERNEL); + image = kmalloc(sizeof(*image), GFP_KERNEL); if (!image) goto out; + memset(image, 0, sizeof(*image)); image->head = 0; image->entry = &image->head; image->last_entry = &image->head; @@ -1068,60 +1067,6 @@ void crash_kexec(struct pt_regs *regs) } } -static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, - size_t data_len) -{ - struct elf_note note; - - note.n_namesz = strlen(name) + 1; - note.n_descsz = data_len; - note.n_type = type; - memcpy(buf, ¬e, sizeof(note)); - buf += (sizeof(note) + 3)/4; - memcpy(buf, name, note.n_namesz); - buf += (note.n_namesz + 3)/4; - memcpy(buf, data, note.n_descsz); - buf += (note.n_descsz + 3)/4; - - return buf; -} - -static void final_note(u32 *buf) -{ - struct elf_note note; - - note.n_namesz = 0; - note.n_descsz = 0; - note.n_type = 0; - memcpy(buf, ¬e, sizeof(note)); -} - -void crash_save_cpu(struct pt_regs *regs, int cpu) -{ - struct elf_prstatus prstatus; - u32 *buf; - - if ((cpu < 0) || (cpu >= NR_CPUS)) - return; - - /* Using ELF notes here is opportunistic. - * I need a well defined structure format - * for the data I pass, and I need tags - * on the data to indicate what information I have - * squirrelled away. ELF notes happen to provide - * all of that, so there is no need to invent something new. - */ - buf = (u32*)per_cpu_ptr(crash_notes, cpu); - if (!buf) - return; - memset(&prstatus, 0, sizeof(prstatus)); - prstatus.pr_pid = current->pid; - elf_core_copy_regs(&prstatus.pr_reg, regs); - buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, - sizeof(prstatus)); - final_note(buf); -} - static int __init crash_notes_memory_init(void) { /* Allocate memory for saving cpu registers. */ diff --git a/trunk/kernel/kprobes.c b/trunk/kernel/kprobes.c index 17ec4afb0994..610c837ad9e0 100644 --- a/trunk/kernel/kprobes.c +++ b/trunk/kernel/kprobes.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -84,36 +83,9 @@ struct kprobe_insn_page { kprobe_opcode_t *insns; /* Page of instruction slots */ char slot_used[INSNS_PER_PAGE]; int nused; - int ngarbage; }; static struct hlist_head kprobe_insn_pages; -static int kprobe_garbage_slots; -static int collect_garbage_slots(void); - -static int __kprobes check_safety(void) -{ - int ret = 0; -#if defined(CONFIG_PREEMPT) && defined(CONFIG_PM) - ret = freeze_processes(); - if (ret == 0) { - struct task_struct *p, *q; - do_each_thread(p, q) { - if (p != current && p->state == TASK_RUNNING && - p->pid != 0) { - printk("Check failed: %s is running\n",p->comm); - ret = -1; - goto loop_end; - } - } while_each_thread(p, q); - } -loop_end: - thaw_processes(); -#else - synchronize_sched(); -#endif - return ret; -} /** * get_insn_slot() - Find a slot on an executable page for an instruction. @@ -124,7 +96,6 @@ kprobe_opcode_t __kprobes *get_insn_slot(void) struct kprobe_insn_page *kip; struct hlist_node *pos; - retry: hlist_for_each(pos, &kprobe_insn_pages) { kip = hlist_entry(pos, struct kprobe_insn_page, hlist); if (kip->nused < INSNS_PER_PAGE) { @@ -141,11 +112,7 @@ kprobe_opcode_t __kprobes *get_insn_slot(void) } } - /* If there are any garbage slots, collect it and try again. */ - if (kprobe_garbage_slots && collect_garbage_slots() == 0) { - goto retry; - } - /* All out of space. Need to allocate a new page. Use slot 0. */ + /* All out of space. Need to allocate a new page. Use slot 0.*/ kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL); if (!kip) { return NULL; @@ -166,62 +133,10 @@ kprobe_opcode_t __kprobes *get_insn_slot(void) memset(kip->slot_used, 0, INSNS_PER_PAGE); kip->slot_used[0] = 1; kip->nused = 1; - kip->ngarbage = 0; return kip->insns; } -/* Return 1 if all garbages are collected, otherwise 0. */ -static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx) -{ - kip->slot_used[idx] = 0; - kip->nused--; - if (kip->nused == 0) { - /* - * Page is no longer in use. Free it unless - * it's the last one. We keep the last one - * so as not to have to set it up again the - * next time somebody inserts a probe. - */ - hlist_del(&kip->hlist); - if (hlist_empty(&kprobe_insn_pages)) { - INIT_HLIST_NODE(&kip->hlist); - hlist_add_head(&kip->hlist, - &kprobe_insn_pages); - } else { - module_free(NULL, kip->insns); - kfree(kip); - } - return 1; - } - return 0; -} - -static int __kprobes collect_garbage_slots(void) -{ - struct kprobe_insn_page *kip; - struct hlist_node *pos, *next; - - /* Ensure no-one is preepmted on the garbages */ - if (check_safety() != 0) - return -EAGAIN; - - hlist_for_each_safe(pos, next, &kprobe_insn_pages) { - int i; - kip = hlist_entry(pos, struct kprobe_insn_page, hlist); - if (kip->ngarbage == 0) - continue; - kip->ngarbage = 0; /* we will collect all garbages */ - for (i = 0; i < INSNS_PER_PAGE; i++) { - if (kip->slot_used[i] == -1 && - collect_one_slot(kip, i)) - break; - } - } - kprobe_garbage_slots = 0; - return 0; -} - -void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty) +void __kprobes free_insn_slot(kprobe_opcode_t *slot) { struct kprobe_insn_page *kip; struct hlist_node *pos; @@ -231,18 +146,28 @@ void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty) if (kip->insns <= slot && slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) { int i = (slot - kip->insns) / MAX_INSN_SIZE; - if (dirty) { - kip->slot_used[i] = -1; - kip->ngarbage++; - } else { - collect_one_slot(kip, i); + kip->slot_used[i] = 0; + kip->nused--; + if (kip->nused == 0) { + /* + * Page is no longer in use. Free it unless + * it's the last one. We keep the last one + * so as not to have to set it up again the + * next time somebody inserts a probe. + */ + hlist_del(&kip->hlist); + if (hlist_empty(&kprobe_insn_pages)) { + INIT_HLIST_NODE(&kip->hlist); + hlist_add_head(&kip->hlist, + &kprobe_insn_pages); + } else { + module_free(NULL, kip->insns); + kfree(kip); + } } - break; + return; } } - if (dirty && (++kprobe_garbage_slots > INSNS_PER_PAGE)) { - collect_garbage_slots(); - } } #endif diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index b02032476dc2..c9fefdb1a7db 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -140,6 +140,13 @@ void lockdep_on(void) EXPORT_SYMBOL(lockdep_on); +int lockdep_internal(void) +{ + return current->lockdep_recursion != 0; +} + +EXPORT_SYMBOL(lockdep_internal); + /* * Debugging switches: */ @@ -221,15 +228,17 @@ static int save_trace(struct stack_trace *trace) trace->skip = 3; trace->all_contexts = 0; + /* Make sure to not recurse in case the the unwinder needs to tak +e locks. */ + lockdep_off(); save_stack_trace(trace, NULL); + lockdep_on(); trace->max_entries = trace->nr_entries; nr_stack_trace_entries += trace->nr_entries; - if (DEBUG_LOCKS_WARN_ON(nr_stack_trace_entries > MAX_STACK_TRACE_ENTRIES)) { - __raw_spin_unlock(&hash_lock); + if (DEBUG_LOCKS_WARN_ON(nr_stack_trace_entries > MAX_STACK_TRACE_ENTRIES)) return 0; - } if (nr_stack_trace_entries == MAX_STACK_TRACE_ENTRIES) { __raw_spin_unlock(&hash_lock); @@ -348,7 +357,7 @@ get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4 static void print_lock_name(struct lock_class *class) { - char str[KSYM_NAME_LEN + 1], c1, c2, c3, c4; + char str[128], c1, c2, c3, c4; const char *name; get_usage_chars(class, &c1, &c2, &c3, &c4); @@ -370,7 +379,7 @@ static void print_lock_name(struct lock_class *class) static void print_lockdep_cache(struct lockdep_map *lock) { const char *name; - char str[KSYM_NAME_LEN + 1]; + char str[128]; name = lock->name; if (!name) @@ -440,9 +449,7 @@ static void print_lock_dependencies(struct lock_class *class, int depth) print_lock_class_header(class, depth); list_for_each_entry(entry, &class->locks_after, entry) { - if (DEBUG_LOCKS_WARN_ON(!entry->class)) - return; - + DEBUG_LOCKS_WARN_ON(!entry->class); print_lock_dependencies(entry->class, depth + 1); printk("%*s ... acquired at:\n",depth,""); @@ -467,8 +474,7 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this, return 0; entry->class = this; - if (!save_trace(&entry->trace)) - return 0; + save_trace(&entry->trace); /* * Since we never remove from the dependency list, the list can @@ -556,12 +562,8 @@ static noinline int print_circular_bug_tail(void) if (debug_locks_silent) return 0; - /* hash_lock unlocked by the header */ - __raw_spin_lock(&hash_lock); this.class = check_source->class; - if (!save_trace(&this.trace)) - return 0; - __raw_spin_unlock(&hash_lock); + save_trace(&this.trace); print_circular_bug_entry(&this, 0); printk("\nother info that might help us debug this:\n\n"); @@ -964,11 +966,14 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, &prev->class->locks_after, next->acquire_ip); if (!ret) return 0; - + /* + * Return value of 2 signals 'dependency already added', + * in that case we dont have to add the backlink either. + */ + if (ret == 2) + return 2; ret = add_lock_to_list(next->class, prev->class, &next->class->locks_before, next->acquire_ip); - if (!ret) - return 0; /* * Debugging printouts: @@ -1020,8 +1025,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next) * added: */ if (hlock->read != 2) { - if (!check_prev_add(curr, hlock, next)) - return 0; + check_prev_add(curr, hlock, next); /* * Stop after the first non-trylock entry, * as non-trylock entries have added their @@ -1178,7 +1182,6 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) struct lockdep_subclass_key *key; struct list_head *hash_head; struct lock_class *class; - unsigned long flags; class = look_up_lock_class(lock, subclass); if (likely(class)) @@ -1200,7 +1203,6 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) key = lock->key->subkeys + subclass; hash_head = classhashentry(key); - raw_local_irq_save(flags); __raw_spin_lock(&hash_lock); /* * We have to do the hash-walk again, to avoid races @@ -1215,7 +1217,6 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) */ if (nr_lock_classes >= MAX_LOCKDEP_KEYS) { __raw_spin_unlock(&hash_lock); - raw_local_irq_restore(flags); debug_locks_off(); printk("BUG: MAX_LOCKDEP_KEYS too low!\n"); printk("turning off the locking correctness validator.\n"); @@ -1238,18 +1239,15 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) if (verbose(class)) { __raw_spin_unlock(&hash_lock); - raw_local_irq_restore(flags); printk("\nnew class %p: %s", class->key, class->name); if (class->name_version > 1) printk("#%d", class->name_version); printk("\n"); dump_stack(); - raw_local_irq_save(flags); __raw_spin_lock(&hash_lock); } out_unlock_set: __raw_spin_unlock(&hash_lock); - raw_local_irq_restore(flags); if (!subclass || force) lock->class_cache = class; @@ -1730,7 +1728,6 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, debug_atomic_dec(&nr_unused_locks); break; default: - __raw_spin_unlock(&hash_lock); debug_locks_off(); WARN_ON(1); return 0; @@ -2648,7 +2645,6 @@ void debug_check_no_locks_freed(const void *mem_from, unsigned long mem_len) } local_irq_restore(flags); } -EXPORT_SYMBOL_GPL(debug_check_no_locks_freed); static void print_held_locks_bug(struct task_struct *curr) { diff --git a/trunk/kernel/lockdep_internals.h b/trunk/kernel/lockdep_internals.h index 8ce09bc4613d..eab043c83bb2 100644 --- a/trunk/kernel/lockdep_internals.h +++ b/trunk/kernel/lockdep_internals.h @@ -20,7 +20,7 @@ #define MAX_LOCKDEP_KEYS_BITS 11 #define MAX_LOCKDEP_KEYS (1UL << MAX_LOCKDEP_KEYS_BITS) -#define MAX_LOCKDEP_CHAINS_BITS 14 +#define MAX_LOCKDEP_CHAINS_BITS 13 #define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS) /* diff --git a/trunk/kernel/lockdep_proc.c b/trunk/kernel/lockdep_proc.c index b554b40a4aa6..f6e72eaab3fa 100644 --- a/trunk/kernel/lockdep_proc.c +++ b/trunk/kernel/lockdep_proc.c @@ -113,7 +113,7 @@ static int l_show(struct seq_file *m, void *v) return 0; } -static const struct seq_operations lockdep_ops = { +static struct seq_operations lockdep_ops = { .start = l_start, .next = l_next, .stop = l_stop, @@ -135,7 +135,7 @@ static int lockdep_open(struct inode *inode, struct file *file) return res; } -static const struct file_operations proc_lockdep_operations = { +static struct file_operations proc_lockdep_operations = { .open = lockdep_open, .read = seq_read, .llseek = seq_lseek, @@ -319,7 +319,7 @@ static int lockdep_stats_open(struct inode *inode, struct file *file) return single_open(file, lockdep_stats_show, NULL); } -static const struct file_operations proc_lockdep_stats_operations = { +static struct file_operations proc_lockdep_stats_operations = { .open = lockdep_stats_open, .read = seq_read, .llseek = seq_lseek, diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index d9eae45d0145..e2d09d604ca0 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -2209,7 +2209,7 @@ static int m_show(struct seq_file *m, void *p) Where refcount is a number or -, and deps is a comma-separated list of depends or -. */ -const struct seq_operations modules_op = { +struct seq_operations modules_op = { .start = m_start, .next = m_next, .stop = m_stop, diff --git a/trunk/kernel/mutex-debug.c b/trunk/kernel/mutex-debug.c index 841539d72c55..18651641a7b5 100644 --- a/trunk/kernel/mutex-debug.c +++ b/trunk/kernel/mutex-debug.c @@ -77,9 +77,6 @@ void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, void debug_mutex_unlock(struct mutex *lock) { - if (unlikely(!debug_locks)) - return; - DEBUG_LOCKS_WARN_ON(lock->owner != current_thread_info()); DEBUG_LOCKS_WARN_ON(lock->magic != lock); DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); diff --git a/trunk/kernel/pid.c b/trunk/kernel/pid.c index a48879b0b921..b914392085f9 100644 --- a/trunk/kernel/pid.c +++ b/trunk/kernel/pid.c @@ -31,7 +31,7 @@ #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift) static struct hlist_head *pid_hash; static int pidhash_shift; -static struct kmem_cache *pid_cachep; +static kmem_cache_t *pid_cachep; int pid_max = PID_MAX_DEFAULT; diff --git a/trunk/kernel/posix-timers.c b/trunk/kernel/posix-timers.c index 5fe87de10ff0..9cbb5d1be06f 100644 --- a/trunk/kernel/posix-timers.c +++ b/trunk/kernel/posix-timers.c @@ -70,7 +70,7 @@ /* * Lets keep our timers in a slab cache :-) */ -static struct kmem_cache *posix_timers_cache; +static kmem_cache_t *posix_timers_cache; static struct idr posix_timers_id; static DEFINE_SPINLOCK(idr_lock); diff --git a/trunk/kernel/power/Kconfig b/trunk/kernel/power/Kconfig index 710ed084e7c5..825068ca3479 100644 --- a/trunk/kernel/power/Kconfig +++ b/trunk/kernel/power/Kconfig @@ -78,7 +78,7 @@ config PM_SYSFS_DEPRECATED config SOFTWARE_SUSPEND bool "Software Suspend" - depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)) + depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP) && !X86_PAE) || ((FRV || PPC32) && !SMP)) ---help--- Enable the possibility of suspending the machine. It doesn't need ACPI or APM. diff --git a/trunk/kernel/power/disk.c b/trunk/kernel/power/disk.c index 0b00f56c2ad0..b1fb7866b0b3 100644 --- a/trunk/kernel/power/disk.c +++ b/trunk/kernel/power/disk.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "power.h" @@ -28,23 +27,6 @@ static int noresume = 0; char resume_file[256] = CONFIG_PM_STD_PARTITION; dev_t swsusp_resume_device; -sector_t swsusp_resume_block; - -/** - * platform_prepare - prepare the machine for hibernation using the - * platform driver if so configured and return an error code if it fails - */ - -static inline int platform_prepare(void) -{ - int error = 0; - - if (pm_disk_mode == PM_DISK_PLATFORM) { - if (pm_ops && pm_ops->prepare) - error = pm_ops->prepare(PM_SUSPEND_DISK); - } - return error; -} /** * power_down - Shut machine down for hibernate. @@ -58,10 +40,12 @@ static inline int platform_prepare(void) static void power_down(suspend_disk_method_t mode) { + int error = 0; + switch(mode) { case PM_DISK_PLATFORM: kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); - pm_ops->enter(PM_SUSPEND_DISK); + error = pm_ops->enter(PM_SUSPEND_DISK); break; case PM_DISK_SHUTDOWN: kernel_power_off(); @@ -106,18 +90,12 @@ static int prepare_processes(void) goto thaw; } - error = platform_prepare(); - if (error) - goto thaw; - /* Free memory before shutting down devices. */ if (!(error = swsusp_shrink_memory())) return 0; - - platform_finish(); - thaw: +thaw: thaw_processes(); - enable_cpus: +enable_cpus: enable_nonboot_cpus(); pm_restore_console(); return error; @@ -149,7 +127,7 @@ int pm_suspend_disk(void) return error; if (pm_disk_mode == PM_DISK_TESTPROC) - return 0; + goto Thaw; suspend_console(); error = device_suspend(PMSG_FREEZE); @@ -211,10 +189,10 @@ static int software_resume(void) { int error; - mutex_lock(&pm_mutex); + down(&pm_sem); if (!swsusp_resume_device) { if (!strlen(resume_file)) { - mutex_unlock(&pm_mutex); + up(&pm_sem); return -ENOENT; } swsusp_resume_device = name_to_dev_t(resume_file); @@ -229,7 +207,7 @@ static int software_resume(void) * FIXME: If noresume is specified, we need to find the partition * and reset it back to normal swap space. */ - mutex_unlock(&pm_mutex); + up(&pm_sem); return 0; } @@ -273,7 +251,7 @@ static int software_resume(void) unprepare_processes(); Done: /* For success case, the suspend path will release the lock */ - mutex_unlock(&pm_mutex); + up(&pm_sem); pr_debug("PM: Resume from disk failed.\n"); return 0; } @@ -334,7 +312,7 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) p = memchr(buf, '\n', n); len = p ? p - buf : n; - mutex_lock(&pm_mutex); + down(&pm_sem); for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) { if (!strncmp(buf, pm_disk_modes[i], len)) { mode = i; @@ -358,7 +336,7 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) pr_debug("PM: suspend-to-disk mode set to '%s'\n", pm_disk_modes[mode]); - mutex_unlock(&pm_mutex); + up(&pm_sem); return error ? error : n; } @@ -383,14 +361,14 @@ static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n) if (maj != MAJOR(res) || min != MINOR(res)) goto out; - mutex_lock(&pm_mutex); + down(&pm_sem); swsusp_resume_device = res; - mutex_unlock(&pm_mutex); + up(&pm_sem); printk("Attempting manual resume\n"); noresume = 0; software_resume(); ret = n; - out: +out: return ret; } @@ -445,19 +423,6 @@ static int __init resume_setup(char *str) return 1; } -static int __init resume_offset_setup(char *str) -{ - unsigned long long offset; - - if (noresume) - return 1; - - if (sscanf(str, "%llu", &offset) == 1) - swsusp_resume_block = offset; - - return 1; -} - static int __init noresume_setup(char *str) { noresume = 1; @@ -465,5 +430,4 @@ static int __init noresume_setup(char *str) } __setup("noresume", noresume_setup); -__setup("resume_offset=", resume_offset_setup); __setup("resume=", resume_setup); diff --git a/trunk/kernel/power/main.c b/trunk/kernel/power/main.c index 500eb87f643d..873228c71dab 100644 --- a/trunk/kernel/power/main.c +++ b/trunk/kernel/power/main.c @@ -8,7 +8,6 @@ * */ -#include #include #include #include @@ -19,14 +18,13 @@ #include #include #include -#include #include "power.h" /*This is just an arbitrary number */ #define FREE_PAGE_NUMBER (100) -DEFINE_MUTEX(pm_mutex); +DECLARE_MUTEX(pm_sem); struct pm_ops *pm_ops; suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN; @@ -38,9 +36,9 @@ suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN; void pm_set_ops(struct pm_ops * ops) { - mutex_lock(&pm_mutex); + down(&pm_sem); pm_ops = ops; - mutex_unlock(&pm_mutex); + up(&pm_sem); } @@ -184,7 +182,7 @@ static int enter_state(suspend_state_t state) if (!valid_state(state)) return -ENODEV; - if (!mutex_trylock(&pm_mutex)) + if (down_trylock(&pm_sem)) return -EBUSY; if (state == PM_SUSPEND_DISK) { @@ -202,7 +200,7 @@ static int enter_state(suspend_state_t state) pr_debug("PM: Finishing wakeup.\n"); suspend_finish(state); Unlock: - mutex_unlock(&pm_mutex); + up(&pm_sem); return error; } @@ -231,7 +229,7 @@ int pm_suspend(suspend_state_t state) return -EINVAL; } -EXPORT_SYMBOL(pm_suspend); + decl_subsys(power,NULL,NULL); diff --git a/trunk/kernel/power/power.h b/trunk/kernel/power/power.h index eb461b816bf4..bfe999f7b272 100644 --- a/trunk/kernel/power/power.h +++ b/trunk/kernel/power/power.h @@ -22,9 +22,7 @@ static inline int pm_suspend_disk(void) return -EPERM; } #endif - -extern struct mutex pm_mutex; - +extern struct semaphore pm_sem; #define power_attr(_name) \ static struct subsys_attribute _name##_attr = { \ .attr = { \ @@ -44,7 +42,6 @@ extern const void __nosave_begin, __nosave_end; extern unsigned long image_size; extern int in_suspend; extern dev_t swsusp_resume_device; -extern sector_t swsusp_resume_block; extern asmlinkage int swsusp_arch_suspend(void); extern asmlinkage int swsusp_arch_resume(void); @@ -105,18 +102,8 @@ struct snapshot_handle { extern unsigned int snapshot_additional_pages(struct zone *zone); extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); -extern void snapshot_write_finalize(struct snapshot_handle *handle); extern int snapshot_image_loaded(struct snapshot_handle *handle); - -/* - * This structure is used to pass the values needed for the identification - * of the resume swap area from a user space to the kernel via the - * SNAPSHOT_SET_SWAP_AREA ioctl - */ -struct resume_swap_area { - loff_t offset; - u_int32_t dev; -} __attribute__((packed)); +extern void snapshot_free_unused_memory(struct snapshot_handle *handle); #define SNAPSHOT_IOC_MAGIC '3' #define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1) @@ -130,14 +117,7 @@ struct resume_swap_area { #define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9) #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) #define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11) -#define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) -#define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \ - struct resume_swap_area) -#define SNAPSHOT_IOC_MAXNR 13 - -#define PMOPS_PREPARE 1 -#define PMOPS_ENTER 2 -#define PMOPS_FINISH 3 +#define SNAPSHOT_IOC_MAXNR 11 /** * The bitmap is used for tracing allocated swap pages @@ -161,7 +141,7 @@ struct bitmap_page { extern void free_bitmap(struct bitmap_page *bitmap); extern struct bitmap_page *alloc_bitmap(unsigned int nr_bits); -extern sector_t alloc_swapdev_block(int swap, struct bitmap_page *bitmap); +extern unsigned long alloc_swap_page(int swap, struct bitmap_page *bitmap); extern void free_all_swap_pages(int swap, struct bitmap_page *bitmap); extern int swsusp_check(void); @@ -173,7 +153,3 @@ extern int swsusp_read(void); extern int swsusp_write(void); extern void swsusp_close(void); extern int suspend_enter(suspend_state_t state); - -struct timeval; -extern void swsusp_show_speed(struct timeval *, struct timeval *, - unsigned int, char *); diff --git a/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index 99eeb119b06d..72e72d2c61e6 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/kernel/power/process.c @@ -13,15 +13,12 @@ #include #include #include -#include /* * Timeout for stopping processes */ #define TIMEOUT (20 * HZ) -#define FREEZER_KERNEL_THREADS 0 -#define FREEZER_USER_SPACE 1 static inline int freezeable(struct task_struct * p) { @@ -42,6 +39,7 @@ void refrigerator(void) long save; save = current->state; pr_debug("%s entered refrigerator\n", current->comm); + printk("="); frozen_process(current); spin_lock_irq(¤t->sighand->siglock); @@ -81,136 +79,96 @@ static void cancel_freezing(struct task_struct *p) } } -static inline int is_user_space(struct task_struct *p) -{ - return p->mm && !(p->flags & PF_BORROWED_MM); -} - -static unsigned int try_to_freeze_tasks(int freeze_user_space) +/* 0 = success, else # of processes that we failed to stop */ +int freeze_processes(void) { + int todo, nr_user, user_frozen; + unsigned long start_time; struct task_struct *g, *p; - unsigned long end_time; - unsigned int todo; - end_time = jiffies + TIMEOUT; + printk( "Stopping tasks: " ); + start_time = jiffies; + user_frozen = 0; do { - todo = 0; + nr_user = todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (!freezeable(p)) continue; - if (frozen(p)) continue; - - if (p->state == TASK_TRACED && - (frozen(p->parent) || - p->parent->state == TASK_STOPPED)) { + if (p->state == TASK_TRACED && frozen(p->parent)) { cancel_freezing(p); continue; } - if (is_user_space(p)) { - if (!freeze_user_space) - continue; - - /* Freeze the task unless there is a vfork - * completion pending + if (p->mm && !(p->flags & PF_BORROWED_MM)) { + /* The task is a user-space one. + * Freeze it unless there's a vfork completion + * pending */ if (!p->vfork_done) freeze_process(p); + nr_user++; } else { - if (freeze_user_space) - continue; - - freeze_process(p); + /* Freeze only if the user space is frozen */ + if (user_frozen) + freeze_process(p); + todo++; } - todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); + todo += nr_user; + if (!user_frozen && !nr_user) { + sys_sync(); + start_time = jiffies; + } + user_frozen = !nr_user; yield(); /* Yield is okay here */ - if (todo && time_after(jiffies, end_time)) + if (todo && time_after(jiffies, start_time + TIMEOUT)) break; - } while (todo); + } while(todo); + /* This does not unfreeze processes that are already frozen + * (we have slightly ugly calling convention in that respect, + * and caller must call thaw_processes() if something fails), + * but it cleans up leftover PF_FREEZE requests. + */ if (todo) { - /* This does not unfreeze processes that are already frozen - * (we have slightly ugly calling convention in that respect, - * and caller must call thaw_processes() if something fails), - * but it cleans up leftover PF_FREEZE requests. - */ - printk("\n"); - printk(KERN_ERR "Stopping %s timed out after %d seconds " - "(%d tasks refusing to freeze):\n", - freeze_user_space ? "user space processes" : - "kernel threads", - TIMEOUT / HZ, todo); + printk( "\n" ); + printk(KERN_ERR " stopping tasks timed out " + "after %d seconds (%d tasks remaining):\n", + TIMEOUT / HZ, todo); read_lock(&tasklist_lock); do_each_thread(g, p) { - if (is_user_space(p) == !freeze_user_space) - continue; - if (freezeable(p) && !frozen(p)) - printk(KERN_ERR " %s\n", p->comm); - + printk(KERN_ERR " %s\n", p->comm); cancel_freezing(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); + return todo; } - return todo; -} - -/** - * freeze_processes - tell processes to enter the refrigerator - * - * Returns 0 on success, or the number of processes that didn't freeze, - * although they were told to. - */ -int freeze_processes(void) -{ - unsigned int nr_unfrozen; - - printk("Stopping tasks ... "); - nr_unfrozen = try_to_freeze_tasks(FREEZER_USER_SPACE); - if (nr_unfrozen) - return nr_unfrozen; - - sys_sync(); - nr_unfrozen = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); - if (nr_unfrozen) - return nr_unfrozen; - - printk("done.\n"); + printk( "|\n" ); BUG_ON(in_atomic()); return 0; } -static void thaw_tasks(int thaw_user_space) +void thaw_processes(void) { struct task_struct *g, *p; + printk( "Restarting tasks..." ); read_lock(&tasklist_lock); do_each_thread(g, p) { if (!freezeable(p)) continue; - - if (is_user_space(p) == !thaw_user_space) - continue; - if (!thaw_process(p)) - printk(KERN_WARNING " Strange, %s not stopped\n", - p->comm ); + printk(KERN_INFO " Strange, %s not stopped\n", p->comm ); } while_each_thread(g, p); - read_unlock(&tasklist_lock); -} -void thaw_processes(void) -{ - printk("Restarting tasks ... "); - thaw_tasks(FREEZER_KERNEL_THREADS); - thaw_tasks(FREEZER_USER_SPACE); + read_unlock(&tasklist_lock); schedule(); - printk("done.\n"); + printk( " done\n" ); } EXPORT_SYMBOL(refrigerator); diff --git a/trunk/kernel/power/snapshot.c b/trunk/kernel/power/snapshot.c index c024606221c4..99f9b7d177d6 100644 --- a/trunk/kernel/power/snapshot.c +++ b/trunk/kernel/power/snapshot.c @@ -1,15 +1,15 @@ /* * linux/kernel/power/snapshot.c * - * This file provides system snapshot/restore functionality for swsusp. + * This file provide system snapshot/restore functionality. * * Copyright (C) 1998-2005 Pavel Machek - * Copyright (C) 2006 Rafael J. Wysocki * - * This file is released under the GPLv2. + * This file is released under the GPLv2, and is based on swsusp.c. * */ + #include #include #include @@ -34,24 +34,137 @@ #include "power.h" -/* List of PBEs needed for restoring the pages that were allocated before - * the suspend and included in the suspend image, but have also been - * allocated by the "resume" kernel, so their contents cannot be written - * directly to their "original" page frames. - */ +/* List of PBEs used for creating and restoring the suspend image */ struct pbe *restore_pblist; -/* Pointer to an auxiliary buffer (1 page) */ +static unsigned int nr_copy_pages; +static unsigned int nr_meta_pages; static void *buffer; +#ifdef CONFIG_HIGHMEM +unsigned int count_highmem_pages(void) +{ + struct zone *zone; + unsigned long zone_pfn; + unsigned int n = 0; + + for_each_zone (zone) + if (is_highmem(zone)) { + mark_free_pages(zone); + for (zone_pfn = 0; zone_pfn < zone->spanned_pages; zone_pfn++) { + struct page *page; + unsigned long pfn = zone_pfn + zone->zone_start_pfn; + if (!pfn_valid(pfn)) + continue; + page = pfn_to_page(pfn); + if (PageReserved(page)) + continue; + if (PageNosaveFree(page)) + continue; + n++; + } + } + return n; +} + +struct highmem_page { + char *data; + struct page *page; + struct highmem_page *next; +}; + +static struct highmem_page *highmem_copy; + +static int save_highmem_zone(struct zone *zone) +{ + unsigned long zone_pfn; + mark_free_pages(zone); + for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) { + struct page *page; + struct highmem_page *save; + void *kaddr; + unsigned long pfn = zone_pfn + zone->zone_start_pfn; + + if (!(pfn%10000)) + printk("."); + if (!pfn_valid(pfn)) + continue; + page = pfn_to_page(pfn); + /* + * This condition results from rvmalloc() sans vmalloc_32() + * and architectural memory reservations. This should be + * corrected eventually when the cases giving rise to this + * are better understood. + */ + if (PageReserved(page)) + continue; + BUG_ON(PageNosave(page)); + if (PageNosaveFree(page)) + continue; + save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC); + if (!save) + return -ENOMEM; + save->next = highmem_copy; + save->page = page; + save->data = (void *) get_zeroed_page(GFP_ATOMIC); + if (!save->data) { + kfree(save); + return -ENOMEM; + } + kaddr = kmap_atomic(page, KM_USER0); + memcpy(save->data, kaddr, PAGE_SIZE); + kunmap_atomic(kaddr, KM_USER0); + highmem_copy = save; + } + return 0; +} + +int save_highmem(void) +{ + struct zone *zone; + int res = 0; + + pr_debug("swsusp: Saving Highmem"); + drain_local_pages(); + for_each_zone (zone) { + if (is_highmem(zone)) + res = save_highmem_zone(zone); + if (res) + return res; + } + printk("\n"); + return 0; +} + +int restore_highmem(void) +{ + printk("swsusp: Restoring Highmem\n"); + while (highmem_copy) { + struct highmem_page *save = highmem_copy; + void *kaddr; + highmem_copy = save->next; + + kaddr = kmap_atomic(save->page, KM_USER0); + memcpy(kaddr, save->data, PAGE_SIZE); + kunmap_atomic(kaddr, KM_USER0); + free_page((long) save->data); + kfree(save); + } + return 0; +} +#else +static inline unsigned int count_highmem_pages(void) {return 0;} +static inline int save_highmem(void) {return 0;} +static inline int restore_highmem(void) {return 0;} +#endif + /** * @safe_needed - on resume, for storing the PBE list and the image, * we can only use memory pages that do not conflict with the pages - * used before suspend. The unsafe pages have PageNosaveFree set - * and we count them using unsafe_pages. + * used before suspend. * - * Each allocated image page is marked as PageNosave and PageNosaveFree - * so that swsusp_free() can release it. + * The unsafe pages are marked with the PG_nosave_free flag + * and we count them using unsafe_pages */ #define PG_ANY 0 @@ -61,7 +174,7 @@ static void *buffer; static unsigned int allocated_unsafe_pages; -static void *get_image_page(gfp_t gfp_mask, int safe_needed) +static void *alloc_image_page(gfp_t gfp_mask, int safe_needed) { void *res; @@ -82,39 +195,20 @@ static void *get_image_page(gfp_t gfp_mask, int safe_needed) unsigned long get_safe_page(gfp_t gfp_mask) { - return (unsigned long)get_image_page(gfp_mask, PG_SAFE); -} - -static struct page *alloc_image_page(gfp_t gfp_mask) -{ - struct page *page; - - page = alloc_page(gfp_mask); - if (page) { - SetPageNosave(page); - SetPageNosaveFree(page); - } - return page; + return (unsigned long)alloc_image_page(gfp_mask, PG_SAFE); } /** * free_image_page - free page represented by @addr, allocated with - * get_image_page (page flags set by it must be cleared) + * alloc_image_page (page flags set by it must be cleared) */ static inline void free_image_page(void *addr, int clear_nosave_free) { - struct page *page; - - BUG_ON(!virt_addr_valid(addr)); - - page = virt_to_page(addr); - - ClearPageNosave(page); + ClearPageNosave(virt_to_page(addr)); if (clear_nosave_free) - ClearPageNosaveFree(page); - - __free_page(page); + ClearPageNosaveFree(virt_to_page(addr)); + free_page((unsigned long)addr); } /* struct linked_page is used to build chains of pages */ @@ -175,7 +269,7 @@ static void *chain_alloc(struct chain_allocator *ca, unsigned int size) if (LINKED_PAGE_DATA_SIZE - ca->used_space < size) { struct linked_page *lp; - lp = get_image_page(ca->gfp_mask, ca->safe_needed); + lp = alloc_image_page(ca->gfp_mask, ca->safe_needed); if (!lp) return NULL; @@ -352,8 +446,8 @@ memory_bm_create(struct memory_bitmap *bm, gfp_t gfp_mask, int safe_needed) /* Compute the number of zones */ nr = 0; - for_each_zone(zone) - if (populated_zone(zone)) + for_each_zone (zone) + if (populated_zone(zone) && !is_highmem(zone)) nr++; /* Allocate the list of zones bitmap objects */ @@ -365,10 +459,10 @@ memory_bm_create(struct memory_bitmap *bm, gfp_t gfp_mask, int safe_needed) } /* Initialize the zone bitmap objects */ - for_each_zone(zone) { + for_each_zone (zone) { unsigned long pfn; - if (!populated_zone(zone)) + if (!populated_zone(zone) || is_highmem(zone)) continue; zone_bm->start_pfn = zone->zone_start_pfn; @@ -387,7 +481,7 @@ memory_bm_create(struct memory_bitmap *bm, gfp_t gfp_mask, int safe_needed) while (bb) { unsigned long *ptr; - ptr = get_image_page(gfp_mask, safe_needed); + ptr = alloc_image_page(gfp_mask, safe_needed); bb->data = ptr; if (!ptr) goto Free; @@ -411,7 +505,7 @@ memory_bm_create(struct memory_bitmap *bm, gfp_t gfp_mask, int safe_needed) memory_bm_position_reset(bm); return 0; - Free: +Free: bm->p_list = ca.chain; memory_bm_free(bm, PG_UNSAFE_CLEAR); return -ENOMEM; @@ -557,7 +651,7 @@ static unsigned long memory_bm_next_pfn(struct memory_bitmap *bm) memory_bm_position_reset(bm); return BM_END_OF_MAP; - Return_pfn: +Return_pfn: bm->cur.chunk = chunk; bm->cur.bit = bit; return bb->start_pfn + chunk * BM_BITS_PER_CHUNK + bit; @@ -575,80 +669,8 @@ unsigned int snapshot_additional_pages(struct zone *zone) res = DIV_ROUND_UP(zone->spanned_pages, BM_BITS_PER_BLOCK); res += DIV_ROUND_UP(res * sizeof(struct bm_block), PAGE_SIZE); - return 2 * res; -} - -#ifdef CONFIG_HIGHMEM -/** - * count_free_highmem_pages - compute the total number of free highmem - * pages, system-wide. - */ - -static unsigned int count_free_highmem_pages(void) -{ - struct zone *zone; - unsigned int cnt = 0; - - for_each_zone(zone) - if (populated_zone(zone) && is_highmem(zone)) - cnt += zone->free_pages; - - return cnt; -} - -/** - * saveable_highmem_page - Determine whether a highmem page should be - * included in the suspend image. - * - * We should save the page if it isn't Nosave or NosaveFree, or Reserved, - * and it isn't a part of a free chunk of pages. - */ - -static struct page *saveable_highmem_page(unsigned long pfn) -{ - struct page *page; - - if (!pfn_valid(pfn)) - return NULL; - - page = pfn_to_page(pfn); - - BUG_ON(!PageHighMem(page)); - - if (PageNosave(page) || PageReserved(page) || PageNosaveFree(page)) - return NULL; - - return page; -} - -/** - * count_highmem_pages - compute the total number of saveable highmem - * pages. - */ - -unsigned int count_highmem_pages(void) -{ - struct zone *zone; - unsigned int n = 0; - - for_each_zone(zone) { - unsigned long pfn, max_zone_pfn; - - if (!is_highmem(zone)) - continue; - - mark_free_pages(zone); - max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; - for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (saveable_highmem_page(pfn)) - n++; - } - return n; + return res; } -#else -static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } -static inline unsigned int count_highmem_pages(void) { return 0; } -#endif /* CONFIG_HIGHMEM */ /** * pfn_is_nosave - check if given pfn is in the 'nosave' section @@ -662,12 +684,12 @@ static inline int pfn_is_nosave(unsigned long pfn) } /** - * saveable - Determine whether a non-highmem page should be included in - * the suspend image. + * saveable - Determine whether a page should be cloned or not. + * @pfn: The page * - * We should save the page if it isn't Nosave, and is not in the range - * of pages statically defined as 'unsaveable', and it isn't a part of - * a free chunk of pages. + * We save a page if it isn't Nosave, and is not in the range of pages + * statically defined as 'unsaveable', and it + * isn't a part of a free chunk of pages. */ static struct page *saveable_page(unsigned long pfn) @@ -679,130 +701,76 @@ static struct page *saveable_page(unsigned long pfn) page = pfn_to_page(pfn); - BUG_ON(PageHighMem(page)); - - if (PageNosave(page) || PageNosaveFree(page)) + if (PageNosave(page)) return NULL; - if (PageReserved(page) && pfn_is_nosave(pfn)) return NULL; + if (PageNosaveFree(page)) + return NULL; return page; } -/** - * count_data_pages - compute the total number of saveable non-highmem - * pages. - */ - unsigned int count_data_pages(void) { struct zone *zone; unsigned long pfn, max_zone_pfn; unsigned int n = 0; - for_each_zone(zone) { + for_each_zone (zone) { if (is_highmem(zone)) continue; - mark_free_pages(zone); max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if(saveable_page(pfn)) - n++; + n += !!saveable_page(pfn); } return n; } -/* This is needed, because copy_page and memcpy are not usable for copying - * task structs. - */ -static inline void do_copy_page(long *dst, long *src) +static inline void copy_data_page(long *dst, long *src) { int n; + /* copy_page and memcpy are not usable for copying task structs. */ for (n = PAGE_SIZE / sizeof(long); n; n--) *dst++ = *src++; } -#ifdef CONFIG_HIGHMEM -static inline struct page * -page_is_saveable(struct zone *zone, unsigned long pfn) -{ - return is_highmem(zone) ? - saveable_highmem_page(pfn) : saveable_page(pfn); -} - -static inline void -copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) -{ - struct page *s_page, *d_page; - void *src, *dst; - - s_page = pfn_to_page(src_pfn); - d_page = pfn_to_page(dst_pfn); - if (PageHighMem(s_page)) { - src = kmap_atomic(s_page, KM_USER0); - dst = kmap_atomic(d_page, KM_USER1); - do_copy_page(dst, src); - kunmap_atomic(src, KM_USER0); - kunmap_atomic(dst, KM_USER1); - } else { - src = page_address(s_page); - if (PageHighMem(d_page)) { - /* Page pointed to by src may contain some kernel - * data modified by kmap_atomic() - */ - do_copy_page(buffer, src); - dst = kmap_atomic(pfn_to_page(dst_pfn), KM_USER0); - memcpy(dst, buffer, PAGE_SIZE); - kunmap_atomic(dst, KM_USER0); - } else { - dst = page_address(d_page); - do_copy_page(dst, src); - } - } -} -#else -#define page_is_saveable(zone, pfn) saveable_page(pfn) - -static inline void -copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) -{ - do_copy_page(page_address(pfn_to_page(dst_pfn)), - page_address(pfn_to_page(src_pfn))); -} -#endif /* CONFIG_HIGHMEM */ - static void copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm) { struct zone *zone; unsigned long pfn; - for_each_zone(zone) { + for_each_zone (zone) { unsigned long max_zone_pfn; + if (is_highmem(zone)) + continue; + mark_free_pages(zone); max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (page_is_saveable(zone, pfn)) + if (saveable_page(pfn)) memory_bm_set_bit(orig_bm, pfn); } memory_bm_position_reset(orig_bm); memory_bm_position_reset(copy_bm); do { pfn = memory_bm_next_pfn(orig_bm); - if (likely(pfn != BM_END_OF_MAP)) - copy_data_page(memory_bm_next_pfn(copy_bm), pfn); + if (likely(pfn != BM_END_OF_MAP)) { + struct page *page; + void *src; + + page = pfn_to_page(pfn); + src = page_address(page); + page = pfn_to_page(memory_bm_next_pfn(copy_bm)); + copy_data_page(page_address(page), src); + } } while (pfn != BM_END_OF_MAP); } -/* Total number of image pages */ -static unsigned int nr_copy_pages; -/* Number of pages needed for saving the original pfns of the image pages */ -static unsigned int nr_meta_pages; - /** * swsusp_free - free pages allocated for the suspend. * @@ -824,7 +792,7 @@ void swsusp_free(void) if (PageNosave(page) && PageNosaveFree(page)) { ClearPageNosave(page); ClearPageNosaveFree(page); - __free_page(page); + free_page((long) page_address(page)); } } } @@ -834,108 +802,34 @@ void swsusp_free(void) buffer = NULL; } -#ifdef CONFIG_HIGHMEM -/** - * count_pages_for_highmem - compute the number of non-highmem pages - * that will be necessary for creating copies of highmem pages. - */ - -static unsigned int count_pages_for_highmem(unsigned int nr_highmem) -{ - unsigned int free_highmem = count_free_highmem_pages(); - - if (free_highmem >= nr_highmem) - nr_highmem = 0; - else - nr_highmem -= free_highmem; - - return nr_highmem; -} -#else -static unsigned int -count_pages_for_highmem(unsigned int nr_highmem) { return 0; } -#endif /* CONFIG_HIGHMEM */ /** - * enough_free_mem - Make sure we have enough free memory for the - * snapshot image. + * enough_free_mem - Make sure we enough free memory to snapshot. + * + * Returns TRUE or FALSE after checking the number of available + * free pages. */ -static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem) +static int enough_free_mem(unsigned int nr_pages) { struct zone *zone; unsigned int free = 0, meta = 0; - for_each_zone(zone) { - meta += snapshot_additional_pages(zone); - if (!is_highmem(zone)) + for_each_zone (zone) + if (!is_highmem(zone)) { free += zone->free_pages; - } + meta += snapshot_additional_pages(zone); + } - nr_pages += count_pages_for_highmem(nr_highmem); - pr_debug("swsusp: Normal pages needed: %u + %u + %u, available pages: %u\n", + pr_debug("swsusp: pages needed: %u + %u + %u, available pages: %u\n", nr_pages, PAGES_FOR_IO, meta, free); return free > nr_pages + PAGES_FOR_IO + meta; } -#ifdef CONFIG_HIGHMEM -/** - * get_highmem_buffer - if there are some highmem pages in the suspend - * image, we may need the buffer to copy them and/or load their data. - */ - -static inline int get_highmem_buffer(int safe_needed) -{ - buffer = get_image_page(GFP_ATOMIC | __GFP_COLD, safe_needed); - return buffer ? 0 : -ENOMEM; -} - -/** - * alloc_highmem_image_pages - allocate some highmem pages for the image. - * Try to allocate as many pages as needed, but if the number of free - * highmem pages is lesser than that, allocate them all. - */ - -static inline unsigned int -alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int nr_highmem) -{ - unsigned int to_alloc = count_free_highmem_pages(); - - if (to_alloc > nr_highmem) - to_alloc = nr_highmem; - - nr_highmem -= to_alloc; - while (to_alloc-- > 0) { - struct page *page; - - page = alloc_image_page(__GFP_HIGHMEM); - memory_bm_set_bit(bm, page_to_pfn(page)); - } - return nr_highmem; -} -#else -static inline int get_highmem_buffer(int safe_needed) { return 0; } - -static inline unsigned int -alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int n) { return 0; } -#endif /* CONFIG_HIGHMEM */ - -/** - * swsusp_alloc - allocate memory for the suspend image - * - * We first try to allocate as many highmem pages as there are - * saveable highmem pages in the system. If that fails, we allocate - * non-highmem pages for the copies of the remaining highmem ones. - * - * In this approach it is likely that the copies of highmem pages will - * also be located in the high memory, because of the way in which - * copy_data_pages() works. - */ - static int swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, - unsigned int nr_pages, unsigned int nr_highmem) + unsigned int nr_pages) { int error; @@ -947,61 +841,46 @@ swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, if (error) goto Free; - if (nr_highmem > 0) { - error = get_highmem_buffer(PG_ANY); - if (error) - goto Free; - - nr_pages += alloc_highmem_image_pages(copy_bm, nr_highmem); - } while (nr_pages-- > 0) { - struct page *page = alloc_image_page(GFP_ATOMIC | __GFP_COLD); - + struct page *page = alloc_page(GFP_ATOMIC | __GFP_COLD); if (!page) goto Free; + SetPageNosave(page); + SetPageNosaveFree(page); memory_bm_set_bit(copy_bm, page_to_pfn(page)); } return 0; - Free: +Free: swsusp_free(); return -ENOMEM; } -/* Memory bitmap used for marking saveable pages (during suspend) or the - * suspend image pages (during resume) - */ +/* Memory bitmap used for marking saveable pages */ static struct memory_bitmap orig_bm; -/* Memory bitmap used on suspend for marking allocated pages that will contain - * the copies of saveable pages. During resume it is initially used for - * marking the suspend image pages, but then its set bits are duplicated in - * @orig_bm and it is released. Next, on systems with high memory, it may be - * used for marking "safe" highmem pages, but it has to be reinitialized for - * this purpose. +/* Memory bitmap used for marking allocated pages that will contain the copies + * of saveable pages */ static struct memory_bitmap copy_bm; asmlinkage int swsusp_save(void) { - unsigned int nr_pages, nr_highmem; + unsigned int nr_pages; - printk("swsusp: critical section: \n"); + pr_debug("swsusp: critical section: \n"); drain_local_pages(); nr_pages = count_data_pages(); - nr_highmem = count_highmem_pages(); - printk("swsusp: Need to copy %u pages\n", nr_pages + nr_highmem); + printk("swsusp: Need to copy %u pages\n", nr_pages); - if (!enough_free_mem(nr_pages, nr_highmem)) { + if (!enough_free_mem(nr_pages)) { printk(KERN_ERR "swsusp: Not enough free memory\n"); return -ENOMEM; } - if (swsusp_alloc(&orig_bm, ©_bm, nr_pages, nr_highmem)) { - printk(KERN_ERR "swsusp: Memory allocation failed\n"); + if (swsusp_alloc(&orig_bm, ©_bm, nr_pages)) return -ENOMEM; - } /* During allocating of suspend pagedir, new cold pages may appear. * Kill them. @@ -1015,12 +894,10 @@ asmlinkage int swsusp_save(void) * touch swap space! Except we must write out our image of course. */ - nr_pages += nr_highmem; nr_copy_pages = nr_pages; - nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE); + nr_meta_pages = (nr_pages * sizeof(long) + PAGE_SIZE - 1) >> PAGE_SHIFT; printk("swsusp: critical section/: done (%d pages copied)\n", nr_pages); - return 0; } @@ -1083,7 +960,7 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count) if (!buffer) { /* This makes the buffer be freed by swsusp_free() */ - buffer = get_image_page(GFP_ATOMIC, PG_ANY); + buffer = alloc_image_page(GFP_ATOMIC, PG_ANY); if (!buffer) return -ENOMEM; } @@ -1098,23 +975,9 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count) memset(buffer, 0, PAGE_SIZE); pack_pfns(buffer, &orig_bm); } else { - struct page *page; + unsigned long pfn = memory_bm_next_pfn(©_bm); - page = pfn_to_page(memory_bm_next_pfn(©_bm)); - if (PageHighMem(page)) { - /* Highmem pages are copied to the buffer, - * because we can't return with a kmapped - * highmem page (we may not be called again). - */ - void *kaddr; - - kaddr = kmap_atomic(page, KM_USER0); - memcpy(buffer, kaddr, PAGE_SIZE); - kunmap_atomic(kaddr, KM_USER0); - handle->buffer = buffer; - } else { - handle->buffer = page_address(page); - } + handle->buffer = page_address(pfn_to_page(pfn)); } handle->prev = handle->cur; } @@ -1142,7 +1005,7 @@ static int mark_unsafe_pages(struct memory_bitmap *bm) unsigned long pfn, max_zone_pfn; /* Clear page flags */ - for_each_zone(zone) { + for_each_zone (zone) { max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) if (pfn_valid(pfn)) @@ -1238,218 +1101,6 @@ unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm) } } -/* List of "safe" pages that may be used to store data loaded from the suspend - * image - */ -static struct linked_page *safe_pages_list; - -#ifdef CONFIG_HIGHMEM -/* struct highmem_pbe is used for creating the list of highmem pages that - * should be restored atomically during the resume from disk, because the page - * frames they have occupied before the suspend are in use. - */ -struct highmem_pbe { - struct page *copy_page; /* data is here now */ - struct page *orig_page; /* data was here before the suspend */ - struct highmem_pbe *next; -}; - -/* List of highmem PBEs needed for restoring the highmem pages that were - * allocated before the suspend and included in the suspend image, but have - * also been allocated by the "resume" kernel, so their contents cannot be - * written directly to their "original" page frames. - */ -static struct highmem_pbe *highmem_pblist; - -/** - * count_highmem_image_pages - compute the number of highmem pages in the - * suspend image. The bits in the memory bitmap @bm that correspond to the - * image pages are assumed to be set. - */ - -static unsigned int count_highmem_image_pages(struct memory_bitmap *bm) -{ - unsigned long pfn; - unsigned int cnt = 0; - - memory_bm_position_reset(bm); - pfn = memory_bm_next_pfn(bm); - while (pfn != BM_END_OF_MAP) { - if (PageHighMem(pfn_to_page(pfn))) - cnt++; - - pfn = memory_bm_next_pfn(bm); - } - return cnt; -} - -/** - * prepare_highmem_image - try to allocate as many highmem pages as - * there are highmem image pages (@nr_highmem_p points to the variable - * containing the number of highmem image pages). The pages that are - * "safe" (ie. will not be overwritten when the suspend image is - * restored) have the corresponding bits set in @bm (it must be - * unitialized). - * - * NOTE: This function should not be called if there are no highmem - * image pages. - */ - -static unsigned int safe_highmem_pages; - -static struct memory_bitmap *safe_highmem_bm; - -static int -prepare_highmem_image(struct memory_bitmap *bm, unsigned int *nr_highmem_p) -{ - unsigned int to_alloc; - - if (memory_bm_create(bm, GFP_ATOMIC, PG_SAFE)) - return -ENOMEM; - - if (get_highmem_buffer(PG_SAFE)) - return -ENOMEM; - - to_alloc = count_free_highmem_pages(); - if (to_alloc > *nr_highmem_p) - to_alloc = *nr_highmem_p; - else - *nr_highmem_p = to_alloc; - - safe_highmem_pages = 0; - while (to_alloc-- > 0) { - struct page *page; - - page = alloc_page(__GFP_HIGHMEM); - if (!PageNosaveFree(page)) { - /* The page is "safe", set its bit the bitmap */ - memory_bm_set_bit(bm, page_to_pfn(page)); - safe_highmem_pages++; - } - /* Mark the page as allocated */ - SetPageNosave(page); - SetPageNosaveFree(page); - } - memory_bm_position_reset(bm); - safe_highmem_bm = bm; - return 0; -} - -/** - * get_highmem_page_buffer - for given highmem image page find the buffer - * that suspend_write_next() should set for its caller to write to. - * - * If the page is to be saved to its "original" page frame or a copy of - * the page is to be made in the highmem, @buffer is returned. Otherwise, - * the copy of the page is to be made in normal memory, so the address of - * the copy is returned. - * - * If @buffer is returned, the caller of suspend_write_next() will write - * the page's contents to @buffer, so they will have to be copied to the - * right location on the next call to suspend_write_next() and it is done - * with the help of copy_last_highmem_page(). For this purpose, if - * @buffer is returned, @last_highmem page is set to the page to which - * the data will have to be copied from @buffer. - */ - -static struct page *last_highmem_page; - -static void * -get_highmem_page_buffer(struct page *page, struct chain_allocator *ca) -{ - struct highmem_pbe *pbe; - void *kaddr; - - if (PageNosave(page) && PageNosaveFree(page)) { - /* We have allocated the "original" page frame and we can - * use it directly to store the loaded page. - */ - last_highmem_page = page; - return buffer; - } - /* The "original" page frame has not been allocated and we have to - * use a "safe" page frame to store the loaded page. - */ - pbe = chain_alloc(ca, sizeof(struct highmem_pbe)); - if (!pbe) { - swsusp_free(); - return NULL; - } - pbe->orig_page = page; - if (safe_highmem_pages > 0) { - struct page *tmp; - - /* Copy of the page will be stored in high memory */ - kaddr = buffer; - tmp = pfn_to_page(memory_bm_next_pfn(safe_highmem_bm)); - safe_highmem_pages--; - last_highmem_page = tmp; - pbe->copy_page = tmp; - } else { - /* Copy of the page will be stored in normal memory */ - kaddr = safe_pages_list; - safe_pages_list = safe_pages_list->next; - pbe->copy_page = virt_to_page(kaddr); - } - pbe->next = highmem_pblist; - highmem_pblist = pbe; - return kaddr; -} - -/** - * copy_last_highmem_page - copy the contents of a highmem image from - * @buffer, where the caller of snapshot_write_next() has place them, - * to the right location represented by @last_highmem_page . - */ - -static void copy_last_highmem_page(void) -{ - if (last_highmem_page) { - void *dst; - - dst = kmap_atomic(last_highmem_page, KM_USER0); - memcpy(dst, buffer, PAGE_SIZE); - kunmap_atomic(dst, KM_USER0); - last_highmem_page = NULL; - } -} - -static inline int last_highmem_page_copied(void) -{ - return !last_highmem_page; -} - -static inline void free_highmem_data(void) -{ - if (safe_highmem_bm) - memory_bm_free(safe_highmem_bm, PG_UNSAFE_CLEAR); - - if (buffer) - free_image_page(buffer, PG_UNSAFE_CLEAR); -} -#else -static inline int get_safe_write_buffer(void) { return 0; } - -static unsigned int -count_highmem_image_pages(struct memory_bitmap *bm) { return 0; } - -static inline int -prepare_highmem_image(struct memory_bitmap *bm, unsigned int *nr_highmem_p) -{ - return 0; -} - -static inline void * -get_highmem_page_buffer(struct page *page, struct chain_allocator *ca) -{ - return NULL; -} - -static inline void copy_last_highmem_page(void) {} -static inline int last_highmem_page_copied(void) { return 1; } -static inline void free_highmem_data(void) {} -#endif /* CONFIG_HIGHMEM */ - /** * prepare_image - use the memory bitmap @bm to mark the pages that will * be overwritten in the process of restoring the system memory state @@ -1459,25 +1110,20 @@ static inline void free_highmem_data(void) {} * The idea is to allocate a new memory bitmap first and then allocate * as many pages as needed for the image data, but not to assign these * pages to specific tasks initially. Instead, we just mark them as - * allocated and create a lists of "safe" pages that will be used - * later. On systems with high memory a list of "safe" highmem pages is - * also created. + * allocated and create a list of "safe" pages that will be used later. */ #define PBES_PER_LINKED_PAGE (LINKED_PAGE_DATA_SIZE / sizeof(struct pbe)) +static struct linked_page *safe_pages_list; + static int prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm) { - unsigned int nr_pages, nr_highmem; + unsigned int nr_pages; struct linked_page *sp_list, *lp; int error; - /* If there is no highmem, the buffer will not be necessary */ - free_image_page(buffer, PG_UNSAFE_CLEAR); - buffer = NULL; - - nr_highmem = count_highmem_image_pages(bm); error = mark_unsafe_pages(bm); if (error) goto Free; @@ -1488,11 +1134,6 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm) duplicate_memory_bitmap(new_bm, bm); memory_bm_free(bm, PG_UNSAFE_KEEP); - if (nr_highmem > 0) { - error = prepare_highmem_image(bm, &nr_highmem); - if (error) - goto Free; - } /* Reserve some safe pages for potential later use. * * NOTE: This way we make sure there will be enough safe pages for the @@ -1501,10 +1142,10 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm) */ sp_list = NULL; /* nr_copy_pages cannot be lesser than allocated_unsafe_pages */ - nr_pages = nr_copy_pages - nr_highmem - allocated_unsafe_pages; + nr_pages = nr_copy_pages - allocated_unsafe_pages; nr_pages = DIV_ROUND_UP(nr_pages, PBES_PER_LINKED_PAGE); while (nr_pages > 0) { - lp = get_image_page(GFP_ATOMIC, PG_SAFE); + lp = alloc_image_page(GFP_ATOMIC, PG_SAFE); if (!lp) { error = -ENOMEM; goto Free; @@ -1515,7 +1156,7 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm) } /* Preallocate memory for the image */ safe_pages_list = NULL; - nr_pages = nr_copy_pages - nr_highmem - allocated_unsafe_pages; + nr_pages = nr_copy_pages - allocated_unsafe_pages; while (nr_pages > 0) { lp = (struct linked_page *)get_zeroed_page(GFP_ATOMIC); if (!lp) { @@ -1540,7 +1181,7 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm) } return 0; - Free: +Free: swsusp_free(); return error; } @@ -1555,9 +1196,6 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca) struct pbe *pbe; struct page *page = pfn_to_page(memory_bm_next_pfn(bm)); - if (PageHighMem(page)) - return get_highmem_page_buffer(page, ca); - if (PageNosave(page) && PageNosaveFree(page)) /* We have allocated the "original" page frame and we can * use it directly to store the loaded page. @@ -1572,12 +1210,12 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca) swsusp_free(); return NULL; } - pbe->orig_address = page_address(page); - pbe->address = safe_pages_list; + pbe->orig_address = (unsigned long)page_address(page); + pbe->address = (unsigned long)safe_pages_list; safe_pages_list = safe_pages_list->next; pbe->next = restore_pblist; restore_pblist = pbe; - return pbe->address; + return (void *)pbe->address; } /** @@ -1611,16 +1249,14 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count) if (handle->prev && handle->cur > nr_meta_pages + nr_copy_pages) return 0; - if (handle->offset == 0) { - if (!buffer) - /* This makes the buffer be freed by swsusp_free() */ - buffer = get_image_page(GFP_ATOMIC, PG_ANY); - + if (!buffer) { + /* This makes the buffer be freed by swsusp_free() */ + buffer = alloc_image_page(GFP_ATOMIC, PG_ANY); if (!buffer) return -ENOMEM; - - handle->buffer = buffer; } + if (!handle->offset) + handle->buffer = buffer; handle->sync_read = 1; if (handle->prev < handle->cur) { if (handle->prev == 0) { @@ -1648,10 +1284,8 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count) return -ENOMEM; } } else { - copy_last_highmem_page(); handle->buffer = get_buffer(&orig_bm, &ca); - if (handle->buffer != buffer) - handle->sync_read = 0; + handle->sync_read = 0; } handle->prev = handle->cur; } @@ -1667,73 +1301,15 @@ int snapshot_write_next(struct snapshot_handle *handle, size_t count) return count; } -/** - * snapshot_write_finalize - must be called after the last call to - * snapshot_write_next() in case the last page in the image happens - * to be a highmem page and its contents should be stored in the - * highmem. Additionally, it releases the memory that will not be - * used any more. - */ - -void snapshot_write_finalize(struct snapshot_handle *handle) -{ - copy_last_highmem_page(); - /* Free only if we have loaded the image entirely */ - if (handle->prev && handle->cur > nr_meta_pages + nr_copy_pages) { - memory_bm_free(&orig_bm, PG_UNSAFE_CLEAR); - free_highmem_data(); - } -} - int snapshot_image_loaded(struct snapshot_handle *handle) { - return !(!nr_copy_pages || !last_highmem_page_copied() || + return !(!nr_copy_pages || handle->cur <= nr_meta_pages + nr_copy_pages); } -#ifdef CONFIG_HIGHMEM -/* Assumes that @buf is ready and points to a "safe" page */ -static inline void -swap_two_pages_data(struct page *p1, struct page *p2, void *buf) -{ - void *kaddr1, *kaddr2; - - kaddr1 = kmap_atomic(p1, KM_USER0); - kaddr2 = kmap_atomic(p2, KM_USER1); - memcpy(buf, kaddr1, PAGE_SIZE); - memcpy(kaddr1, kaddr2, PAGE_SIZE); - memcpy(kaddr2, buf, PAGE_SIZE); - kunmap_atomic(kaddr1, KM_USER0); - kunmap_atomic(kaddr2, KM_USER1); -} - -/** - * restore_highmem - for each highmem page that was allocated before - * the suspend and included in the suspend image, and also has been - * allocated by the "resume" kernel swap its current (ie. "before - * resume") contents with the previous (ie. "before suspend") one. - * - * If the resume eventually fails, we can call this function once - * again and restore the "before resume" highmem state. - */ - -int restore_highmem(void) +void snapshot_free_unused_memory(struct snapshot_handle *handle) { - struct highmem_pbe *pbe = highmem_pblist; - void *buf; - - if (!pbe) - return 0; - - buf = get_image_page(GFP_ATOMIC, PG_SAFE); - if (!buf) - return -ENOMEM; - - while (pbe) { - swap_two_pages_data(pbe->copy_page, pbe->orig_page, buf); - pbe = pbe->next; - } - free_image_page(buf, PG_UNSAFE_CLEAR); - return 0; + /* Free only if we have loaded the image entirely */ + if (handle->prev && handle->cur > nr_meta_pages + nr_copy_pages) + memory_bm_free(&orig_bm, PG_UNSAFE_CLEAR); } -#endif /* CONFIG_HIGHMEM */ diff --git a/trunk/kernel/power/swap.c b/trunk/kernel/power/swap.c index f133d4a6d817..1a3b0dd2c3fc 100644 --- a/trunk/kernel/power/swap.c +++ b/trunk/kernel/power/swap.c @@ -34,123 +34,34 @@ extern char resume_file[]; #define SWSUSP_SIG "S1SUSPEND" static struct swsusp_header { - char reserved[PAGE_SIZE - 20 - sizeof(sector_t)]; - sector_t image; + char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)]; + swp_entry_t image; char orig_sig[10]; char sig[10]; } __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header; /* - * General things + * Saving part... */ static unsigned short root_swap = 0xffff; -static struct block_device *resume_bdev; - -/** - * submit - submit BIO request. - * @rw: READ or WRITE. - * @off physical offset of page. - * @page: page we're reading or writing. - * @bio_chain: list of pending biod (for async reading) - * - * Straight from the textbook - allocate and initialize the bio. - * If we're reading, make sure the page is marked as dirty. - * Then submit it and, if @bio_chain == NULL, wait. - */ -static int submit(int rw, pgoff_t page_off, struct page *page, - struct bio **bio_chain) -{ - struct bio *bio; - - bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); - if (!bio) - return -ENOMEM; - bio->bi_sector = page_off * (PAGE_SIZE >> 9); - bio->bi_bdev = resume_bdev; - bio->bi_end_io = end_swap_bio_read; - - if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { - printk("swsusp: ERROR: adding page to bio at %ld\n", page_off); - bio_put(bio); - return -EFAULT; - } - - lock_page(page); - bio_get(bio); - - if (bio_chain == NULL) { - submit_bio(rw | (1 << BIO_RW_SYNC), bio); - wait_on_page_locked(page); - if (rw == READ) - bio_set_pages_dirty(bio); - bio_put(bio); - } else { - if (rw == READ) - get_page(page); /* These pages are freed later */ - bio->bi_private = *bio_chain; - *bio_chain = bio; - submit_bio(rw | (1 << BIO_RW_SYNC), bio); - } - return 0; -} - -static int bio_read_page(pgoff_t page_off, void *addr, struct bio **bio_chain) -{ - return submit(READ, page_off, virt_to_page(addr), bio_chain); -} - -static int bio_write_page(pgoff_t page_off, void *addr, struct bio **bio_chain) -{ - return submit(WRITE, page_off, virt_to_page(addr), bio_chain); -} - -static int wait_on_bio_chain(struct bio **bio_chain) -{ - struct bio *bio; - struct bio *next_bio; - int ret = 0; - - if (bio_chain == NULL) - return 0; - - bio = *bio_chain; - if (bio == NULL) - return 0; - while (bio) { - struct page *page; - - next_bio = bio->bi_private; - page = bio->bi_io_vec[0].bv_page; - wait_on_page_locked(page); - if (!PageUptodate(page) || PageError(page)) - ret = -EIO; - put_page(page); - bio_put(bio); - bio = next_bio; - } - *bio_chain = NULL; - return ret; -} - -/* - * Saving part - */ -static int mark_swapfiles(sector_t start) +static int mark_swapfiles(swp_entry_t start) { int error; - bio_read_page(swsusp_resume_block, &swsusp_header, NULL); + rw_swap_page_sync(READ, swp_entry(root_swap, 0), + virt_to_page((unsigned long)&swsusp_header), NULL); if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) || !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) { memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10); memcpy(swsusp_header.sig,SWSUSP_SIG, 10); swsusp_header.image = start; - error = bio_write_page(swsusp_resume_block, - &swsusp_header, NULL); + error = rw_swap_page_sync(WRITE, swp_entry(root_swap, 0), + virt_to_page((unsigned long)&swsusp_header), + NULL); } else { - printk(KERN_ERR "swsusp: Swap header not found!\n"); + pr_debug("swsusp: Partition is not swap space.\n"); error = -ENODEV; } return error; @@ -163,21 +74,12 @@ static int mark_swapfiles(sector_t start) static int swsusp_swap_check(void) /* This is called before saving image */ { - int res; - - res = swap_type_of(swsusp_resume_device, swsusp_resume_block); - if (res < 0) - return res; - - root_swap = res; - resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_WRITE); - if (IS_ERR(resume_bdev)) - return PTR_ERR(resume_bdev); - - res = set_blocksize(resume_bdev, PAGE_SIZE); - if (res < 0) - blkdev_put(resume_bdev); + int res = swap_type_of(swsusp_resume_device); + if (res >= 0) { + root_swap = res; + return 0; + } return res; } @@ -188,26 +90,36 @@ static int swsusp_swap_check(void) /* This is called before saving image */ * @bio_chain: Link the next write BIO here */ -static int write_page(void *buf, sector_t offset, struct bio **bio_chain) +static int write_page(void *buf, unsigned long offset, struct bio **bio_chain) { - void *src; - - if (!offset) - return -ENOSPC; - - if (bio_chain) { - src = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH); - if (src) { - memcpy(src, buf, PAGE_SIZE); - } else { - WARN_ON_ONCE(1); - bio_chain = NULL; /* Go synchronous */ - src = buf; + swp_entry_t entry; + int error = -ENOSPC; + + if (offset) { + struct page *page = virt_to_page(buf); + + if (bio_chain) { + /* + * Whether or not we successfully allocated a copy page, + * we take a ref on the page here. It gets undone in + * wait_on_bio_chain(). + */ + struct page *page_copy; + page_copy = alloc_page(GFP_ATOMIC); + if (page_copy == NULL) { + WARN_ON_ONCE(1); + bio_chain = NULL; /* Go synchronous */ + get_page(page); + } else { + memcpy(page_address(page_copy), + page_address(page), PAGE_SIZE); + page = page_copy; + } } - } else { - src = buf; + entry = swp_entry(root_swap, offset); + error = rw_swap_page_sync(WRITE, entry, page, bio_chain); } - return bio_write_page(offset, src, bio_chain); + return error; } /* @@ -225,11 +137,11 @@ static int write_page(void *buf, sector_t offset, struct bio **bio_chain) * at a time. */ -#define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(sector_t) - 1) +#define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(long) - 1) struct swap_map_page { - sector_t entries[MAP_PAGE_ENTRIES]; - sector_t next_swap; + unsigned long entries[MAP_PAGE_ENTRIES]; + unsigned long next_swap; }; /** @@ -239,7 +151,7 @@ struct swap_map_page { struct swap_map_handle { struct swap_map_page *cur; - sector_t cur_swap; + unsigned long cur_swap; struct bitmap_page *bitmap; unsigned int k; }; @@ -254,6 +166,26 @@ static void release_swap_writer(struct swap_map_handle *handle) handle->bitmap = NULL; } +static void show_speed(struct timeval *start, struct timeval *stop, + unsigned nr_pages, char *msg) +{ + s64 elapsed_centisecs64; + int centisecs; + int k; + int kps; + + elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start); + do_div(elapsed_centisecs64, NSEC_PER_SEC / 100); + centisecs = elapsed_centisecs64; + if (centisecs == 0) + centisecs = 1; /* avoid div-by-zero */ + k = nr_pages * (PAGE_SIZE / 1024); + kps = (k * 100) / centisecs; + printk("%s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", msg, k, + centisecs / 100, centisecs % 100, + kps / 1000, (kps % 1000) / 10); +} + static int get_swap_writer(struct swap_map_handle *handle) { handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL); @@ -264,7 +196,7 @@ static int get_swap_writer(struct swap_map_handle *handle) release_swap_writer(handle); return -ENOMEM; } - handle->cur_swap = alloc_swapdev_block(root_swap, handle->bitmap); + handle->cur_swap = alloc_swap_page(root_swap, handle->bitmap); if (!handle->cur_swap) { release_swap_writer(handle); return -ENOSPC; @@ -273,15 +205,43 @@ static int get_swap_writer(struct swap_map_handle *handle) return 0; } +static int wait_on_bio_chain(struct bio **bio_chain) +{ + struct bio *bio; + struct bio *next_bio; + int ret = 0; + + if (bio_chain == NULL) + return 0; + + bio = *bio_chain; + if (bio == NULL) + return 0; + while (bio) { + struct page *page; + + next_bio = bio->bi_private; + page = bio->bi_io_vec[0].bv_page; + wait_on_page_locked(page); + if (!PageUptodate(page) || PageError(page)) + ret = -EIO; + put_page(page); + bio_put(bio); + bio = next_bio; + } + *bio_chain = NULL; + return ret; +} + static int swap_write_page(struct swap_map_handle *handle, void *buf, struct bio **bio_chain) { int error = 0; - sector_t offset; + unsigned long offset; if (!handle->cur) return -EINVAL; - offset = alloc_swapdev_block(root_swap, handle->bitmap); + offset = alloc_swap_page(root_swap, handle->bitmap); error = write_page(buf, offset, bio_chain); if (error) return error; @@ -290,7 +250,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, error = wait_on_bio_chain(bio_chain); if (error) goto out; - offset = alloc_swapdev_block(root_swap, handle->bitmap); + offset = alloc_swap_page(root_swap, handle->bitmap); if (!offset) return -ENOSPC; handle->cur->next_swap = offset; @@ -301,7 +261,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, handle->cur_swap = offset; handle->k = 0; } - out: +out: return error; } @@ -355,7 +315,7 @@ static int save_image(struct swap_map_handle *handle, error = err2; if (!error) printk("\b\b\b\bdone\n"); - swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); + show_speed(&start, &stop, nr_to_write, "Wrote"); return error; } @@ -390,50 +350,100 @@ int swsusp_write(void) struct swsusp_info *header; int error; - error = swsusp_swap_check(); - if (error) { + if ((error = swsusp_swap_check())) { printk(KERN_ERR "swsusp: Cannot find swap device, try " "swapon -a.\n"); return error; } memset(&snapshot, 0, sizeof(struct snapshot_handle)); error = snapshot_read_next(&snapshot, PAGE_SIZE); - if (error < PAGE_SIZE) { - if (error >= 0) - error = -EFAULT; - - goto out; - } + if (error < PAGE_SIZE) + return error < 0 ? error : -EFAULT; header = (struct swsusp_info *)data_of(snapshot); if (!enough_swap(header->pages)) { printk(KERN_ERR "swsusp: Not enough free swap\n"); - error = -ENOSPC; - goto out; + return -ENOSPC; } error = get_swap_writer(&handle); if (!error) { - sector_t start = handle.cur_swap; - + unsigned long start = handle.cur_swap; error = swap_write_page(&handle, header, NULL); if (!error) error = save_image(&handle, &snapshot, header->pages - 1); - if (!error) { flush_swap_writer(&handle); printk("S"); - error = mark_swapfiles(start); + error = mark_swapfiles(swp_entry(root_swap, start)); printk("|\n"); } } if (error) free_all_swap_pages(root_swap, handle.bitmap); release_swap_writer(&handle); - out: - swsusp_close(); return error; } +static struct block_device *resume_bdev; + +/** + * submit - submit BIO request. + * @rw: READ or WRITE. + * @off physical offset of page. + * @page: page we're reading or writing. + * @bio_chain: list of pending biod (for async reading) + * + * Straight from the textbook - allocate and initialize the bio. + * If we're reading, make sure the page is marked as dirty. + * Then submit it and, if @bio_chain == NULL, wait. + */ +static int submit(int rw, pgoff_t page_off, struct page *page, + struct bio **bio_chain) +{ + struct bio *bio; + + bio = bio_alloc(GFP_ATOMIC, 1); + if (!bio) + return -ENOMEM; + bio->bi_sector = page_off * (PAGE_SIZE >> 9); + bio->bi_bdev = resume_bdev; + bio->bi_end_io = end_swap_bio_read; + + if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { + printk("swsusp: ERROR: adding page to bio at %ld\n", page_off); + bio_put(bio); + return -EFAULT; + } + + lock_page(page); + bio_get(bio); + + if (bio_chain == NULL) { + submit_bio(rw | (1 << BIO_RW_SYNC), bio); + wait_on_page_locked(page); + if (rw == READ) + bio_set_pages_dirty(bio); + bio_put(bio); + } else { + if (rw == READ) + get_page(page); /* These pages are freed later */ + bio->bi_private = *bio_chain; + *bio_chain = bio; + submit_bio(rw | (1 << BIO_RW_SYNC), bio); + } + return 0; +} + +static int bio_read_page(pgoff_t page_off, void *addr, struct bio **bio_chain) +{ + return submit(READ, page_off, virt_to_page(addr), bio_chain); +} + +static int bio_write_page(pgoff_t page_off, void *addr) +{ + return submit(WRITE, page_off, virt_to_page(addr), NULL); +} + /** * The following functions allow us to read data using a swap map * in a file-alike way @@ -446,18 +456,17 @@ static void release_swap_reader(struct swap_map_handle *handle) handle->cur = NULL; } -static int get_swap_reader(struct swap_map_handle *handle, sector_t start) +static int get_swap_reader(struct swap_map_handle *handle, + swp_entry_t start) { int error; - if (!start) + if (!swp_offset(start)) return -EINVAL; - - handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH); + handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC); if (!handle->cur) return -ENOMEM; - - error = bio_read_page(start, handle->cur, NULL); + error = bio_read_page(swp_offset(start), handle->cur, NULL); if (error) { release_swap_reader(handle); return error; @@ -469,7 +478,7 @@ static int get_swap_reader(struct swap_map_handle *handle, sector_t start) static int swap_read_page(struct swap_map_handle *handle, void *buf, struct bio **bio_chain) { - sector_t offset; + unsigned long offset; int error; if (!handle->cur) @@ -538,11 +547,11 @@ static int load_image(struct swap_map_handle *handle, error = err2; if (!error) { printk("\b\b\b\bdone\n"); - snapshot_write_finalize(snapshot); + snapshot_free_unused_memory(snapshot); if (!snapshot_image_loaded(snapshot)) error = -ENODATA; } - swsusp_show_speed(&start, &stop, nr_to_read, "Read"); + show_speed(&start, &stop, nr_to_read, "Read"); return error; } @@ -591,16 +600,12 @@ int swsusp_check(void) if (!IS_ERR(resume_bdev)) { set_blocksize(resume_bdev, PAGE_SIZE); memset(&swsusp_header, 0, sizeof(swsusp_header)); - error = bio_read_page(swsusp_resume_block, - &swsusp_header, NULL); - if (error) + if ((error = bio_read_page(0, &swsusp_header, NULL))) return error; - if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) { memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10); /* Reset swap signature now */ - error = bio_write_page(swsusp_resume_block, - &swsusp_header, NULL); + error = bio_write_page(0, &swsusp_header); } else { return -EINVAL; } diff --git a/trunk/kernel/power/swsusp.c b/trunk/kernel/power/swsusp.c index 31aa0390c777..0b66659dc516 100644 --- a/trunk/kernel/power/swsusp.c +++ b/trunk/kernel/power/swsusp.c @@ -49,7 +49,6 @@ #include #include #include -#include #include "power.h" @@ -65,8 +64,10 @@ int in_suspend __nosavedata = 0; #ifdef CONFIG_HIGHMEM unsigned int count_highmem_pages(void); +int save_highmem(void); int restore_highmem(void); #else +static inline int save_highmem(void) { return 0; } static inline int restore_highmem(void) { return 0; } static inline unsigned int count_highmem_pages(void) { return 0; } #endif @@ -133,18 +134,18 @@ static int bitmap_set(struct bitmap_page *bitmap, unsigned long bit) return 0; } -sector_t alloc_swapdev_block(int swap, struct bitmap_page *bitmap) +unsigned long alloc_swap_page(int swap, struct bitmap_page *bitmap) { unsigned long offset; offset = swp_offset(get_swap_page_of_type(swap)); if (offset) { - if (bitmap_set(bitmap, offset)) + if (bitmap_set(bitmap, offset)) { swap_free(swp_entry(swap, offset)); - else - return swapdev_block(swap, offset); + offset = 0; + } } - return 0; + return offset; } void free_all_swap_pages(int swap, struct bitmap_page *bitmap) @@ -164,34 +165,6 @@ void free_all_swap_pages(int swap, struct bitmap_page *bitmap) } } -/** - * swsusp_show_speed - print the time elapsed between two events represented by - * @start and @stop - * - * @nr_pages - number of pages processed between @start and @stop - * @msg - introductory message to print - */ - -void swsusp_show_speed(struct timeval *start, struct timeval *stop, - unsigned nr_pages, char *msg) -{ - s64 elapsed_centisecs64; - int centisecs; - int k; - int kps; - - elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start); - do_div(elapsed_centisecs64, NSEC_PER_SEC / 100); - centisecs = elapsed_centisecs64; - if (centisecs == 0) - centisecs = 1; /* avoid div-by-zero */ - k = nr_pages * (PAGE_SIZE / 1024); - kps = (k * 100) / centisecs; - printk("%s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", msg, k, - centisecs / 100, centisecs % 100, - kps / 1000, (kps % 1000) / 10); -} - /** * swsusp_shrink_memory - Try to free as much memory as needed * @@ -211,37 +184,23 @@ static inline unsigned long __shrink_memory(long tmp) int swsusp_shrink_memory(void) { - long tmp; + long size, tmp; struct zone *zone; unsigned long pages = 0; unsigned int i = 0; char *p = "-\\|/"; - struct timeval start, stop; printk("Shrinking memory... "); - do_gettimeofday(&start); do { - long size, highmem_size; - - highmem_size = count_highmem_pages(); - size = count_data_pages() + PAGES_FOR_IO; + size = 2 * count_highmem_pages(); + size += size / 50 + count_data_pages() + PAGES_FOR_IO; tmp = size; - size += highmem_size; for_each_zone (zone) - if (populated_zone(zone)) { - if (is_highmem(zone)) { - highmem_size -= zone->free_pages; - } else { - tmp -= zone->free_pages; - tmp += zone->lowmem_reserve[ZONE_NORMAL]; - tmp += snapshot_additional_pages(zone); - } + if (!is_highmem(zone) && populated_zone(zone)) { + tmp -= zone->free_pages; + tmp += zone->lowmem_reserve[ZONE_NORMAL]; + tmp += snapshot_additional_pages(zone); } - - if (highmem_size < 0) - highmem_size = 0; - - tmp += highmem_size; if (tmp > 0) { tmp = __shrink_memory(tmp); if (!tmp) @@ -253,9 +212,7 @@ int swsusp_shrink_memory(void) } printk("\b%c", p[i++%4]); } while (tmp > 0); - do_gettimeofday(&stop); printk("\bdone (%lu pages freed)\n", pages); - swsusp_show_speed(&start, &stop, pages, "Freed"); return 0; } @@ -266,7 +223,6 @@ int swsusp_suspend(void) if ((error = arch_prepare_suspend())) return error; - local_irq_disable(); /* At this point, device_suspend() has been called, but *not* * device_power_down(). We *must* device_power_down() now. @@ -279,16 +235,23 @@ int swsusp_suspend(void) goto Enable_irqs; } + if ((error = save_highmem())) { + printk(KERN_ERR "swsusp: Not enough free pages for highmem\n"); + goto Restore_highmem; + } + save_processor_state(); if ((error = swsusp_arch_suspend())) printk(KERN_ERR "Error %d suspending\n", error); /* Restore control flow magically appears here */ restore_processor_state(); +Restore_highmem: + restore_highmem(); /* NOTE: device_power_up() is just a resume() for devices * that suspended with irqs off ... no overall powerup. */ device_power_up(); - Enable_irqs: +Enable_irqs: local_irq_enable(); return error; } @@ -305,23 +268,18 @@ int swsusp_resume(void) printk(KERN_ERR "Some devices failed to power down, very bad\n"); /* We'll ignore saved state, but this gets preempt count (etc) right */ save_processor_state(); - error = restore_highmem(); - if (!error) { - error = swsusp_arch_resume(); - /* The code below is only ever reached in case of a failure. - * Otherwise execution continues at place where - * swsusp_arch_suspend() was called - */ - BUG_ON(!error); - /* This call to restore_highmem() undos the previous one */ - restore_highmem(); - } + error = swsusp_arch_resume(); + /* Code below is only ever reached in case of failure. Otherwise + * execution continues at place where swsusp_arch_suspend was called + */ + BUG_ON(!error); /* The only reason why swsusp_arch_resume() can fail is memory being * very tight, so we have to free it as soon as we can to avoid * subsequent failures */ swsusp_free(); restore_processor_state(); + restore_highmem(); touch_softlockup_watchdog(); device_power_up(); local_irq_enable(); diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index 89443b85163b..d991d3b0e5a4 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -22,7 +21,6 @@ #include #include #include -#include #include @@ -56,8 +54,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) filp->private_data = data; memset(&data->handle, 0, sizeof(struct snapshot_handle)); if ((filp->f_flags & O_ACCMODE) == O_RDONLY) { - data->swap = swsusp_resume_device ? - swap_type_of(swsusp_resume_device, 0) : -1; + data->swap = swsusp_resume_device ? swap_type_of(swsusp_resume_device) : -1; data->mode = O_RDONLY; } else { data->swap = -1; @@ -79,10 +76,10 @@ static int snapshot_release(struct inode *inode, struct file *filp) free_all_swap_pages(data->swap, data->bitmap); free_bitmap(data->bitmap); if (data->frozen) { - mutex_lock(&pm_mutex); + down(&pm_sem); thaw_processes(); enable_nonboot_cpus(); - mutex_unlock(&pm_mutex); + up(&pm_sem); } atomic_inc(&device_available); return 0; @@ -127,8 +124,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, { int error = 0; struct snapshot_data *data; - loff_t avail; - sector_t offset; + loff_t offset, avail; if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) return -ENOTTY; @@ -144,7 +140,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, case SNAPSHOT_FREEZE: if (data->frozen) break; - mutex_lock(&pm_mutex); + down(&pm_sem); error = disable_nonboot_cpus(); if (!error) { error = freeze_processes(); @@ -154,7 +150,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, error = -EBUSY; } } - mutex_unlock(&pm_mutex); + up(&pm_sem); if (!error) data->frozen = 1; break; @@ -162,10 +158,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, case SNAPSHOT_UNFREEZE: if (!data->frozen) break; - mutex_lock(&pm_mutex); + down(&pm_sem); thaw_processes(); enable_nonboot_cpus(); - mutex_unlock(&pm_mutex); + up(&pm_sem); data->frozen = 0; break; @@ -174,7 +170,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, error = -EPERM; break; } - mutex_lock(&pm_mutex); + down(&pm_sem); /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (!error) { @@ -187,7 +183,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, } resume_console(); } - mutex_unlock(&pm_mutex); + up(&pm_sem); if (!error) error = put_user(in_suspend, (unsigned int __user *)arg); if (!error) @@ -195,13 +191,13 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, break; case SNAPSHOT_ATOMIC_RESTORE: - snapshot_write_finalize(&data->handle); if (data->mode != O_WRONLY || !data->frozen || !snapshot_image_loaded(&data->handle)) { error = -EPERM; break; } - mutex_lock(&pm_mutex); + snapshot_free_unused_memory(&data->handle); + down(&pm_sem); pm_prepare_console(); suspend_console(); error = device_suspend(PMSG_PRETHAW); @@ -211,7 +207,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, } resume_console(); pm_restore_console(); - mutex_unlock(&pm_mutex); + up(&pm_sem); break; case SNAPSHOT_FREE: @@ -242,10 +238,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, break; } } - offset = alloc_swapdev_block(data->swap, data->bitmap); + offset = alloc_swap_page(data->swap, data->bitmap); if (offset) { offset <<= PAGE_SHIFT; - error = put_user(offset, (sector_t __user *)arg); + error = put_user(offset, (loff_t __user *)arg); } else { error = -ENOSPC; } @@ -268,7 +264,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, * so we need to recode them */ if (old_decode_dev(arg)) { - data->swap = swap_type_of(old_decode_dev(arg), 0); + data->swap = swap_type_of(old_decode_dev(arg)); if (data->swap < 0) error = -ENODEV; } else { @@ -286,7 +282,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, break; } - if (!mutex_trylock(&pm_mutex)) { + if (down_trylock(&pm_sem)) { error = -EBUSY; break; } @@ -313,66 +309,8 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, if (pm_ops->finish) pm_ops->finish(PM_SUSPEND_MEM); - OutS3: - mutex_unlock(&pm_mutex); - break; - - case SNAPSHOT_PMOPS: - switch (arg) { - - case PMOPS_PREPARE: - if (pm_ops->prepare) { - error = pm_ops->prepare(PM_SUSPEND_DISK); - } - break; - - case PMOPS_ENTER: - kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); - error = pm_ops->enter(PM_SUSPEND_DISK); - break; - - case PMOPS_FINISH: - if (pm_ops && pm_ops->finish) { - pm_ops->finish(PM_SUSPEND_DISK); - } - break; - - default: - printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg); - error = -EINVAL; - - } - break; - - case SNAPSHOT_SET_SWAP_AREA: - if (data->bitmap) { - error = -EPERM; - } else { - struct resume_swap_area swap_area; - dev_t swdev; - - error = copy_from_user(&swap_area, (void __user *)arg, - sizeof(struct resume_swap_area)); - if (error) { - error = -EFAULT; - break; - } - - /* - * User space encodes device types as two-byte values, - * so we need to recode them - */ - swdev = old_decode_dev(swap_area.dev); - if (swdev) { - offset = swap_area.offset; - data->swap = swap_type_of(swdev, offset); - if (data->swap < 0) - error = -ENODEV; - } else { - data->swap = -1; - error = -EINVAL; - } - } +OutS3: + up(&pm_sem); break; default: @@ -383,7 +321,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, return error; } -static const struct file_operations snapshot_fops = { +static struct file_operations snapshot_fops = { .open = snapshot_open, .release = snapshot_release, .read = snapshot_read, diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 185bb45eacf7..66426552fbfe 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -53,6 +53,8 @@ int console_printk[4] = { DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ }; +EXPORT_UNUSED_SYMBOL(console_printk); /* June 2006 */ + /* * Low lever drivers may need that to know if they can schedule in * their unblank() callback or not. So let's export it. @@ -333,25 +335,13 @@ static void __call_console_drivers(unsigned long start, unsigned long end) } } -static int __read_mostly ignore_loglevel; - -int __init ignore_loglevel_setup(char *str) -{ - ignore_loglevel = 1; - printk(KERN_INFO "debug: ignoring loglevel setting.\n"); - - return 1; -} - -__setup("ignore_loglevel", ignore_loglevel_setup); - /* * Write out chars from start to end - 1 inclusive */ static void _call_console_drivers(unsigned long start, unsigned long end, int msg_log_level) { - if ((msg_log_level < console_loglevel || ignore_loglevel) && + if (msg_log_level < console_loglevel && console_drivers && start != end) { if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) { /* wrapped write */ @@ -641,7 +631,12 @@ EXPORT_SYMBOL(vprintk); asmlinkage long sys_syslog(int type, char __user *buf, int len) { - return -ENOSYS; + return 0; +} + +int do_syslog(int type, char __user *buf, int len) +{ + return 0; } static void call_console_drivers(unsigned long start, unsigned long end) @@ -782,6 +777,7 @@ int is_console_locked(void) { return console_locked; } +EXPORT_UNUSED_SYMBOL(is_console_locked); /* June 2006 */ /** * release_console_sem - unlock the console system diff --git a/trunk/kernel/profile.c b/trunk/kernel/profile.c index fb5e03d57e9d..f940b462eec9 100644 --- a/trunk/kernel/profile.c +++ b/trunk/kernel/profile.c @@ -40,7 +40,7 @@ int (*timer_hook)(struct pt_regs *) __read_mostly; static atomic_t *prof_buffer; static unsigned long prof_len, prof_shift; -int prof_on __read_mostly; +static int prof_on __read_mostly; static cpumask_t prof_cpu_mask = CPU_MASK_ALL; #ifdef CONFIG_SMP static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits); @@ -51,19 +51,9 @@ static DEFINE_MUTEX(profile_flip_mutex); static int __init profile_setup(char * str) { static char __initdata schedstr[] = "schedule"; - static char __initdata sleepstr[] = "sleep"; int par; - if (!strncmp(str, sleepstr, strlen(sleepstr))) { - prof_on = SLEEP_PROFILING; - if (str[strlen(sleepstr)] == ',') - str += strlen(sleepstr) + 1; - if (get_option(&str, &par)) - prof_shift = par; - printk(KERN_INFO - "kernel sleep profiling enabled (shift: %ld)\n", - prof_shift); - } else if (!strncmp(str, sleepstr, strlen(sleepstr))) { + if (!strncmp(str, schedstr, strlen(schedstr))) { prof_on = SCHED_PROFILING; if (str[strlen(schedstr)] == ',') str += strlen(schedstr) + 1; @@ -214,8 +204,7 @@ EXPORT_SYMBOL_GPL(profile_event_unregister); * positions to which hits are accounted during short intervals (e.g. * several seconds) is usually very small. Exclusion from buffer * flipping is provided by interrupt disablement (note that for - * SCHED_PROFILING or SLEEP_PROFILING profile_hit() may be called from - * process context). + * SCHED_PROFILING profile_hit() may be called from process context). * The hash function is meant to be lightweight as opposed to strong, * and was vaguely inspired by ppc64 firmware-supported inverted * pagetable hash functions, but uses a full hashtable full of finite @@ -268,7 +257,7 @@ static void profile_discard_flip_buffers(void) mutex_unlock(&profile_flip_mutex); } -void profile_hits(int type, void *__pc, unsigned int nr_hits) +void profile_hit(int type, void *__pc) { unsigned long primary, secondary, flags, pc = (unsigned long)__pc; int i, j, cpu; @@ -285,31 +274,21 @@ void profile_hits(int type, void *__pc, unsigned int nr_hits) put_cpu(); return; } - /* - * We buffer the global profiler buffer into a per-CPU - * queue and thus reduce the number of global (and possibly - * NUMA-alien) accesses. The write-queue is self-coalescing: - */ local_irq_save(flags); do { for (j = 0; j < PROFILE_GRPSZ; ++j) { if (hits[i + j].pc == pc) { - hits[i + j].hits += nr_hits; + hits[i + j].hits++; goto out; } else if (!hits[i + j].hits) { hits[i + j].pc = pc; - hits[i + j].hits = nr_hits; + hits[i + j].hits = 1; goto out; } } i = (i + secondary) & (NR_PROFILE_HIT - 1); } while (i != primary); - - /* - * Add the current hit(s) and flush the write-queue out - * to the global buffer: - */ - atomic_add(nr_hits, &prof_buffer[pc]); + atomic_inc(&prof_buffer[pc]); for (i = 0; i < NR_PROFILE_HIT; ++i) { atomic_add(hits[i].hits, &prof_buffer[hits[i].pc]); hits[i].pc = hits[i].hits = 0; @@ -319,6 +298,7 @@ void profile_hits(int type, void *__pc, unsigned int nr_hits) put_cpu(); } +#ifdef CONFIG_HOTPLUG_CPU static int __devinit profile_cpu_callback(struct notifier_block *info, unsigned long action, void *__cpu) { @@ -371,19 +351,19 @@ static int __devinit profile_cpu_callback(struct notifier_block *info, } return NOTIFY_OK; } +#endif /* CONFIG_HOTPLUG_CPU */ #else /* !CONFIG_SMP */ #define profile_flip_buffers() do { } while (0) #define profile_discard_flip_buffers() do { } while (0) -#define profile_cpu_callback NULL -void profile_hits(int type, void *__pc, unsigned int nr_hits) +void profile_hit(int type, void *__pc) { unsigned long pc; if (prof_on != type || !prof_buffer) return; pc = ((unsigned long)__pc - (unsigned long)_stext) >> prof_shift; - atomic_add(nr_hits, &prof_buffer[min(pc, prof_len - 1)]); + atomic_inc(&prof_buffer[min(pc, prof_len - 1)]); } #endif /* !CONFIG_SMP */ @@ -462,8 +442,7 @@ read_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos) read = 0; while (p < sizeof(unsigned int) && count > 0) { - if (put_user(*((char *)(&sample_step)+p),buf)) - return -EFAULT; + put_user(*((char *)(&sample_step)+p),buf); buf++; p++; count--; read++; } pnt = (char *)prof_buffer + p - sizeof(atomic_t); @@ -501,7 +480,7 @@ static ssize_t write_profile(struct file *file, const char __user *buf, return count; } -static const struct file_operations proc_profile_operations = { +static struct file_operations proc_profile_operations = { .read = read_profile, .write = write_profile, }; diff --git a/trunk/kernel/rcupdate.c b/trunk/kernel/rcupdate.c index 3554b76da84c..26bb5ffe1ef1 100644 --- a/trunk/kernel/rcupdate.c +++ b/trunk/kernel/rcupdate.c @@ -235,14 +235,12 @@ static void rcu_do_batch(struct rcu_data *rdp) list = rdp->donelist; while (list) { - next = list->next; - prefetch(next); + next = rdp->donelist = list->next; list->func(list); list = next; if (++count >= rdp->blimit) break; } - rdp->donelist = list; local_irq_disable(); rdp->qlen -= count; diff --git a/trunk/kernel/rcutorture.c b/trunk/kernel/rcutorture.c index c52f981ea008..e2bda18f6f42 100644 --- a/trunk/kernel/rcutorture.c +++ b/trunk/kernel/rcutorture.c @@ -401,7 +401,7 @@ static void srcu_torture_cleanup(void) cleanup_srcu_struct(&srcu_ctl); } -static int srcu_torture_read_lock(void) __acquires(&srcu_ctl) +static int srcu_torture_read_lock(void) { return srcu_read_lock(&srcu_ctl); } @@ -419,7 +419,7 @@ static void srcu_read_delay(struct rcu_random_state *rrsp) schedule_timeout_interruptible(longdelay); } -static void srcu_torture_read_unlock(int idx) __releases(&srcu_ctl) +static void srcu_torture_read_unlock(int idx) { srcu_read_unlock(&srcu_ctl, idx); } diff --git a/trunk/kernel/relay.c b/trunk/kernel/relay.c index 75a3a9a7efc2..2b92e8ece85b 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -1013,7 +1013,7 @@ static ssize_t relay_file_sendfile(struct file *filp, actor, &desc); } -const struct file_operations relay_file_operations = { +struct file_operations relay_file_operations = { .open = relay_file_open, .poll = relay_file_poll, .mmap = relay_file_mmap, diff --git a/trunk/kernel/resource.c b/trunk/kernel/resource.c index 7b9a497419d9..6de60c12143e 100644 --- a/trunk/kernel/resource.c +++ b/trunk/kernel/resource.c @@ -88,7 +88,7 @@ static int r_show(struct seq_file *m, void *v) return 0; } -static const struct seq_operations resource_op = { +static struct seq_operations resource_op = { .start = r_start, .next = r_next, .stop = r_stop, @@ -115,14 +115,14 @@ static int iomem_open(struct inode *inode, struct file *file) return res; } -static const struct file_operations proc_ioports_operations = { +static struct file_operations proc_ioports_operations = { .open = ioports_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, }; -static const struct file_operations proc_iomem_operations = { +static struct file_operations proc_iomem_operations = { .open = iomem_open, .read = seq_read, .llseek = seq_lseek, diff --git a/trunk/kernel/rtmutex-tester.c b/trunk/kernel/rtmutex-tester.c index 015fc633c96c..6dcea9dd8c94 100644 --- a/trunk/kernel/rtmutex-tester.c +++ b/trunk/kernel/rtmutex-tester.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "rtmutex.h" diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index f385eff4682d..3399701c680e 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -505,7 +505,7 @@ static int schedstat_open(struct inode *inode, struct file *file) return res; } -const struct file_operations proc_schedstat_operations = { +struct file_operations proc_schedstat_operations = { .open = schedstat_open, .read = seq_read, .llseek = seq_lseek, @@ -948,17 +948,6 @@ static void activate_task(struct task_struct *p, struct rq *rq, int local) } #endif - /* - * Sleep time is in units of nanosecs, so shift by 20 to get a - * milliseconds-range estimation of the amount of time that the task - * spent sleeping: - */ - if (unlikely(prof_on == SLEEP_PROFILING)) { - if (p->state == TASK_UNINTERRUPTIBLE) - profile_hits(SLEEP_PROFILING, (void *)get_wchan(p), - (now - p->timestamp) >> 20); - } - if (!rt_task(p)) p->prio = recalc_task_prio(p, now); @@ -3344,7 +3333,6 @@ asmlinkage void __sched schedule(void) printk(KERN_ERR "BUG: scheduling while atomic: " "%s/0x%08x/%d\n", current->comm, preempt_count(), current->pid); - debug_show_held_locks(current); dump_stack(); } profile_hit(SCHED_PROFILING, __builtin_return_address(0)); @@ -4816,18 +4804,18 @@ static void show_task(struct task_struct *p) show_stack(p, NULL); } -void show_state_filter(unsigned long state_filter) +void show_state(void) { struct task_struct *g, *p; #if (BITS_PER_LONG == 32) printk("\n" - " free sibling\n"); - printk(" task PC stack pid father child younger older\n"); + " sibling\n"); + printk(" task PC pid father child younger older\n"); #else printk("\n" - " free sibling\n"); - printk(" task PC stack pid father child younger older\n"); + " sibling\n"); + printk(" task PC pid father child younger older\n"); #endif read_lock(&tasklist_lock); do_each_thread(g, p) { @@ -4836,16 +4824,11 @@ void show_state_filter(unsigned long state_filter) * console might take alot of time: */ touch_nmi_watchdog(); - if (p->state & state_filter) - show_task(p); + show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); - /* - * Only show locks if all tasks are dumped: - */ - if (state_filter == -1) - debug_show_all_locks(); + debug_show_all_locks(); } /** @@ -6740,6 +6723,8 @@ SYSDEV_ATTR(sched_smt_power_savings, 0644, sched_smt_power_savings_show, sched_smt_power_savings_store); #endif + +#ifdef CONFIG_HOTPLUG_CPU /* * Force a reinitialization of the sched domains hierarchy. The domains * and groups cannot be updated in place without racing with the balancing @@ -6772,6 +6757,7 @@ static int update_sched_domains(struct notifier_block *nfb, return NOTIFY_OK; } +#endif void __init sched_init_smp(void) { @@ -6881,7 +6867,6 @@ void __might_sleep(char *file, int line) " context at %s:%d\n", file, line); printk("in_atomic():%d, irqs_disabled():%d\n", in_atomic(), irqs_disabled()); - debug_show_held_locks(current); dump_stack(); } #endif diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index ec81defde339..df18c167a2a7 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,7 @@ * SLAB caches for signal bits. */ -static struct kmem_cache *sigqueue_cachep; +static kmem_cache_t *sigqueue_cachep; /* * In POSIX a signal is sent either to a specific thread (Linux task) @@ -1134,7 +1133,8 @@ int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) return error; } -static int kill_proc_info(int sig, struct siginfo *info, pid_t pid) +int +kill_proc_info(int sig, struct siginfo *info, pid_t pid) { int error; rcu_read_lock(); diff --git a/trunk/kernel/softirq.c b/trunk/kernel/softirq.c index 918e52df090e..bf25015dce16 100644 --- a/trunk/kernel/softirq.c +++ b/trunk/kernel/softirq.c @@ -574,6 +574,8 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_UP_PREPARE: + BUG_ON(per_cpu(tasklet_vec, hotcpu).list); + BUG_ON(per_cpu(tasklet_hi_vec, hotcpu).list); p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu); if (IS_ERR(p)) { printk("ksoftirqd for %i failed\n", hotcpu); diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index a0c1a29a507f..c87b461de38d 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -1102,14 +1102,14 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) asmlinkage long sys_setuid(uid_t uid) { int old_euid = current->euid; - int old_ruid, old_suid, new_suid; + int old_ruid, old_suid, new_ruid, new_suid; int retval; retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID); if (retval) return retval; - old_ruid = current->uid; + old_ruid = new_ruid = current->uid; old_suid = current->suid; new_suid = old_suid; diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 8e9f00fd6d18..09e569f4792b 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -54,7 +54,6 @@ extern int proc_nr_files(ctl_table *table, int write, struct file *filp, #ifdef CONFIG_X86 #include -#include #endif #if defined(CONFIG_SYSCTL) @@ -171,7 +170,7 @@ static ssize_t proc_readsys(struct file *, char __user *, size_t, loff_t *); static ssize_t proc_writesys(struct file *, const char __user *, size_t, loff_t *); static int proc_opensys(struct inode *, struct file *); -const struct file_operations proc_sys_file_operations = { +struct file_operations proc_sys_file_operations = { .open = proc_opensys, .read = proc_readsys, .write = proc_writesys, @@ -708,14 +707,6 @@ static ctl_table kern_table[] = { .mode = 0444, .proc_handler = &proc_dointvec, }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "kstack_depth_to_print", - .data = &kstack_depth_to_print, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, #endif #if defined(CONFIG_MMU) { @@ -986,6 +977,17 @@ static ctl_table vm_table[] = { .extra1 = &zero, }, #endif +#ifdef CONFIG_SWAP + { + .ctl_name = VM_SWAP_TOKEN_TIMEOUT, + .procname = "swap_token_timeout", + .data = &swap_token_default_timeout, + .maxlen = sizeof(swap_token_default_timeout), + .mode = 0644, + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, + }, +#endif #ifdef CONFIG_NUMA { .ctl_name = VM_ZONE_RECLAIM_MODE, @@ -1884,7 +1886,7 @@ static int __do_proc_dointvec(void *tbl_data, ctl_table *table, p = buf; if (*p == '-' && left > 1) { neg = 1; - p++; + left--, p++; } if (*p < '0' || *p > '9') break; @@ -2135,7 +2137,7 @@ static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write, p = buf; if (*p == '-' && left > 1) { neg = 1; - p++; + left--, p++; } if (*p < '0' || *p > '9') break; diff --git a/trunk/kernel/taskstats.c b/trunk/kernel/taskstats.c index 4c3476fa058d..d3d28919d4b4 100644 --- a/trunk/kernel/taskstats.c +++ b/trunk/kernel/taskstats.c @@ -34,7 +34,7 @@ static DEFINE_PER_CPU(__u32, taskstats_seqnum) = { 0 }; static int family_registered; -struct kmem_cache *taskstats_cache; +kmem_cache_t *taskstats_cache; static struct genl_family family = { .id = GENL_ID_GENERATE, @@ -69,7 +69,7 @@ enum actions { }; static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, - size_t size) + void **replyp, size_t size) { struct sk_buff *skb; void *reply; @@ -94,6 +94,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, } *skbp = skb; + *replyp = reply; return 0; } @@ -118,10 +119,10 @@ static int send_reply(struct sk_buff *skb, pid_t pid) /* * Send taskstats data in @skb to listeners registered for @cpu's exit data */ -static void send_cpu_listeners(struct sk_buff *skb, - struct listener_list *listeners) +static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) { struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data); + struct listener_list *listeners; struct listener *s, *tmp; struct sk_buff *skb_next, *skb_cur = skb; void *reply = genlmsg_data(genlhdr); @@ -134,6 +135,7 @@ static void send_cpu_listeners(struct sk_buff *skb, } rc = 0; + listeners = &per_cpu(listener_array, cpu); down_read(&listeners->sem); list_for_each_entry(s, &listeners->list, list) { skb_next = NULL; @@ -184,7 +186,6 @@ static int fill_pid(pid_t pid, struct task_struct *tsk, } else get_task_struct(tsk); - memset(stats, 0, sizeof(*stats)); /* * Each accounting subsystem adds calls to its functions to * fill in relevant parts of struct taskstsats as follows @@ -227,8 +228,6 @@ static int fill_tgid(pid_t tgid, struct task_struct *first, if (first->signal->stats) memcpy(stats, first->signal->stats, sizeof(*stats)); - else - memset(stats, 0, sizeof(*stats)); tsk = first; do { @@ -345,36 +344,14 @@ static int parse(struct nlattr *na, cpumask_t *mask) return ret; } -static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) -{ - struct nlattr *na, *ret; - int aggr; - - aggr = (type == TASKSTATS_TYPE_PID) - ? TASKSTATS_TYPE_AGGR_PID - : TASKSTATS_TYPE_AGGR_TGID; - - na = nla_nest_start(skb, aggr); - if (!na) - goto err; - if (nla_put(skb, type, sizeof(pid), &pid) < 0) - goto err; - ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); - if (!ret) - goto err; - nla_nest_end(skb, na); - - return nla_data(ret); -err: - return NULL; -} - static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) { int rc = 0; struct sk_buff *rep_skb; - struct taskstats *stats; + struct taskstats stats; + void *reply; size_t size; + struct nlattr *na; cpumask_t mask; rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask); @@ -395,71 +372,83 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) size = nla_total_size(sizeof(u32)) + nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); - rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); + memset(&stats, 0, sizeof(stats)); + rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, &reply, size); if (rc < 0) return rc; - rc = -EINVAL; if (info->attrs[TASKSTATS_CMD_ATTR_PID]) { u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); - stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); - if (!stats) - goto err; - - rc = fill_pid(pid, NULL, stats); + rc = fill_pid(pid, NULL, &stats); if (rc < 0) goto err; + + na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID); + NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, pid); + NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS, + stats); } else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) { u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); - stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); - if (!stats) - goto err; - - rc = fill_tgid(tgid, NULL, stats); + rc = fill_tgid(tgid, NULL, &stats); if (rc < 0) goto err; - } else + + na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID); + NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, tgid); + NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS, + stats); + } else { + rc = -EINVAL; goto err; + } + + nla_nest_end(rep_skb, na); return send_reply(rep_skb, info->snd_pid); + +nla_put_failure: + rc = genlmsg_cancel(rep_skb, reply); err: nlmsg_free(rep_skb); return rc; } -static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) +void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu) { - struct signal_struct *sig = tsk->signal; - struct taskstats *stats; - - if (sig->stats || thread_group_empty(tsk)) - goto ret; + struct listener_list *listeners; + struct taskstats *tmp; + /* + * This is the cpu on which the task is exiting currently and will + * be the one for which the exit event is sent, even if the cpu + * on which this function is running changes later. + */ + *mycpu = raw_smp_processor_id(); - /* No problem if kmem_cache_zalloc() fails */ - stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); + *ptidstats = NULL; + tmp = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL); + if (!tmp) + return; - spin_lock_irq(&tsk->sighand->siglock); - if (!sig->stats) { - sig->stats = stats; - stats = NULL; + listeners = &per_cpu(listener_array, *mycpu); + down_read(&listeners->sem); + if (!list_empty(&listeners->list)) { + *ptidstats = tmp; + tmp = NULL; } - spin_unlock_irq(&tsk->sighand->siglock); - - if (stats) - kmem_cache_free(taskstats_cache, stats); -ret: - return sig->stats; + up_read(&listeners->sem); + kfree(tmp); } /* Send pid data out on exit */ -void taskstats_exit(struct task_struct *tsk, int group_dead) +void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, + int group_dead, unsigned int mycpu) { int rc; - struct listener_list *listeners; - struct taskstats *stats; struct sk_buff *rep_skb; + void *reply; size_t size; int is_thread_group; + struct nlattr *na; if (!family_registered) return; @@ -470,7 +459,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) size = nla_total_size(sizeof(u32)) + nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); - is_thread_group = !!taskstats_tgid_alloc(tsk); + is_thread_group = (tsk->signal->stats != NULL); if (is_thread_group) { /* PID + STATS + TGID + STATS */ size = 2 * size; @@ -478,39 +467,49 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) fill_tgid_exit(tsk); } - listeners = &__raw_get_cpu_var(listener_array); - if (list_empty(&listeners->list)) + if (!tidstats) return; - rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, size); + rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size); if (rc < 0) - return; - - stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, tsk->pid); - if (!stats) - goto err; + goto ret; - rc = fill_pid(tsk->pid, tsk, stats); + rc = fill_pid(tsk->pid, tsk, tidstats); if (rc < 0) - goto err; + goto err_skb; + + na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID); + NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, (u32)tsk->pid); + NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS, + *tidstats); + nla_nest_end(rep_skb, na); + + if (!is_thread_group) + goto send; /* * Doesn't matter if tsk is the leader or the last group member leaving */ - if (!is_thread_group || !group_dead) + if (!group_dead) goto send; - stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tsk->tgid); - if (!stats) - goto err; - - memcpy(stats, tsk->signal->stats, sizeof(*stats)); + na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID); + NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, (u32)tsk->tgid); + /* No locking needed for tsk->signal->stats since group is dead */ + NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS, + *tsk->signal->stats); + nla_nest_end(rep_skb, na); send: - send_cpu_listeners(rep_skb, listeners); + send_cpu_listeners(rep_skb, mycpu); return; -err: + +nla_put_failure: + genlmsg_cancel(rep_skb, reply); +err_skb: nlmsg_free(rep_skb); +ret: + return; } static struct genl_ops taskstats_ops = { diff --git a/trunk/kernel/unwind.c b/trunk/kernel/unwind.c index 09c261329249..ed0a21d4a902 100644 --- a/trunk/kernel/unwind.c +++ b/trunk/kernel/unwind.c @@ -14,12 +14,11 @@ #include #include #include -#include #include #include #include -extern const char __start_unwind[], __end_unwind[]; +extern char __start_unwind[], __end_unwind[]; extern const u8 __start_unwind_hdr[], __end_unwind_hdr[]; #define MAX_STACK_DEPTH 8 @@ -95,7 +94,6 @@ static const struct { typedef unsigned long uleb128_t; typedef signed long sleb128_t; -#define sleb128abs __builtin_labs static struct unwind_table { struct { @@ -137,17 +135,6 @@ struct unwind_state { static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 }; -static unsigned unwind_debug; -static int __init unwind_debug_setup(char *s) -{ - unwind_debug = simple_strtoul(s, NULL, 0); - return 1; -} -__setup("unwind_debug=", unwind_debug_setup); -#define dprintk(lvl, fmt, args...) \ - ((void)(lvl > unwind_debug \ - || printk(KERN_DEBUG "unwind: " fmt "\n", ##args))) - static struct unwind_table *find_table(unsigned long pc) { struct unwind_table *table; @@ -164,9 +151,7 @@ static struct unwind_table *find_table(unsigned long pc) static unsigned long read_pointer(const u8 **pLoc, const void *end, - signed ptrType, - unsigned long text_base, - unsigned long data_base); + signed ptrType); static void init_unwind_table(struct unwind_table *table, const char *name, @@ -191,13 +176,10 @@ static void init_unwind_table(struct unwind_table *table, /* See if the linker provided table looks valid. */ if (header_size <= 4 || header_start[0] != 1 - || (void *)read_pointer(&ptr, end, header_start[1], 0, 0) - != table_start - || !read_pointer(&ptr, end, header_start[2], 0, 0) - || !read_pointer(&ptr, end, header_start[3], 0, - (unsigned long)header_start) - || !read_pointer(&ptr, end, header_start[3], 0, - (unsigned long)header_start)) + || (void *)read_pointer(&ptr, end, header_start[1]) != table_start + || header_start[2] == DW_EH_PE_omit + || read_pointer(&ptr, end, header_start[2]) <= 0 + || header_start[3] == DW_EH_PE_omit) header_start = NULL; table->hdrsz = header_size; smp_wmb(); @@ -287,7 +269,7 @@ static void __init setup_unwind_table(struct unwind_table *table, ptr = (const u8 *)(fde + 2); if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0)) + ptrType)) return; ++n; } @@ -297,7 +279,6 @@ static void __init setup_unwind_table(struct unwind_table *table, hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int) + 2 * n * sizeof(unsigned long); - dprintk(2, "Binary lookup table size for %s: %lu bytes", table->name, hdrSize); header = alloc(hdrSize); if (!header) return; @@ -322,7 +303,7 @@ static void __init setup_unwind_table(struct unwind_table *table, ptr = (const u8 *)(fde + 2); header->table[n].start = read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, - fde_pointer_type(cie), 0, 0); + fde_pointer_type(cie)); header->table[n].fde = (unsigned long)fde; ++n; } @@ -505,9 +486,7 @@ static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table) static unsigned long read_pointer(const u8 **pLoc, const void *end, - signed ptrType, - unsigned long text_base, - unsigned long data_base) + signed ptrType) { unsigned long value = 0; union { @@ -519,17 +498,13 @@ static unsigned long read_pointer(const u8 **pLoc, const unsigned long *pul; } ptr; - if (ptrType < 0 || ptrType == DW_EH_PE_omit) { - dprintk(1, "Invalid pointer encoding %02X (%p,%p).", ptrType, *pLoc, end); + if (ptrType < 0 || ptrType == DW_EH_PE_omit) return 0; - } ptr.p8 = *pLoc; switch(ptrType & DW_EH_PE_FORM) { case DW_EH_PE_data2: - if (end < (const void *)(ptr.p16u + 1)) { - dprintk(1, "Data16 overrun (%p,%p).", ptr.p8, end); + if (end < (const void *)(ptr.p16u + 1)) return 0; - } if(ptrType & DW_EH_PE_signed) value = get_unaligned(ptr.p16s++); else @@ -537,10 +512,8 @@ static unsigned long read_pointer(const u8 **pLoc, break; case DW_EH_PE_data4: #ifdef CONFIG_64BIT - if (end < (const void *)(ptr.p32u + 1)) { - dprintk(1, "Data32 overrun (%p,%p).", ptr.p8, end); + if (end < (const void *)(ptr.p32u + 1)) return 0; - } if(ptrType & DW_EH_PE_signed) value = get_unaligned(ptr.p32s++); else @@ -552,10 +525,8 @@ static unsigned long read_pointer(const u8 **pLoc, BUILD_BUG_ON(sizeof(u32) != sizeof(value)); #endif case DW_EH_PE_native: - if (end < (const void *)(ptr.pul + 1)) { - dprintk(1, "DataUL overrun (%p,%p).", ptr.p8, end); + if (end < (const void *)(ptr.pul + 1)) return 0; - } value = get_unaligned(ptr.pul++); break; case DW_EH_PE_leb128: @@ -563,14 +534,10 @@ static unsigned long read_pointer(const u8 **pLoc, value = ptrType & DW_EH_PE_signed ? get_sleb128(&ptr.p8, end) : get_uleb128(&ptr.p8, end); - if ((const void *)ptr.p8 > end) { - dprintk(1, "DataLEB overrun (%p,%p).", ptr.p8, end); + if ((const void *)ptr.p8 > end) return 0; - } break; default: - dprintk(2, "Cannot decode pointer type %02X (%p,%p).", - ptrType, ptr.p8, end); return 0; } switch(ptrType & DW_EH_PE_ADJUST) { @@ -579,33 +546,12 @@ static unsigned long read_pointer(const u8 **pLoc, case DW_EH_PE_pcrel: value += (unsigned long)*pLoc; break; - case DW_EH_PE_textrel: - if (likely(text_base)) { - value += text_base; - break; - } - dprintk(2, "Text-relative encoding %02X (%p,%p), but zero text base.", - ptrType, *pLoc, end); - return 0; - case DW_EH_PE_datarel: - if (likely(data_base)) { - value += data_base; - break; - } - dprintk(2, "Data-relative encoding %02X (%p,%p), but zero data base.", - ptrType, *pLoc, end); - return 0; default: - dprintk(2, "Cannot adjust pointer type %02X (%p,%p).", - ptrType, *pLoc, end); return 0; } if ((ptrType & DW_EH_PE_indirect) - && probe_kernel_address((unsigned long *)value, value)) { - dprintk(1, "Cannot read indirect value %lx (%p,%p).", - value, *pLoc, end); + && __get_user(value, (unsigned long *)value)) return 0; - } *pLoc = ptr.p8; return value; @@ -648,8 +594,7 @@ static signed fde_pointer_type(const u32 *cie) case 'P': { signed ptrType = *ptr++; - if (!read_pointer(&ptr, end, ptrType, 0, 0) - || ptr > end) + if (!read_pointer(&ptr, end, ptrType) || ptr > end) return -1; } break; @@ -709,8 +654,7 @@ static int processCFI(const u8 *start, case DW_CFA_nop: break; case DW_CFA_set_loc: - state->loc = read_pointer(&ptr.p8, end, ptrType, 0, 0); - if (state->loc == 0) + if ((state->loc = read_pointer(&ptr.p8, end, ptrType)) == 0) result = 0; break; case DW_CFA_advance_loc1: @@ -756,10 +700,8 @@ static int processCFI(const u8 *start, state->label = NULL; return 1; } - if (state->stackDepth >= MAX_STACK_DEPTH) { - dprintk(1, "State stack overflow (%p,%p).", ptr.p8, end); + if (state->stackDepth >= MAX_STACK_DEPTH) return 0; - } state->stack[state->stackDepth++] = ptr.p8; break; case DW_CFA_restore_state: @@ -774,10 +716,8 @@ static int processCFI(const u8 *start, result = processCFI(start, end, 0, ptrType, state); state->loc = loc; state->label = label; - } else { - dprintk(1, "State stack underflow (%p,%p).", ptr.p8, end); + } else return 0; - } break; case DW_CFA_def_cfa: state->cfa.reg = get_uleb128(&ptr.p8, end); @@ -809,7 +749,6 @@ static int processCFI(const u8 *start, break; case DW_CFA_GNU_window_save: default: - dprintk(1, "Unrecognized CFI op %02X (%p,%p).", ptr.p8[-1], ptr.p8 - 1, end); result = 0; break; } @@ -825,17 +764,12 @@ static int processCFI(const u8 *start, set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state); break; } - if (ptr.p8 > end) { - dprintk(1, "Data overrun (%p,%p).", ptr.p8, end); + if (ptr.p8 > end) result = 0; - } if (result && targetLoc != 0 && targetLoc < state->loc) return 1; } - if (result && ptr.p8 < end) - dprintk(1, "Data underrun (%p,%p).", ptr.p8, end); - return result && ptr.p8 == end && (targetLoc == 0 @@ -852,7 +786,7 @@ int unwind(struct unwind_frame_info *frame) #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs]) const u32 *fde = NULL, *cie = NULL; const u8 *ptr = NULL, *end = NULL; - unsigned long pc = UNW_PC(frame) - frame->call_frame, sp; + unsigned long pc = UNW_PC(frame) - frame->call_frame; unsigned long startLoc = 0, endLoc = 0, cfa; unsigned i; signed ptrType = -1; @@ -879,9 +813,9 @@ int unwind(struct unwind_frame_info *frame) ptr = hdr + 4; end = hdr + table->hdrsz; if (tableSize - && read_pointer(&ptr, end, hdr[1], 0, 0) + && read_pointer(&ptr, end, hdr[1]) == (unsigned long)table->address - && (i = read_pointer(&ptr, end, hdr[2], 0, 0)) > 0 + && (i = read_pointer(&ptr, end, hdr[2])) > 0 && i == (end - ptr) / (2 * tableSize) && !((end - ptr) % (2 * tableSize))) { do { @@ -889,8 +823,7 @@ int unwind(struct unwind_frame_info *frame) startLoc = read_pointer(&cur, cur + tableSize, - hdr[3], 0, - (unsigned long)hdr); + hdr[3]); if (pc < startLoc) i /= 2; else { @@ -901,17 +834,13 @@ int unwind(struct unwind_frame_info *frame) if (i == 1 && (startLoc = read_pointer(&ptr, ptr + tableSize, - hdr[3], 0, - (unsigned long)hdr)) != 0 + hdr[3])) != 0 && pc >= startLoc) fde = (void *)read_pointer(&ptr, ptr + tableSize, - hdr[3], 0, - (unsigned long)hdr); + hdr[3]); } } - if(hdr && !fde) - dprintk(3, "Binary lookup for %lx failed.", pc); if (fde != NULL) { cie = cie_for_fde(fde, table); @@ -922,19 +851,17 @@ int unwind(struct unwind_frame_info *frame) && (ptrType = fde_pointer_type(cie)) >= 0 && read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0) == startLoc) { + ptrType) == startLoc) { if (!(ptrType & DW_EH_PE_indirect)) ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed; endLoc = startLoc + read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0); + ptrType); if(pc >= endLoc) fde = NULL; } else fde = NULL; - if(!fde) - dprintk(1, "Binary lookup result for %lx discarded.", pc); } if (fde == NULL) { for (fde = table->address, tableSize = table->size; @@ -954,7 +881,7 @@ int unwind(struct unwind_frame_info *frame) ptr = (const u8 *)(fde + 2); startLoc = read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0); + ptrType); if (!startLoc) continue; if (!(ptrType & DW_EH_PE_indirect)) @@ -962,12 +889,10 @@ int unwind(struct unwind_frame_info *frame) endLoc = startLoc + read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0); + ptrType); if (pc >= startLoc && pc < endLoc) break; } - if(!fde) - dprintk(3, "Linear lookup for %lx failed.", pc); } } if (cie != NULL) { @@ -1001,8 +926,6 @@ int unwind(struct unwind_frame_info *frame) if (ptr >= end || *ptr) cie = NULL; } - if(!cie) - dprintk(1, "CIE unusable (%p,%p).", ptr, end); ++ptr; } if (cie != NULL) { @@ -1012,12 +935,7 @@ int unwind(struct unwind_frame_info *frame) state.dataAlign = get_sleb128(&ptr, end); if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end) cie = NULL; - else if (UNW_PC(frame) % state.codeAlign - || UNW_SP(frame) % sleb128abs(state.dataAlign)) { - dprintk(1, "Input pointer(s) misaligned (%lx,%lx).", - UNW_PC(frame), UNW_SP(frame)); - return -EPERM; - } else { + else { retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end); /* skip augmentation */ if (((const char *)(cie + 2))[1] == 'z') { @@ -1031,8 +949,6 @@ int unwind(struct unwind_frame_info *frame) || reg_info[retAddrReg].width != sizeof(unsigned long)) cie = NULL; } - if(!cie) - dprintk(1, "CIE validation failed (%p,%p).", ptr, end); } if (cie != NULL) { state.cieStart = ptr; @@ -1046,15 +962,11 @@ int unwind(struct unwind_frame_info *frame) if ((ptr += augSize) > end) fde = NULL; } - if(!fde) - dprintk(1, "FDE validation failed (%p,%p).", ptr, end); } if (cie == NULL || fde == NULL) { #ifdef CONFIG_FRAME_POINTER unsigned long top, bottom; - if ((UNW_SP(frame) | UNW_FP(frame)) % sizeof(unsigned long)) - return -EPERM; top = STACK_TOP(frame->task); bottom = STACK_BOTTOM(frame->task); # if FRAME_RETADDR_OFFSET < 0 @@ -1070,19 +982,18 @@ int unwind(struct unwind_frame_info *frame) & (sizeof(unsigned long) - 1))) { unsigned long link; - if (!probe_kernel_address( + if (!__get_user(link, (unsigned long *)(UNW_FP(frame) - + FRAME_LINK_OFFSET), - link) + + FRAME_LINK_OFFSET)) # if FRAME_RETADDR_OFFSET < 0 && link > bottom && link < UNW_FP(frame) # else && link > UNW_FP(frame) && link < bottom # endif && !(link & (sizeof(link) - 1)) - && !probe_kernel_address( + && !__get_user(UNW_PC(frame), (unsigned long *)(UNW_FP(frame) - + FRAME_RETADDR_OFFSET), UNW_PC(frame))) { + + FRAME_RETADDR_OFFSET))) { UNW_SP(frame) = UNW_FP(frame) + FRAME_RETADDR_OFFSET # if FRAME_RETADDR_OFFSET < 0 - @@ -1105,11 +1016,8 @@ int unwind(struct unwind_frame_info *frame) || state.regs[retAddrReg].where == Nowhere || state.cfa.reg >= ARRAY_SIZE(reg_info) || reg_info[state.cfa.reg].width != sizeof(unsigned long) - || FRAME_REG(state.cfa.reg, unsigned long) % sizeof(unsigned long) - || state.cfa.offs % sizeof(unsigned long)) { - dprintk(1, "Unusable unwind info (%p,%p).", ptr, end); + || state.cfa.offs % sizeof(unsigned long)) return -EIO; - } /* update frame */ #ifndef CONFIG_AS_CFI_SIGNAL_FRAME if(frame->call_frame @@ -1128,14 +1036,10 @@ int unwind(struct unwind_frame_info *frame) #else # define CASES CASE(8); CASE(16); CASE(32); CASE(64) #endif - pc = UNW_PC(frame); - sp = UNW_SP(frame); for (i = 0; i < ARRAY_SIZE(state.regs); ++i) { if (REG_INVALID(i)) { if (state.regs[i].where == Nowhere) continue; - dprintk(1, "Cannot restore register %u (%d).", - i, state.regs[i].where); return -EIO; } switch(state.regs[i].where) { @@ -1144,11 +1048,8 @@ int unwind(struct unwind_frame_info *frame) case Register: if (state.regs[i].value >= ARRAY_SIZE(reg_info) || REG_INVALID(state.regs[i].value) - || reg_info[i].width > reg_info[state.regs[i].value].width) { - dprintk(1, "Cannot restore register %u from register %lu.", - i, state.regs[i].value); + || reg_info[i].width > reg_info[state.regs[i].value].width) return -EIO; - } switch(reg_info[state.regs[i].value].width) { #define CASE(n) \ case sizeof(u##n): \ @@ -1158,9 +1059,6 @@ int unwind(struct unwind_frame_info *frame) CASES; #undef CASE default: - dprintk(1, "Unsupported register size %u (%lu).", - reg_info[state.regs[i].value].width, - state.regs[i].value); return -EIO; } break; @@ -1185,17 +1083,12 @@ int unwind(struct unwind_frame_info *frame) CASES; #undef CASE default: - dprintk(1, "Unsupported register size %u (%u).", - reg_info[i].width, i); return -EIO; } break; case Value: - if (reg_info[i].width != sizeof(unsigned long)) { - dprintk(1, "Unsupported value size %u (%u).", - reg_info[i].width, i); + if (reg_info[i].width != sizeof(unsigned long)) return -EIO; - } FRAME_REG(i, unsigned long) = cfa + state.regs[i].value * state.dataAlign; break; @@ -1207,20 +1100,15 @@ int unwind(struct unwind_frame_info *frame) % sizeof(unsigned long) || addr < startLoc || addr + sizeof(unsigned long) < addr - || addr + sizeof(unsigned long) > endLoc) { - dprintk(1, "Bad memory location %lx (%lx).", - addr, state.regs[i].value); + || addr + sizeof(unsigned long) > endLoc) return -EIO; - } switch(reg_info[i].width) { #define CASE(n) case sizeof(u##n): \ - probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \ + __get_user(FRAME_REG(i, u##n), (u##n *)addr); \ break CASES; #undef CASE default: - dprintk(1, "Unsupported memory size %u (%u).", - reg_info[i].width, i); return -EIO; } } @@ -1228,17 +1116,6 @@ int unwind(struct unwind_frame_info *frame) } } - if (UNW_PC(frame) % state.codeAlign - || UNW_SP(frame) % sleb128abs(state.dataAlign)) { - dprintk(1, "Output pointer(s) misaligned (%lx,%lx).", - UNW_PC(frame), UNW_SP(frame)); - return -EIO; - } - if (pc == UNW_PC(frame) && sp == UNW_SP(frame)) { - dprintk(1, "No progress (%lx,%lx).", pc, sp); - return -EIO; - } - return 0; #undef CASES #undef FRAME_REG diff --git a/trunk/kernel/user.c b/trunk/kernel/user.c index 4869563080e9..220e586127a0 100644 --- a/trunk/kernel/user.c +++ b/trunk/kernel/user.c @@ -26,7 +26,7 @@ #define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK) #define uidhashentry(uid) (uidhash_table + __uidhashfn((uid))) -static struct kmem_cache *uid_cachep; +static kmem_cache_t *uid_cachep; static struct list_head uidhash_table[UIDHASH_SZ]; /* @@ -132,7 +132,7 @@ struct user_struct * alloc_uid(uid_t uid) if (!up) { struct user_struct *new; - new = kmem_cache_alloc(uid_cachep, GFP_KERNEL); + new = kmem_cache_alloc(uid_cachep, SLAB_KERNEL); if (!new) return NULL; new->uid = uid; diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index c5257316f4b9..8d1e7cb8a51a 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -29,9 +29,6 @@ #include #include #include -#include -#include -#include /* * The per-CPU workqueue (if single thread, we always use the first @@ -58,8 +55,6 @@ struct cpu_workqueue_struct { struct task_struct *thread; int run_depth; /* Detect run_workqueue() recursion depth */ - - int freezeable; /* Freeze the thread during suspend */ } ____cacheline_aligned; /* @@ -255,17 +250,6 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq) work_release(work); f(work); - if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { - printk(KERN_ERR "BUG: workqueue leaked lock or atomic: " - "%s/0x%08x/%d\n", - current->comm, preempt_count(), - current->pid); - printk(KERN_ERR " last function: "); - print_symbol("%s\n", (unsigned long)f); - debug_show_held_locks(current); - dump_stack(); - } - spin_lock_irqsave(&cwq->lock, flags); cwq->remove_sequence++; wake_up(&cwq->work_done); @@ -281,8 +265,7 @@ static int worker_thread(void *__cwq) struct k_sigaction sa; sigset_t blocked; - if (!cwq->freezeable) - current->flags |= PF_NOFREEZE; + current->flags |= PF_NOFREEZE; set_user_nice(current, -5); @@ -305,9 +288,6 @@ static int worker_thread(void *__cwq) set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { - if (cwq->freezeable) - try_to_freeze(); - add_wait_queue(&cwq->more_work, &wait); if (list_empty(&cwq->worklist)) schedule(); @@ -384,7 +364,7 @@ void fastcall flush_workqueue(struct workqueue_struct *wq) EXPORT_SYMBOL_GPL(flush_workqueue); static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq, - int cpu, int freezeable) + int cpu) { struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu); struct task_struct *p; @@ -394,7 +374,6 @@ static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq, cwq->thread = NULL; cwq->insert_sequence = 0; cwq->remove_sequence = 0; - cwq->freezeable = freezeable; INIT_LIST_HEAD(&cwq->worklist); init_waitqueue_head(&cwq->more_work); init_waitqueue_head(&cwq->work_done); @@ -410,7 +389,7 @@ static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq, } struct workqueue_struct *__create_workqueue(const char *name, - int singlethread, int freezeable) + int singlethread) { int cpu, destroy = 0; struct workqueue_struct *wq; @@ -430,7 +409,7 @@ struct workqueue_struct *__create_workqueue(const char *name, mutex_lock(&workqueue_mutex); if (singlethread) { INIT_LIST_HEAD(&wq->list); - p = create_workqueue_thread(wq, singlethread_cpu, freezeable); + p = create_workqueue_thread(wq, singlethread_cpu); if (!p) destroy = 1; else @@ -438,7 +417,7 @@ struct workqueue_struct *__create_workqueue(const char *name, } else { list_add(&wq->list, &workqueues); for_each_online_cpu(cpu) { - p = create_workqueue_thread(wq, cpu, freezeable); + p = create_workqueue_thread(wq, cpu); if (p) { kthread_bind(p, cpu); wake_up_process(p); @@ -655,6 +634,7 @@ int current_is_keventd(void) } +#ifdef CONFIG_HOTPLUG_CPU /* Take the work from this (downed) CPU. */ static void take_over_work(struct workqueue_struct *wq, unsigned int cpu) { @@ -687,7 +667,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, mutex_lock(&workqueue_mutex); /* Create a new workqueue thread for it. */ list_for_each_entry(wq, &workqueues, list) { - if (!create_workqueue_thread(wq, hotcpu, 0)) { + if (!create_workqueue_thread(wq, hotcpu)) { printk("workqueue for %i failed\n", hotcpu); return NOTIFY_BAD; } @@ -737,6 +717,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } +#endif void init_workqueues(void) { diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index b75fed737f25..d3679103a8e4 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -1,7 +1,6 @@ config PRINTK_TIME bool "Show timing information on printks" - depends on PRINTK help Selecting this option causes timing information to be included in printk output. This allows you to measure diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index fea8f9035f07..cf98fabaa549 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -25,7 +25,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o -obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o +lib-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o obj-$(CONFIG_PLIST) += plist.o obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o diff --git a/trunk/lib/cmdline.c b/trunk/lib/cmdline.c index 8a5b5303bd4f..0331ed825ea7 100644 --- a/trunk/lib/cmdline.c +++ b/trunk/lib/cmdline.c @@ -16,23 +16,6 @@ #include #include -/* - * If a hyphen was found in get_option, this will handle the - * range of numbers, M-N. This will expand the range and insert - * the values[M, M+1, ..., N] into the ints array in get_options. - */ - -static int get_range(char **str, int *pint) -{ - int x, inc_counter, upper_range; - - (*str)++; - upper_range = simple_strtol((*str), NULL, 0); - inc_counter = upper_range - *pint; - for (x = *pint; x < upper_range; x++) - *pint++ = x; - return inc_counter; -} /** * get_option - Parse integer from an option string @@ -46,7 +29,6 @@ static int get_range(char **str, int *pint) * 0 : no int in string * 1 : int found, no subsequent comma * 2 : int found including a subsequent comma - * 3 : hyphen found to denote a range */ int get_option (char **str, int *pint) @@ -62,8 +44,6 @@ int get_option (char **str, int *pint) (*str)++; return 2; } - if (**str == '-') - return 3; return 1; } @@ -75,8 +55,7 @@ int get_option (char **str, int *pint) * @ints: integer array * * This function parses a string containing a comma-separated - * list of integers, a hyphen-separated range of _positive_ integers, - * or a combination of both. The parse halts when the array is + * list of integers. The parse halts when the array is * full, or when no more numbers can be retrieved from the * string. * @@ -93,18 +72,6 @@ char *get_options(const char *str, int nints, int *ints) res = get_option ((char **)&str, ints + i); if (res == 0) break; - if (res == 3) { - int range_nums; - range_nums = get_range((char **)&str, ints + i); - if (range_nums < 0) - break; - /* - * Decrement the result by one to leave out the - * last number in the range. The next iteration - * will handle the upper number in the range - */ - i += (range_nums - 1); - } i++; if (res == 1) break; diff --git a/trunk/lib/idr.c b/trunk/lib/idr.c index 71853531d3b0..16d2143fea48 100644 --- a/trunk/lib/idr.c +++ b/trunk/lib/idr.c @@ -33,7 +33,7 @@ #include #include -static struct kmem_cache *idr_layer_cache; +static kmem_cache_t *idr_layer_cache; static struct idr_layer *alloc_layer(struct idr *idp) { @@ -445,7 +445,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) } EXPORT_SYMBOL(idr_replace); -static void idr_cache_ctor(void * idr_layer, struct kmem_cache *idr_layer_cache, +static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache, unsigned long flags) { memset(idr_layer, 0, sizeof(struct idr_layer)); diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index 7ce6dc138e90..744a4b102c7f 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -111,9 +111,10 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) len = get_kobj_path_length(kobj); if (len == 0) return NULL; - path = kzalloc(len, gfp_mask); + path = kmalloc(len, gfp_mask); if (!path) return NULL; + memset(path, 0x00, len); fill_kobj_path(kobj, path, len); return path; diff --git a/trunk/lib/list_debug.c b/trunk/lib/list_debug.c index 4350ba9655bd..7ba9d823d388 100644 --- a/trunk/lib/list_debug.c +++ b/trunk/lib/list_debug.c @@ -21,15 +21,13 @@ void __list_add(struct list_head *new, struct list_head *next) { if (unlikely(next->prev != prev)) { - printk(KERN_ERR "list_add corruption. next->prev should be " - "prev (%p), but was %p. (next=%p).\n", - prev, next->prev, next); + printk(KERN_ERR "list_add corruption. next->prev should be %p, but was %p\n", + prev, next->prev); BUG(); } if (unlikely(prev->next != next)) { - printk(KERN_ERR "list_add corruption. prev->next should be " - "next (%p), but was %p. (prev=%p).\n", - next, prev->next, prev); + printk(KERN_ERR "list_add corruption. prev->next should be %p, but was %p\n", + next, prev->next); BUG(); } next->prev = new; diff --git a/trunk/lib/locking-selftest.c b/trunk/lib/locking-selftest.c index 280332c1827c..7945787f439a 100644 --- a/trunk/lib/locking-selftest.c +++ b/trunk/lib/locking-selftest.c @@ -963,9 +963,7 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) printk("failed|"); } else { unexpected_testcase_failures++; - printk("FAILED|"); - dump_stack(); } } else { testcase_successes++; diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c index d69ddbe43865..aa9bfd0bdbd1 100644 --- a/trunk/lib/radix-tree.c +++ b/trunk/lib/radix-tree.c @@ -2,7 +2,6 @@ * Copyright (C) 2001 Momchil Velikov * Portions Copyright (C) 2001 Christoph Hellwig * Copyright (C) 2005 SGI, Christoph Lameter - * Copyright (C) 2006 Nick Piggin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -31,7 +30,6 @@ #include #include #include -#include #ifdef __KERNEL__ @@ -47,9 +45,7 @@ ((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG) struct radix_tree_node { - unsigned int height; /* Height from the bottom */ unsigned int count; - struct rcu_head rcu_head; void *slots[RADIX_TREE_MAP_SIZE]; unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; }; @@ -67,7 +63,7 @@ static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH] __read_mostly; /* * Radix tree node cache. */ -static struct kmem_cache *radix_tree_node_cachep; +static kmem_cache_t *radix_tree_node_cachep; /* * Per-cpu pool of preloaded nodes @@ -104,21 +100,13 @@ radix_tree_node_alloc(struct radix_tree_root *root) rtp->nr--; } } - BUG_ON(radix_tree_is_direct_ptr(ret)); return ret; } -static void radix_tree_node_rcu_free(struct rcu_head *head) -{ - struct radix_tree_node *node = - container_of(head, struct radix_tree_node, rcu_head); - kmem_cache_free(radix_tree_node_cachep, node); -} - static inline void radix_tree_node_free(struct radix_tree_node *node) { - call_rcu(&node->rcu_head, radix_tree_node_rcu_free); + kmem_cache_free(radix_tree_node_cachep, node); } /* @@ -234,12 +222,11 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) } do { - unsigned int newheight; if (!(node = radix_tree_node_alloc(root))) return -ENOMEM; /* Increase the height. */ - node->slots[0] = radix_tree_direct_to_ptr(root->rnode); + node->slots[0] = root->rnode; /* Propagate the aggregated tag info into the new root */ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { @@ -247,11 +234,9 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) tag_set(node, tag, 0); } - newheight = root->height+1; - node->height = newheight; node->count = 1; - rcu_assign_pointer(root->rnode, node); - root->height = newheight; + root->rnode = node; + root->height++; } while (height > root->height); out: return 0; @@ -273,8 +258,6 @@ int radix_tree_insert(struct radix_tree_root *root, int offset; int error; - BUG_ON(radix_tree_is_direct_ptr(item)); - /* Make sure the tree is high enough. */ if (index > radix_tree_maxindex(root->height)) { error = radix_tree_extend(root, index); @@ -292,12 +275,11 @@ int radix_tree_insert(struct radix_tree_root *root, /* Have to add a child node. */ if (!(slot = radix_tree_node_alloc(root))) return -ENOMEM; - slot->height = height; if (node) { - rcu_assign_pointer(node->slots[offset], slot); + node->slots[offset] = slot; node->count++; } else - rcu_assign_pointer(root->rnode, slot); + root->rnode = slot; } /* Go a level down */ @@ -313,11 +295,11 @@ int radix_tree_insert(struct radix_tree_root *root, if (node) { node->count++; - rcu_assign_pointer(node->slots[offset], item); + node->slots[offset] = item; BUG_ON(tag_get(node, 0, offset)); BUG_ON(tag_get(node, 1, offset)); } else { - rcu_assign_pointer(root->rnode, radix_tree_ptr_to_direct(item)); + root->rnode = item; BUG_ON(root_tag_get(root, 0)); BUG_ON(root_tag_get(root, 1)); } @@ -326,54 +308,49 @@ int radix_tree_insert(struct radix_tree_root *root, } EXPORT_SYMBOL(radix_tree_insert); -/** - * radix_tree_lookup_slot - lookup a slot in a radix tree - * @root: radix tree root - * @index: index key - * - * Returns: the slot corresponding to the position @index in the - * radix tree @root. This is useful for update-if-exists operations. - * - * This function cannot be called under rcu_read_lock, it must be - * excluded from writers, as must the returned slot for subsequent - * use by radix_tree_deref_slot() and radix_tree_replace slot. - * Caller must hold tree write locked across slot lookup and - * replace. - */ -void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) +static inline void **__lookup_slot(struct radix_tree_root *root, + unsigned long index) { unsigned int height, shift; - struct radix_tree_node *node, **slot; - - node = root->rnode; - if (node == NULL) - return NULL; + struct radix_tree_node **slot; - if (radix_tree_is_direct_ptr(node)) { - if (index > 0) - return NULL; - return (void **)&root->rnode; - } + height = root->height; - height = node->height; if (index > radix_tree_maxindex(height)) return NULL; + if (height == 0 && root->rnode) + return (void **)&root->rnode; + shift = (height-1) * RADIX_TREE_MAP_SHIFT; + slot = &root->rnode; - do { - slot = (struct radix_tree_node **) - (node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); - node = *slot; - if (node == NULL) + while (height > 0) { + if (*slot == NULL) return NULL; + slot = (struct radix_tree_node **) + ((*slot)->slots + + ((index >> shift) & RADIX_TREE_MAP_MASK)); shift -= RADIX_TREE_MAP_SHIFT; height--; - } while (height > 0); + } return (void **)slot; } + +/** + * radix_tree_lookup_slot - lookup a slot in a radix tree + * @root: radix tree root + * @index: index key + * + * Lookup the slot corresponding to the position @index in the radix tree + * @root. This is useful for update-if-exists operations. + */ +void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) +{ + return __lookup_slot(root, index); +} EXPORT_SYMBOL(radix_tree_lookup_slot); /** @@ -382,45 +359,13 @@ EXPORT_SYMBOL(radix_tree_lookup_slot); * @index: index key * * Lookup the item at the position @index in the radix tree @root. - * - * This function can be called under rcu_read_lock, however the caller - * must manage lifetimes of leaf nodes (eg. RCU may also be used to free - * them safely). No RCU barriers are required to access or modify the - * returned item, however. */ void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index) { - unsigned int height, shift; - struct radix_tree_node *node, **slot; - - node = rcu_dereference(root->rnode); - if (node == NULL) - return NULL; - - if (radix_tree_is_direct_ptr(node)) { - if (index > 0) - return NULL; - return radix_tree_direct_to_ptr(node); - } - - height = node->height; - if (index > radix_tree_maxindex(height)) - return NULL; - - shift = (height-1) * RADIX_TREE_MAP_SHIFT; + void **slot; - do { - slot = (struct radix_tree_node **) - (node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); - node = rcu_dereference(*slot); - if (node == NULL) - return NULL; - - shift -= RADIX_TREE_MAP_SHIFT; - height--; - } while (height > 0); - - return node; + slot = __lookup_slot(root, index); + return slot != NULL ? *slot : NULL; } EXPORT_SYMBOL(radix_tree_lookup); @@ -550,30 +495,27 @@ int radix_tree_tag_get(struct radix_tree_root *root, unsigned long index, unsigned int tag) { unsigned int height, shift; - struct radix_tree_node *node; + struct radix_tree_node *slot; int saw_unset_tag = 0; - /* check the root's tag bit */ - if (!root_tag_get(root, tag)) + height = root->height; + if (index > radix_tree_maxindex(height)) return 0; - node = rcu_dereference(root->rnode); - if (node == NULL) + /* check the root's tag bit */ + if (!root_tag_get(root, tag)) return 0; - if (radix_tree_is_direct_ptr(node)) - return (index == 0); - - height = node->height; - if (index > radix_tree_maxindex(height)) - return 0; + if (height == 0) + return 1; shift = (height - 1) * RADIX_TREE_MAP_SHIFT; + slot = root->rnode; for ( ; ; ) { int offset; - if (node == NULL) + if (slot == NULL) return 0; offset = (index >> shift) & RADIX_TREE_MAP_MASK; @@ -582,15 +524,15 @@ int radix_tree_tag_get(struct radix_tree_root *root, * This is just a debug check. Later, we can bale as soon as * we see an unset tag. */ - if (!tag_get(node, tag, offset)) + if (!tag_get(slot, tag, offset)) saw_unset_tag = 1; if (height == 1) { - int ret = tag_get(node, tag, offset); + int ret = tag_get(slot, tag, offset); BUG_ON(ret && saw_unset_tag); return !!ret; } - node = rcu_dereference(node->slots[offset]); + slot = slot->slots[offset]; shift -= RADIX_TREE_MAP_SHIFT; height--; } @@ -599,45 +541,47 @@ EXPORT_SYMBOL(radix_tree_tag_get); #endif static unsigned int -__lookup(struct radix_tree_node *slot, void **results, unsigned long index, +__lookup(struct radix_tree_root *root, void **results, unsigned long index, unsigned int max_items, unsigned long *next_index) { unsigned int nr_found = 0; unsigned int shift, height; + struct radix_tree_node *slot; unsigned long i; - height = slot->height; - if (height == 0) + height = root->height; + if (height == 0) { + if (root->rnode && index == 0) + results[nr_found++] = root->rnode; goto out; + } + shift = (height-1) * RADIX_TREE_MAP_SHIFT; + slot = root->rnode; for ( ; height > 1; height--) { - i = (index >> shift) & RADIX_TREE_MAP_MASK; - for (;;) { + + for (i = (index >> shift) & RADIX_TREE_MAP_MASK ; + i < RADIX_TREE_MAP_SIZE; i++) { if (slot->slots[i] != NULL) break; index &= ~((1UL << shift) - 1); index += 1UL << shift; if (index == 0) goto out; /* 32-bit wraparound */ - i++; - if (i == RADIX_TREE_MAP_SIZE) - goto out; } + if (i == RADIX_TREE_MAP_SIZE) + goto out; shift -= RADIX_TREE_MAP_SHIFT; - slot = rcu_dereference(slot->slots[i]); - if (slot == NULL) - goto out; + slot = slot->slots[i]; } /* Bottom level: grab some items */ for (i = index & RADIX_TREE_MAP_MASK; i < RADIX_TREE_MAP_SIZE; i++) { - struct radix_tree_node *node; index++; - node = slot->slots[i]; - if (node) { - results[nr_found++] = rcu_dereference(node); + if (slot->slots[i]) { + results[nr_found++] = slot->slots[i]; if (nr_found == max_items) goto out; } @@ -659,51 +603,28 @@ __lookup(struct radix_tree_node *slot, void **results, unsigned long index, * *@results. * * The implementation is naive. - * - * Like radix_tree_lookup, radix_tree_gang_lookup may be called under - * rcu_read_lock. In this case, rather than the returned results being - * an atomic snapshot of the tree at a single point in time, the semantics - * of an RCU protected gang lookup are as though multiple radix_tree_lookups - * have been issued in individual locks, and results stored in 'results'. */ unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items) { - unsigned long max_index; - struct radix_tree_node *node; + const unsigned long max_index = radix_tree_maxindex(root->height); unsigned long cur_index = first_index; - unsigned int ret; - - node = rcu_dereference(root->rnode); - if (!node) - return 0; + unsigned int ret = 0; - if (radix_tree_is_direct_ptr(node)) { - if (first_index > 0) - return 0; - node = radix_tree_direct_to_ptr(node); - results[0] = rcu_dereference(node); - return 1; - } - - max_index = radix_tree_maxindex(node->height); - - ret = 0; while (ret < max_items) { unsigned int nr_found; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; - nr_found = __lookup(node, results + ret, cur_index, + nr_found = __lookup(root, results + ret, cur_index, max_items - ret, &next_index); ret += nr_found; if (next_index == 0) break; cur_index = next_index; } - return ret; } EXPORT_SYMBOL(radix_tree_gang_lookup); @@ -713,64 +634,55 @@ EXPORT_SYMBOL(radix_tree_gang_lookup); * open-coding the search. */ static unsigned int -__lookup_tag(struct radix_tree_node *slot, void **results, unsigned long index, +__lookup_tag(struct radix_tree_root *root, void **results, unsigned long index, unsigned int max_items, unsigned long *next_index, unsigned int tag) { unsigned int nr_found = 0; - unsigned int shift, height; + unsigned int shift; + unsigned int height = root->height; + struct radix_tree_node *slot; - height = slot->height; - if (height == 0) + if (height == 0) { + if (root->rnode && index == 0) + results[nr_found++] = root->rnode; goto out; - shift = (height-1) * RADIX_TREE_MAP_SHIFT; + } - while (height > 0) { - unsigned long i = (index >> shift) & RADIX_TREE_MAP_MASK ; + shift = (height - 1) * RADIX_TREE_MAP_SHIFT; + slot = root->rnode; + + do { + unsigned long i = (index >> shift) & RADIX_TREE_MAP_MASK; - for (;;) { - if (tag_get(slot, tag, i)) + for ( ; i < RADIX_TREE_MAP_SIZE; i++) { + if (tag_get(slot, tag, i)) { + BUG_ON(slot->slots[i] == NULL); break; + } index &= ~((1UL << shift) - 1); index += 1UL << shift; if (index == 0) goto out; /* 32-bit wraparound */ - i++; - if (i == RADIX_TREE_MAP_SIZE) - goto out; } + if (i == RADIX_TREE_MAP_SIZE) + goto out; height--; if (height == 0) { /* Bottom level: grab some items */ unsigned long j = index & RADIX_TREE_MAP_MASK; for ( ; j < RADIX_TREE_MAP_SIZE; j++) { - struct radix_tree_node *node; index++; - if (!tag_get(slot, tag, j)) - continue; - node = slot->slots[j]; - /* - * Even though the tag was found set, we need to - * recheck that we have a non-NULL node, because - * if this lookup is lockless, it may have been - * subsequently deleted. - * - * Similar care must be taken in any place that - * lookup ->slots[x] without a lock (ie. can't - * rely on its value remaining the same). - */ - if (node) { - node = rcu_dereference(node); - results[nr_found++] = node; + if (tag_get(slot, tag, j)) { + BUG_ON(slot->slots[j] == NULL); + results[nr_found++] = slot->slots[j]; if (nr_found == max_items) goto out; } } } shift -= RADIX_TREE_MAP_SHIFT; - slot = rcu_dereference(slot->slots[i]); - if (slot == NULL) - break; - } + slot = slot->slots[i]; + } while (height > 0); out: *next_index = index; return nr_found; @@ -794,44 +706,27 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag) { - struct radix_tree_node *node; - unsigned long max_index; + const unsigned long max_index = radix_tree_maxindex(root->height); unsigned long cur_index = first_index; - unsigned int ret; + unsigned int ret = 0; /* check the root's tag bit */ if (!root_tag_get(root, tag)) return 0; - node = rcu_dereference(root->rnode); - if (!node) - return 0; - - if (radix_tree_is_direct_ptr(node)) { - if (first_index > 0) - return 0; - node = radix_tree_direct_to_ptr(node); - results[0] = rcu_dereference(node); - return 1; - } - - max_index = radix_tree_maxindex(node->height); - - ret = 0; while (ret < max_items) { unsigned int nr_found; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; - nr_found = __lookup_tag(node, results + ret, cur_index, + nr_found = __lookup_tag(root, results + ret, cur_index, max_items - ret, &next_index, tag); ret += nr_found; if (next_index == 0) break; cur_index = next_index; } - return ret; } EXPORT_SYMBOL(radix_tree_gang_lookup_tag); @@ -847,19 +742,8 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) root->rnode->count == 1 && root->rnode->slots[0]) { struct radix_tree_node *to_free = root->rnode; - void *newptr; - /* - * We don't need rcu_assign_pointer(), since we are simply - * moving the node from one part of the tree to another. If - * it was safe to dereference the old pointer to it - * (to_free->slots[0]), it will be safe to dereference the new - * one (root->rnode). - */ - newptr = to_free->slots[0]; - if (root->height == 1) - newptr = radix_tree_ptr_to_direct(newptr); - root->rnode = newptr; + root->rnode = to_free->slots[0]; root->height--; /* must only free zeroed nodes into the slab */ tag_clear(to_free, 0, 0); @@ -883,7 +767,6 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) { struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path; struct radix_tree_node *slot = NULL; - struct radix_tree_node *to_free; unsigned int height, shift; int tag; int offset; @@ -894,7 +777,6 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) slot = root->rnode; if (height == 0 && root->rnode) { - slot = radix_tree_direct_to_ptr(slot); root_tag_clear_all(root); root->rnode = NULL; goto out; @@ -927,17 +809,10 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) radix_tree_tag_clear(root, index, tag); } - to_free = NULL; /* Now free the nodes we do not need anymore */ while (pathp->node) { pathp->node->slots[pathp->offset] = NULL; pathp->node->count--; - /* - * Queue the node for deferred freeing after the - * last reference to it disappears (set NULL, above). - */ - if (to_free) - radix_tree_node_free(to_free); if (pathp->node->count) { if (pathp->node == root->rnode) @@ -946,15 +821,13 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) } /* Node with zero slots in use so free it */ - to_free = pathp->node; - pathp--; + radix_tree_node_free(pathp->node); + pathp--; } root_tag_clear_all(root); root->height = 0; root->rnode = NULL; - if (to_free) - radix_tree_node_free(to_free); out: return slot; @@ -973,7 +846,7 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag) EXPORT_SYMBOL(radix_tree_tagged); static void -radix_tree_node_ctor(void *node, struct kmem_cache *cachep, unsigned long flags) +radix_tree_node_ctor(void *node, kmem_cache_t *cachep, unsigned long flags) { memset(node, 0, sizeof(struct radix_tree_node)); } @@ -996,6 +869,7 @@ static __init void radix_tree_init_maxindex(void) height_to_maxindex[i] = __maxindex(i); } +#ifdef CONFIG_HOTPLUG_CPU static int radix_tree_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -1015,6 +889,7 @@ static int radix_tree_callback(struct notifier_block *nfb, } return NOTIFY_OK; } +#endif /* CONFIG_HOTPLUG_CPU */ void __init radix_tree_init(void) { diff --git a/trunk/lib/spinlock_debug.c b/trunk/lib/spinlock_debug.c index 479fd462eaa9..b6c4f898197c 100644 --- a/trunk/lib/spinlock_debug.c +++ b/trunk/lib/spinlock_debug.c @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -118,9 +117,6 @@ static void __spin_lock_debug(spinlock_t *lock) raw_smp_processor_id(), current->comm, current->pid, lock); dump_stack(); -#ifdef CONFIG_SMP - trigger_all_cpu_backtrace(); -#endif } } } diff --git a/trunk/mm/allocpercpu.c b/trunk/mm/allocpercpu.c index b2486cf887a0..eaa9abeea536 100644 --- a/trunk/mm/allocpercpu.c +++ b/trunk/mm/allocpercpu.c @@ -17,9 +17,10 @@ void percpu_depopulate(void *__pdata, int cpu) { struct percpu_data *pdata = __percpu_disguise(__pdata); - - kfree(pdata->ptrs[cpu]); - pdata->ptrs[cpu] = NULL; + if (pdata->ptrs[cpu]) { + kfree(pdata->ptrs[cpu]); + pdata->ptrs[cpu] = NULL; + } } EXPORT_SYMBOL_GPL(percpu_depopulate); @@ -122,8 +123,6 @@ EXPORT_SYMBOL_GPL(__percpu_alloc_mask); */ void percpu_free(void *__pdata) { - if (unlikely(!__pdata)) - return; __percpu_depopulate_mask(__pdata, &cpu_possible_map); kfree(__percpu_disguise(__pdata)); } diff --git a/trunk/mm/bootmem.c b/trunk/mm/bootmem.c index 00a96970b237..d53112fcb404 100644 --- a/trunk/mm/bootmem.c +++ b/trunk/mm/bootmem.c @@ -27,6 +27,8 @@ unsigned long max_low_pfn; unsigned long min_low_pfn; unsigned long max_pfn; +EXPORT_UNUSED_SYMBOL(max_pfn); /* June 2006 */ + static LIST_HEAD(bdata_list); #ifdef CONFIG_CRASH_DUMP /* @@ -194,10 +196,6 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size, if (limit && bdata->node_boot_start >= limit) return NULL; - /* on nodes without memory - bootmem_map is NULL */ - if (!bdata->node_bootmem_map) - return NULL; - end_pfn = bdata->node_low_pfn; limit = PFN_DOWN(limit); if (limit && end_pfn > limit) diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index af7e2f5caea9..13df01c50479 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -1445,6 +1445,7 @@ struct page *filemap_nopage(struct vm_area_struct *area, * effect. */ error = page_cache_read(file, pgoff); + grab_swap_token(); /* * The page we want has now been added to the page cache. diff --git a/trunk/mm/fremap.c b/trunk/mm/fremap.c index b77a002c3352..7a9d0f5d246d 100644 --- a/trunk/mm/fremap.c +++ b/trunk/mm/fremap.c @@ -101,6 +101,7 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, { int err = -ENOMEM; pte_t *pte; + pte_t pte_val; spinlock_t *ptl; pte = get_locked_pte(mm, addr, &ptl); @@ -113,6 +114,7 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, } set_pte_at(mm, addr, pte, pgoff_to_pte(pgoff)); + pte_val = *pte; /* * We don't need to run update_mmu_cache() here because the "file pte" * being installed by install_file_pte() is not a real pte - it's a diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 0ccc7f230252..a088f593a807 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -109,7 +109,7 @@ static int alloc_fresh_huge_page(void) if (nid == MAX_NUMNODES) nid = first_node(node_online_map); if (page) { - set_compound_page_dtor(page, free_huge_page); + page[1].lru.next = (void *)free_huge_page; /* dtor */ spin_lock(&hugetlb_lock); nr_huge_pages++; nr_huge_pages_node[page_to_nid(page)]++; @@ -344,6 +344,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, entry = *src_pte; ptepage = pte_page(entry); get_page(ptepage); + add_mm_counter(dst, file_rss, HPAGE_SIZE / PAGE_SIZE); set_huge_pte_at(dst, addr, dst_pte, entry); } spin_unlock(&src->page_table_lock); @@ -364,11 +365,6 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, pte_t pte; struct page *page; struct page *tmp; - /* - * A page gathering list, protected by per file i_mmap_lock. The - * lock is used to avoid list corruption from multiple unmapping - * of the same page since we are using page->lru. - */ LIST_HEAD(page_list); WARN_ON(!is_vm_hugetlb_page(vma)); @@ -376,21 +372,24 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, BUG_ON(end & ~HPAGE_MASK); spin_lock(&mm->page_table_lock); + + /* Update high watermark before we lower rss */ + update_hiwater_rss(mm); + for (address = start; address < end; address += HPAGE_SIZE) { ptep = huge_pte_offset(mm, address); if (!ptep) continue; - if (huge_pmd_unshare(mm, &address, ptep)) - continue; - pte = huge_ptep_get_and_clear(mm, address, ptep); if (pte_none(pte)) continue; page = pte_page(pte); list_add(&page->lru, &page_list); + add_mm_counter(mm, file_rss, (int) -(HPAGE_SIZE / PAGE_SIZE)); } + spin_unlock(&mm->page_table_lock); flush_tlb_range(vma, start, end); list_for_each_entry_safe(page, tmp, &page_list, lru) { @@ -516,6 +515,7 @@ int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma, if (!pte_none(*ptep)) goto backout; + add_mm_counter(mm, file_rss, HPAGE_SIZE / PAGE_SIZE); new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE) && (vma->vm_flags & VM_SHARED))); set_huge_pte_at(mm, address, ptep, new_pte); @@ -653,14 +653,11 @@ void hugetlb_change_protection(struct vm_area_struct *vma, BUG_ON(address >= end); flush_cache_range(vma, address, end); - spin_lock(&vma->vm_file->f_mapping->i_mmap_lock); spin_lock(&mm->page_table_lock); for (; address < end; address += HPAGE_SIZE) { ptep = huge_pte_offset(mm, address); if (!ptep) continue; - if (huge_pmd_unshare(mm, &address, ptep)) - continue; if (!pte_none(*ptep)) { pte = huge_ptep_get_and_clear(mm, address, ptep); pte = pte_mkhuge(pte_modify(pte, newprot)); @@ -669,7 +666,6 @@ void hugetlb_change_protection(struct vm_area_struct *vma, } } spin_unlock(&mm->page_table_lock); - spin_unlock(&vma->vm_file->f_mapping->i_mmap_lock); flush_tlb_range(vma, start, end); } diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 4198df0dff1c..156861fcac43 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1902,6 +1902,7 @@ int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end) return 0; } +EXPORT_UNUSED_SYMBOL(vmtruncate_range); /* June 2006 */ /** * swapin_readahead - swap in pages in hope we need them soon @@ -1990,7 +1991,6 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, delayacct_set_flag(DELAYACCT_PF_SWAPIN); page = lookup_swap_cache(entry); if (!page) { - grab_swap_token(); /* Contend for token _before_ read-in */ swapin_readahead(entry, address, vma); page = read_swap_cache_async(entry, vma, address); if (!page) { @@ -2008,6 +2008,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, /* Had to read the page from swap area: Major fault */ ret = VM_FAULT_MAJOR; count_vm_event(PGMAJFAULT); + grab_swap_token(); } delayacct_clear_flag(DELAYACCT_PF_SWAPIN); diff --git a/trunk/mm/memory_hotplug.c b/trunk/mm/memory_hotplug.c index 0c055a090f4d..fd678a662eae 100644 --- a/trunk/mm/memory_hotplug.c +++ b/trunk/mm/memory_hotplug.c @@ -72,6 +72,7 @@ static int __add_zone(struct zone *zone, unsigned long phys_start_pfn) return ret; } memmap_init_zone(nr_pages, nid, zone_type, phys_start_pfn); + zonetable_add(zone, nid, zone_type, phys_start_pfn, nr_pages); return 0; } diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index b917d6fdc1bb..617fb31086ee 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -141,11 +141,9 @@ static struct zonelist *bind_zonelist(nodemask_t *nodes) enum zone_type k; max = 1 + MAX_NR_ZONES * nodes_weight(*nodes); - max++; /* space for zlcache_ptr (see mmzone.h) */ zl = kmalloc(sizeof(struct zone *) * max, GFP_KERNEL); if (!zl) return NULL; - zl->zlcache_ptr = NULL; num = 0; /* First put in the highest zones from all nodes, then all the next lower zones etc. Avoid empty zones because the memory allocator @@ -221,7 +219,7 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, orig_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); do { struct page *page; - int nid; + unsigned int nid; if (!pte_present(*pte)) continue; @@ -1326,7 +1324,7 @@ struct mempolicy *__mpol_copy(struct mempolicy *old) atomic_set(&new->refcnt, 1); if (new->policy == MPOL_BIND) { int sz = ksize(old->v.zonelist); - new->v.zonelist = kmemdup(old->v.zonelist, sz, GFP_KERNEL); + new->v.zonelist = kmemdup(old->v.zonelist, sz, SLAB_KERNEL); if (!new->v.zonelist) { kmem_cache_free(policy_cache, new); return ERR_PTR(-ENOMEM); @@ -1707,8 +1705,8 @@ void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new) * Display pages allocated per node and memory policy via /proc. */ -static const char * const policy_types[] = - { "default", "prefer", "bind", "interleave" }; +static const char *policy_types[] = { "default", "prefer", "bind", + "interleave" }; /* * Convert a mempolicy into a string. diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index e9b161bde95b..b4979d423d2b 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -294,7 +294,7 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, static int migrate_page_move_mapping(struct address_space *mapping, struct page *newpage, struct page *page) { - void **pslot; + struct page **radix_pointer; if (!mapping) { /* Anonymous page */ @@ -305,11 +305,12 @@ static int migrate_page_move_mapping(struct address_space *mapping, write_lock_irq(&mapping->tree_lock); - pslot = radix_tree_lookup_slot(&mapping->page_tree, - page_index(page)); + radix_pointer = (struct page **)radix_tree_lookup_slot( + &mapping->page_tree, + page_index(page)); if (page_count(page) != 2 + !!PagePrivate(page) || - (struct page *)radix_tree_deref_slot(pslot) != page) { + *radix_pointer != page) { write_unlock_irq(&mapping->tree_lock); return -EAGAIN; } @@ -317,7 +318,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, /* * Now we know that no one else is looking at the page. */ - get_page(newpage); /* add cache reference */ + get_page(newpage); #ifdef CONFIG_SWAP if (PageSwapCache(page)) { SetPageSwapCache(newpage); @@ -325,14 +326,8 @@ static int migrate_page_move_mapping(struct address_space *mapping, } #endif - radix_tree_replace_slot(pslot, newpage); - - /* - * Drop cache reference from old page. - * We know this isn't the last reference. - */ + *radix_pointer = newpage; __put_page(page); - write_unlock_irq(&mapping->tree_lock); return 0; diff --git a/trunk/mm/mlock.c b/trunk/mm/mlock.c index 3446b7ef731e..b90c59573abf 100644 --- a/trunk/mm/mlock.c +++ b/trunk/mm/mlock.c @@ -65,7 +65,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev, ret = make_pages_present(start, end); } - mm->locked_vm -= pages; + vma->vm_mm->locked_vm -= pages; out: if (ret == -ENOMEM) ret = -EAGAIN; diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 7be110e98d4c..7b40abd7cba2 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -1736,7 +1736,7 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, if (mm->map_count >= sysctl_max_map_count) return -ENOMEM; - new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + new = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!new) return -ENOMEM; @@ -2057,7 +2057,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, vma_start < new_vma->vm_end) *vmap = new_vma; } else { - new_vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); + new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (new_vma) { *new_vma = *vma; pol = mpol_copy(vma_policy(vma)); diff --git a/trunk/mm/mmzone.c b/trunk/mm/mmzone.c index eb5838634f18..febea1c98168 100644 --- a/trunk/mm/mmzone.c +++ b/trunk/mm/mmzone.c @@ -14,6 +14,8 @@ struct pglist_data *first_online_pgdat(void) return NODE_DATA(first_online_node); } +EXPORT_UNUSED_SYMBOL(first_online_pgdat); /* June 2006 */ + struct pglist_data *next_online_pgdat(struct pglist_data *pgdat) { int nid = next_online_node(pgdat->node_id); @@ -22,6 +24,8 @@ struct pglist_data *next_online_pgdat(struct pglist_data *pgdat) return NULL; return NODE_DATA(nid); } +EXPORT_UNUSED_SYMBOL(next_online_pgdat); /* June 2006 */ + /* * next_zone - helper magic for for_each_zone() @@ -41,4 +45,5 @@ struct zone *next_zone(struct zone *zone) } return zone; } +EXPORT_UNUSED_SYMBOL(next_zone); /* June 2006 */ diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index af874569d0f1..6a2a8aada401 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -808,9 +808,10 @@ unsigned long do_mmap_pgoff(struct file *file, vm_flags = determine_vm_flags(file, prot, flags, capabilities); /* we're going to need to record the mapping if it works */ - vml = kzalloc(sizeof(struct vm_list_struct), GFP_KERNEL); + vml = kmalloc(sizeof(struct vm_list_struct), GFP_KERNEL); if (!vml) goto error_getting_vml; + memset(vml, 0, sizeof(*vml)); down_write(&nommu_vma_sem); @@ -886,10 +887,11 @@ unsigned long do_mmap_pgoff(struct file *file, } /* we're going to need a VMA struct as well */ - vma = kzalloc(sizeof(struct vm_area_struct), GFP_KERNEL); + vma = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL); if (!vma) goto error_getting_vma; + memset(vma, 0, sizeof(*vma)); INIT_LIST_HEAD(&vma->anon_vma_node); atomic_set(&vma->vm_usage, 1); if (file) diff --git a/trunk/mm/oom_kill.c b/trunk/mm/oom_kill.c index 223d9ccb7d64..2e3ce3a928b9 100644 --- a/trunk/mm/oom_kill.c +++ b/trunk/mm/oom_kill.c @@ -264,7 +264,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints) * flag though it's unlikely that we select a process with CAP_SYS_RAW_IO * set. */ -static void __oom_kill_task(struct task_struct *p, int verbose) +static void __oom_kill_task(struct task_struct *p, const char *message) { if (is_init(p)) { WARN_ON(1); @@ -278,8 +278,10 @@ static void __oom_kill_task(struct task_struct *p, int verbose) return; } - if (verbose) - printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm); + if (message) { + printk(KERN_ERR "%s: Killed process %d (%s).\n", + message, p->pid, p->comm); + } /* * We give our sacrificial lamb high priority and access to @@ -292,7 +294,7 @@ static void __oom_kill_task(struct task_struct *p, int verbose) force_sig(SIGKILL, p); } -static int oom_kill_task(struct task_struct *p) +static int oom_kill_task(struct task_struct *p, const char *message) { struct mm_struct *mm; struct task_struct *g, *q; @@ -311,25 +313,15 @@ static int oom_kill_task(struct task_struct *p) if (mm == NULL) return 1; - /* - * Don't kill the process if any threads are set to OOM_DISABLE - */ - do_each_thread(g, q) { - if (q->mm == mm && p->oomkilladj == OOM_DISABLE) - return 1; - } while_each_thread(g, q); - - __oom_kill_task(p, 1); - + __oom_kill_task(p, message); /* * kill all processes that share the ->mm (i.e. all threads), - * but are in a different thread group. Don't let them have access - * to memory reserves though, otherwise we might deplete all memory. + * but are in a different thread group */ - do_each_thread(g, q) { + do_each_thread(g, q) if (q->mm == mm && q->tgid != p->tgid) - force_sig(SIGKILL, p); - } while_each_thread(g, q); + __oom_kill_task(q, message); + while_each_thread(g, q); return 0; } @@ -345,22 +337,21 @@ static int oom_kill_process(struct task_struct *p, unsigned long points, * its children or threads, just set TIF_MEMDIE so it can die quickly */ if (p->flags & PF_EXITING) { - __oom_kill_task(p, 0); + __oom_kill_task(p, NULL); return 0; } - printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n", - message, p->pid, p->comm, points); - + printk(KERN_ERR "Out of Memory: Kill process %d (%s) score %li" + " and children.\n", p->pid, p->comm, points); /* Try to kill a child first */ list_for_each(tsk, &p->children) { c = list_entry(tsk, struct task_struct, sibling); if (c->mm == p->mm) continue; - if (!oom_kill_task(c)) + if (!oom_kill_task(c, message)) return 0; } - return oom_kill_task(p); + return oom_kill_task(p, message); } static BLOCKING_NOTIFIER_HEAD(oom_notify_list); diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index cace22b3ac25..aa6fcc7ca66f 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -83,7 +83,14 @@ int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { EXPORT_SYMBOL(totalram_pages); -static char * const zone_names[MAX_NR_ZONES] = { +/* + * Used by page_zone() to look up the address of the struct zone whose + * id is encoded in the upper bits of page->flags + */ +struct zone *zone_table[1 << ZONETABLE_SHIFT] __read_mostly; +EXPORT_SYMBOL(zone_table); + +static char *zone_names[MAX_NR_ZONES] = { "DMA", #ifdef CONFIG_ZONE_DMA32 "DMA32", @@ -230,7 +237,7 @@ static void prep_compound_page(struct page *page, unsigned long order) int i; int nr_pages = 1 << order; - set_compound_page_dtor(page, free_compound_page); + page[1].lru.next = (void *)free_compound_page; /* set dtor */ page[1].lru.prev = (void *)order; for (i = 0; i < nr_pages; i++) { struct page *p = page + i; @@ -479,7 +486,7 @@ static void free_one_page(struct zone *zone, struct page *page, int order) spin_lock(&zone->lock); zone->all_unreclaimable = 0; zone->pages_scanned = 0; - __free_one_page(page, zone, order); + __free_one_page(page, zone ,order); spin_unlock(&zone->lock); } @@ -598,8 +605,6 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) 1 << PG_checked | 1 << PG_mappedtodisk); set_page_private(page, 0); set_page_refcounted(page); - - arch_alloc_page(page, order); kernel_map_pages(page, 1 << order, 1); if (gfp_flags & __GFP_ZERO) @@ -685,15 +690,9 @@ void drain_node_pages(int nodeid) pcp = &pset->pcp[i]; if (pcp->count) { - int to_drain; - local_irq_save(flags); - if (pcp->count >= pcp->batch) - to_drain = pcp->batch; - else - to_drain = pcp->count; - free_pages_bulk(zone, to_drain, &pcp->list, 0); - pcp->count -= to_drain; + free_pages_bulk(zone, pcp->count, &pcp->list, 0); + pcp->count = 0; local_irq_restore(flags); } } @@ -701,6 +700,7 @@ void drain_node_pages(int nodeid) } #endif +#if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU) static void __drain_pages(unsigned int cpu) { unsigned long flags; @@ -722,6 +722,7 @@ static void __drain_pages(unsigned int cpu) } } } +#endif /* CONFIG_PM || CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_PM @@ -924,160 +925,31 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark, return 1; } -#ifdef CONFIG_NUMA -/* - * zlc_setup - Setup for "zonelist cache". Uses cached zone data to - * skip over zones that are not allowed by the cpuset, or that have - * been recently (in last second) found to be nearly full. See further - * comments in mmzone.h. Reduces cache footprint of zonelist scans - * that have to skip over alot of full or unallowed zones. - * - * If the zonelist cache is present in the passed in zonelist, then - * returns a pointer to the allowed node mask (either the current - * tasks mems_allowed, or node_online_map.) - * - * If the zonelist cache is not available for this zonelist, does - * nothing and returns NULL. - * - * If the fullzones BITMAP in the zonelist cache is stale (more than - * a second since last zap'd) then we zap it out (clear its bits.) - * - * We hold off even calling zlc_setup, until after we've checked the - * first zone in the zonelist, on the theory that most allocations will - * be satisfied from that first zone, so best to examine that zone as - * quickly as we can. - */ -static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags) -{ - struct zonelist_cache *zlc; /* cached zonelist speedup info */ - nodemask_t *allowednodes; /* zonelist_cache approximation */ - - zlc = zonelist->zlcache_ptr; - if (!zlc) - return NULL; - - if (jiffies - zlc->last_full_zap > 1 * HZ) { - bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST); - zlc->last_full_zap = jiffies; - } - - allowednodes = !in_interrupt() && (alloc_flags & ALLOC_CPUSET) ? - &cpuset_current_mems_allowed : - &node_online_map; - return allowednodes; -} - -/* - * Given 'z' scanning a zonelist, run a couple of quick checks to see - * if it is worth looking at further for free memory: - * 1) Check that the zone isn't thought to be full (doesn't have its - * bit set in the zonelist_cache fullzones BITMAP). - * 2) Check that the zones node (obtained from the zonelist_cache - * z_to_n[] mapping) is allowed in the passed in allowednodes mask. - * Return true (non-zero) if zone is worth looking at further, or - * else return false (zero) if it is not. - * - * This check -ignores- the distinction between various watermarks, - * such as GFP_HIGH, GFP_ATOMIC, PF_MEMALLOC, ... If a zone is - * found to be full for any variation of these watermarks, it will - * be considered full for up to one second by all requests, unless - * we are so low on memory on all allowed nodes that we are forced - * into the second scan of the zonelist. - * - * In the second scan we ignore this zonelist cache and exactly - * apply the watermarks to all zones, even it is slower to do so. - * We are low on memory in the second scan, and should leave no stone - * unturned looking for a free page. - */ -static int zlc_zone_worth_trying(struct zonelist *zonelist, struct zone **z, - nodemask_t *allowednodes) -{ - struct zonelist_cache *zlc; /* cached zonelist speedup info */ - int i; /* index of *z in zonelist zones */ - int n; /* node that zone *z is on */ - - zlc = zonelist->zlcache_ptr; - if (!zlc) - return 1; - - i = z - zonelist->zones; - n = zlc->z_to_n[i]; - - /* This zone is worth trying if it is allowed but not full */ - return node_isset(n, *allowednodes) && !test_bit(i, zlc->fullzones); -} - /* - * Given 'z' scanning a zonelist, set the corresponding bit in - * zlc->fullzones, so that subsequent attempts to allocate a page - * from that zone don't waste time re-examining it. - */ -static void zlc_mark_zone_full(struct zonelist *zonelist, struct zone **z) -{ - struct zonelist_cache *zlc; /* cached zonelist speedup info */ - int i; /* index of *z in zonelist zones */ - - zlc = zonelist->zlcache_ptr; - if (!zlc) - return; - - i = z - zonelist->zones; - - set_bit(i, zlc->fullzones); -} - -#else /* CONFIG_NUMA */ - -static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags) -{ - return NULL; -} - -static int zlc_zone_worth_trying(struct zonelist *zonelist, struct zone **z, - nodemask_t *allowednodes) -{ - return 1; -} - -static void zlc_mark_zone_full(struct zonelist *zonelist, struct zone **z) -{ -} -#endif /* CONFIG_NUMA */ - -/* - * get_page_from_freelist goes through the zonelist trying to allocate + * get_page_from_freeliest goes through the zonelist trying to allocate * a page. */ static struct page * get_page_from_freelist(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, int alloc_flags) { - struct zone **z; + struct zone **z = zonelist->zones; struct page *page = NULL; - int classzone_idx = zone_idx(zonelist->zones[0]); + int classzone_idx = zone_idx(*z); struct zone *zone; - nodemask_t *allowednodes = NULL;/* zonelist_cache approximation */ - int zlc_active = 0; /* set if using zonelist_cache */ - int did_zlc_setup = 0; /* just call zlc_setup() one time */ -zonelist_scan: /* - * Scan zonelist, looking for a zone with enough free. + * Go through the zonelist once, looking for a zone with enough free. * See also cpuset_zone_allowed() comment in kernel/cpuset.c. */ - z = zonelist->zones; - do { - if (NUMA_BUILD && zlc_active && - !zlc_zone_worth_trying(zonelist, z, allowednodes)) - continue; zone = *z; if (unlikely(NUMA_BUILD && (gfp_mask & __GFP_THISNODE) && zone->zone_pgdat != zonelist->zones[0]->zone_pgdat)) break; if ((alloc_flags & ALLOC_CPUSET) && - !cpuset_zone_allowed(zone, gfp_mask)) - goto try_next_zone; + !cpuset_zone_allowed(zone, gfp_mask)) + continue; if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { unsigned long mark; @@ -1087,34 +959,18 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order, mark = zone->pages_low; else mark = zone->pages_high; - if (!zone_watermark_ok(zone, order, mark, - classzone_idx, alloc_flags)) { + if (!zone_watermark_ok(zone , order, mark, + classzone_idx, alloc_flags)) if (!zone_reclaim_mode || !zone_reclaim(zone, gfp_mask, order)) - goto this_zone_full; - } + continue; } page = buffered_rmqueue(zonelist, zone, order, gfp_mask); - if (page) + if (page) { break; -this_zone_full: - if (NUMA_BUILD) - zlc_mark_zone_full(zonelist, z); -try_next_zone: - if (NUMA_BUILD && !did_zlc_setup) { - /* we do zlc_setup after the first zone is tried */ - allowednodes = zlc_setup(zonelist, alloc_flags); - zlc_active = 1; - did_zlc_setup = 1; } } while (*(++z) != NULL); - - if (unlikely(NUMA_BUILD && page == NULL && zlc_active)) { - /* Disable zlc cache for second zonelist scan */ - zlc_active = 0; - goto zonelist_scan; - } return page; } @@ -1149,19 +1005,9 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order, if (page) goto got_pg; - /* - * GFP_THISNODE (meaning __GFP_THISNODE, __GFP_NORETRY and - * __GFP_NOWARN set) should not cause reclaim since the subsystem - * (f.e. slab) using GFP_THISNODE may choose to trigger reclaim - * using a larger set of nodes after it has established that the - * allowed per node queues are empty and that nodes are - * over allocated. - */ - if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE) - goto nopage; - - for (z = zonelist->zones; *z; z++) + do { wakeup_kswapd(*z, order); + } while (*(++z)); /* * OK, we're below the kswapd watermark and have kicked background @@ -1195,7 +1041,6 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order, /* This allocation should allow future memory freeing. */ -rebalance: if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) && !in_interrupt()) { if (!(gfp_mask & __GFP_NOMEMALLOC)) { @@ -1217,6 +1062,7 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order, if (!wait) goto nopage; +rebalance: cond_resched(); /* We now go into synchronous reclaim */ @@ -1416,7 +1262,7 @@ unsigned int nr_free_pagecache_pages(void) static inline void show_node(struct zone *zone) { if (NUMA_BUILD) - printk("Node %d ", zone_to_nid(zone)); + printk("Node %ld ", zone_to_nid(zone)); } void si_meminfo(struct sysinfo *val) @@ -1696,24 +1542,6 @@ static void __meminit build_zonelists(pg_data_t *pgdat) } } -/* Construct the zonelist performance cache - see further mmzone.h */ -static void __meminit build_zonelist_cache(pg_data_t *pgdat) -{ - int i; - - for (i = 0; i < MAX_NR_ZONES; i++) { - struct zonelist *zonelist; - struct zonelist_cache *zlc; - struct zone **z; - - zonelist = pgdat->node_zonelists + i; - zonelist->zlcache_ptr = zlc = &zonelist->zlcache; - bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST); - for (z = zonelist->zones; *z; z++) - zlc->z_to_n[z - zonelist->zones] = zone_to_nid(*z); - } -} - #else /* CONFIG_NUMA */ static void __meminit build_zonelists(pg_data_t *pgdat) @@ -1751,26 +1579,14 @@ static void __meminit build_zonelists(pg_data_t *pgdat) } } -/* non-NUMA variant of zonelist performance cache - just NULL zlcache_ptr */ -static void __meminit build_zonelist_cache(pg_data_t *pgdat) -{ - int i; - - for (i = 0; i < MAX_NR_ZONES; i++) - pgdat->node_zonelists[i].zlcache_ptr = NULL; -} - #endif /* CONFIG_NUMA */ /* return values int ....just for stop_machine_run() */ static int __meminit __build_all_zonelists(void *dummy) { int nid; - - for_each_online_node(nid) { + for_each_online_node(nid) build_zonelists(NODE_DATA(nid)); - build_zonelist_cache(NODE_DATA(nid)); - } return 0; } @@ -1899,6 +1715,20 @@ void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone, } } +#define ZONETABLE_INDEX(x, zone_nr) ((x << ZONES_SHIFT) | zone_nr) +void zonetable_add(struct zone *zone, int nid, enum zone_type zid, + unsigned long pfn, unsigned long size) +{ + unsigned long snum = pfn_to_section_nr(pfn); + unsigned long end = pfn_to_section_nr(pfn + size); + + if (FLAGS_HAS_NODE) + zone_table[ZONETABLE_INDEX(nid, zid)] = zone; + else + for (; snum <= end; snum++) + zone_table[ZONETABLE_INDEX(snum, zid)] = zone; +} + #ifndef __HAVE_ARCH_MEMMAP_INIT #define memmap_init(size, nid, zone, start_pfn) \ memmap_init_zone((size), (nid), (zone), (start_pfn)) @@ -2051,16 +1881,16 @@ static int __cpuinit pageset_cpuup_callback(struct notifier_block *nfb, int ret = NOTIFY_OK; switch (action) { - case CPU_UP_PREPARE: - if (process_zones(cpu)) - ret = NOTIFY_BAD; - break; - case CPU_UP_CANCELED: - case CPU_DEAD: - free_zone_pagesets(cpu); - break; - default: - break; + case CPU_UP_PREPARE: + if (process_zones(cpu)) + ret = NOTIFY_BAD; + break; + case CPU_UP_CANCELED: + case CPU_DEAD: + free_zone_pagesets(cpu); + break; + default: + break; } return ret; } @@ -2591,6 +2421,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat, if (!size) continue; + zonetable_add(zone, nid, j, zone_start_pfn, size); ret = init_currently_empty_zone(zone, zone_start_pfn, size); BUG_ON(ret); zone_start_pfn += size; @@ -2905,6 +2736,7 @@ void __init free_area_init(unsigned long *zones_size) __pa(PAGE_OFFSET) >> PAGE_SHIFT, NULL); } +#ifdef CONFIG_HOTPLUG_CPU static int page_alloc_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { @@ -2919,6 +2751,7 @@ static int page_alloc_cpu_notify(struct notifier_block *self, } return NOTIFY_OK; } +#endif /* CONFIG_HOTPLUG_CPU */ void __init page_alloc_init(void) { @@ -3222,7 +3055,7 @@ void *__init alloc_large_system_hash(const char *tablename, /* allow the kernel cmdline to have a say */ if (!numentries) { /* round applicable memory size up to nearest megabyte */ - numentries = nr_kernel_pages; + numentries = (flags & HASH_HIGHMEM) ? nr_all_pages : nr_kernel_pages; numentries += (1UL << (20 - PAGE_SHIFT)) - 1; numentries >>= 20 - PAGE_SHIFT; numentries <<= 20 - PAGE_SHIFT; diff --git a/trunk/mm/page_io.c b/trunk/mm/page_io.c index dbffec0d78c9..d4840ecbf8f9 100644 --- a/trunk/mm/page_io.c +++ b/trunk/mm/page_io.c @@ -147,3 +147,48 @@ int swap_readpage(struct file *file, struct page *page) out: return ret; } + +#ifdef CONFIG_SOFTWARE_SUSPEND +/* + * A scruffy utility function to read or write an arbitrary swap page + * and wait on the I/O. The caller must have a ref on the page. + * + * We use end_swap_bio_read() even for writes, because it happens to do what + * we want. + */ +int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page, + struct bio **bio_chain) +{ + struct bio *bio; + int ret = 0; + int bio_rw; + + lock_page(page); + + bio = get_swap_bio(GFP_KERNEL, entry.val, page, end_swap_bio_read); + if (bio == NULL) { + unlock_page(page); + ret = -ENOMEM; + goto out; + } + + bio_rw = rw; + if (!bio_chain) + bio_rw |= (1 << BIO_RW_SYNC); + if (bio_chain) + bio_get(bio); + submit_bio(bio_rw, bio); + if (bio_chain == NULL) { + wait_on_page_locked(page); + + if (!PageUptodate(page) || PageError(page)) + ret = -EIO; + } + if (bio_chain) { + bio->bi_private = *bio_chain; + *bio_chain = bio; + } +out: + return ret; +} +#endif diff --git a/trunk/mm/pdflush.c b/trunk/mm/pdflush.c index 8ce0900dc95c..b02102feeb4b 100644 --- a/trunk/mm/pdflush.c +++ b/trunk/mm/pdflush.c @@ -21,7 +21,6 @@ #include // Prototypes pdflush_operation() #include #include -#include /* diff --git a/trunk/mm/readahead.c b/trunk/mm/readahead.c index a386f2b6b335..23cb61a01c6e 100644 --- a/trunk/mm/readahead.c +++ b/trunk/mm/readahead.c @@ -148,7 +148,13 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages, if (!pagevec_add(&lru_pvec, page)) __pagevec_lru_add(&lru_pvec); if (ret) { - put_pages_list(pages); + while (!list_empty(pages)) { + struct page *victim; + + victim = list_to_page(pages); + list_del(&victim->lru); + page_cache_release(victim); + } break; } } diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index c820b4f77b8d..4959535fc14c 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -177,7 +177,7 @@ static inline void shmem_unacct_blocks(unsigned long flags, long pages) static struct super_operations shmem_ops; static const struct address_space_operations shmem_aops; -static const struct file_operations shmem_file_operations; +static struct file_operations shmem_file_operations; static struct inode_operations shmem_inode_operations; static struct inode_operations shmem_dir_inode_operations; static struct inode_operations shmem_special_inode_operations; @@ -1943,7 +1943,7 @@ static int shmem_xattr_security_set(struct inode *inode, const char *name, return security_inode_setsecurity(inode, name, value, size, flags); } -static struct xattr_handler shmem_xattr_security_handler = { +struct xattr_handler shmem_xattr_security_handler = { .prefix = XATTR_SECURITY_PREFIX, .list = shmem_xattr_security_list, .get = shmem_xattr_security_get, @@ -2263,7 +2263,7 @@ static struct kmem_cache *shmem_inode_cachep; static struct inode *shmem_alloc_inode(struct super_block *sb) { struct shmem_inode_info *p; - p = (struct shmem_inode_info *)kmem_cache_alloc(shmem_inode_cachep, GFP_KERNEL); + p = (struct shmem_inode_info *)kmem_cache_alloc(shmem_inode_cachep, SLAB_KERNEL); if (!p) return NULL; return &p->vfs_inode; @@ -2319,7 +2319,7 @@ static const struct address_space_operations shmem_aops = { .migratepage = migrate_page, }; -static const struct file_operations shmem_file_operations = { +static struct file_operations shmem_file_operations = { .mmap = shmem_mmap, #ifdef CONFIG_TMPFS .llseek = generic_file_llseek, diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 068cb4503c15..5de81473df34 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -103,12 +103,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -730,10 +730,7 @@ static inline void init_lock_keys(void) } #endif -/* - * 1. Guard access to the cache-chain. - * 2. Protect sanity of cpu_online_map against cpu hotplug events - */ +/* Guard access to the cache-chain. */ static DEFINE_MUTEX(cache_chain_mutex); static struct list_head cache_chain; @@ -869,22 +866,6 @@ static void __slab_error(const char *function, struct kmem_cache *cachep, dump_stack(); } -/* - * By default on NUMA we use alien caches to stage the freeing of - * objects allocated from other nodes. This causes massive memory - * inefficiencies when using fake NUMA setup to split memory into a - * large number of small nodes, so it can be disabled on the command - * line - */ - -static int use_alien_caches __read_mostly = 1; -static int __init noaliencache_setup(char *s) -{ - use_alien_caches = 0; - return 1; -} -__setup("noaliencache", noaliencache_setup); - #ifdef CONFIG_NUMA /* * Special reaping functions for NUMA systems called from cache_reap(). @@ -1015,7 +996,7 @@ static inline void *alternate_node_alloc(struct kmem_cache *cachep, return NULL; } -static inline void *____cache_alloc_node(struct kmem_cache *cachep, +static inline void *__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) { return NULL; @@ -1023,7 +1004,7 @@ static inline void *____cache_alloc_node(struct kmem_cache *cachep, #else /* CONFIG_NUMA */ -static void *____cache_alloc_node(struct kmem_cache *, gfp_t, int); +static void *__cache_alloc_node(struct kmem_cache *, gfp_t, int); static void *alternate_node_alloc(struct kmem_cache *, gfp_t); static struct array_cache **alloc_alien_cache(int node, int limit) @@ -1133,7 +1114,7 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp) * Make sure we are not freeing a object from another node to the array * cache on this cpu. */ - if (likely(slabp->nodeid == node) || unlikely(!use_alien_caches)) + if (likely(slabp->nodeid == node)) return 0; l3 = cachep->nodelists[node]; @@ -1211,7 +1192,7 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, list_for_each_entry(cachep, &cache_chain, next) { struct array_cache *nc; struct array_cache *shared; - struct array_cache **alien = NULL; + struct array_cache **alien; nc = alloc_arraycache(node, cachep->limit, cachep->batchcount); @@ -1223,11 +1204,9 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, if (!shared) goto bad; - if (use_alien_caches) { - alien = alloc_alien_cache(node, cachep->limit); - if (!alien) - goto bad; - } + alien = alloc_alien_cache(node, cachep->limit); + if (!alien) + goto bad; cachep->array[cpu] = nc; l3 = cachep->nodelists[node]; BUG_ON(!l3); @@ -1251,18 +1230,12 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, kfree(shared); free_alien_cache(alien); } + mutex_unlock(&cache_chain_mutex); break; case CPU_ONLINE: - mutex_unlock(&cache_chain_mutex); start_cpu_timer(cpu); break; #ifdef CONFIG_HOTPLUG_CPU - case CPU_DOWN_PREPARE: - mutex_lock(&cache_chain_mutex); - break; - case CPU_DOWN_FAILED: - mutex_unlock(&cache_chain_mutex); - break; case CPU_DEAD: /* * Even if all the cpus of a node are down, we don't free the @@ -1273,8 +1246,8 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, * gets destroyed at kmem_cache_destroy(). */ /* fall thru */ -#endif case CPU_UP_CANCELED: + mutex_lock(&cache_chain_mutex); list_for_each_entry(cachep, &cache_chain, next) { struct array_cache *nc; struct array_cache *shared; @@ -1335,9 +1308,11 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, } mutex_unlock(&cache_chain_mutex); break; +#endif } return NOTIFY_OK; bad: + mutex_unlock(&cache_chain_mutex); return NOTIFY_BAD; } @@ -1605,7 +1580,12 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid) flags |= __GFP_COMP; #endif - flags |= cachep->gfpflags; + /* + * Under NUMA we want memory on the indicated node. We will handle + * the needed fallback ourselves since we want to serve from our + * per node object lists first for other nodes. + */ + flags |= cachep->gfpflags | GFP_THISNODE; page = alloc_pages_node(nodeid, flags, cachep->gfporder); if (!page) @@ -2118,12 +2098,15 @@ kmem_cache_create (const char *name, size_t size, size_t align, } /* - * We use cache_chain_mutex to ensure a consistent view of - * cpu_online_map as well. Please see cpuup_callback + * Prevent CPUs from coming and going. + * lock_cpu_hotplug() nests outside cache_chain_mutex */ + lock_cpu_hotplug(); + mutex_lock(&cache_chain_mutex); list_for_each_entry(pc, &cache_chain, next) { + mm_segment_t old_fs = get_fs(); char tmp; int res; @@ -2132,7 +2115,9 @@ kmem_cache_create (const char *name, size_t size, size_t align, * destroy its slab cache and no-one else reuses the vmalloc * area of the module. Print a warning. */ - res = probe_kernel_address(pc->name, tmp); + set_fs(KERNEL_DS); + res = __get_user(tmp, pc->name); + set_fs(old_fs); if (res) { printk("SLAB: cache with size %d has lost its name\n", pc->buffer_size); @@ -2212,24 +2197,25 @@ kmem_cache_create (const char *name, size_t size, size_t align, if (flags & SLAB_RED_ZONE || flags & SLAB_STORE_USER) ralign = BYTES_PER_WORD; - /* 2) arch mandated alignment */ + /* 2) arch mandated alignment: disables debug if necessary */ if (ralign < ARCH_SLAB_MINALIGN) { ralign = ARCH_SLAB_MINALIGN; + if (ralign > BYTES_PER_WORD) + flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER); } - /* 3) caller mandated alignment */ + /* 3) caller mandated alignment: disables debug if necessary */ if (ralign < align) { ralign = align; + if (ralign > BYTES_PER_WORD) + flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER); } - /* disable debug if necessary */ - if (ralign > BYTES_PER_WORD) - flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER); /* * 4) Store it. */ align = ralign; /* Get cache's description obj. */ - cachep = kmem_cache_zalloc(&cache_cache, GFP_KERNEL); + cachep = kmem_cache_zalloc(&cache_cache, SLAB_KERNEL); if (!cachep) goto oops; @@ -2340,6 +2326,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, panic("kmem_cache_create(): failed to create slab `%s'\n", name); mutex_unlock(&cache_chain_mutex); + unlock_cpu_hotplug(); return cachep; } EXPORT_SYMBOL(kmem_cache_create); @@ -2457,7 +2444,6 @@ static int drain_freelist(struct kmem_cache *cache, return nr_freed; } -/* Called with cache_chain_mutex held to protect against cpu hotplug */ static int __cache_shrink(struct kmem_cache *cachep) { int ret = 0, i = 0; @@ -2488,13 +2474,9 @@ static int __cache_shrink(struct kmem_cache *cachep) */ int kmem_cache_shrink(struct kmem_cache *cachep) { - int ret; BUG_ON(!cachep || in_interrupt()); - mutex_lock(&cache_chain_mutex); - ret = __cache_shrink(cachep); - mutex_unlock(&cache_chain_mutex); - return ret; + return __cache_shrink(cachep); } EXPORT_SYMBOL(kmem_cache_shrink); @@ -2518,16 +2500,23 @@ void kmem_cache_destroy(struct kmem_cache *cachep) { BUG_ON(!cachep || in_interrupt()); + /* Don't let CPUs to come and go */ + lock_cpu_hotplug(); + /* Find the cache in the chain of caches. */ mutex_lock(&cache_chain_mutex); /* * the chain is never empty, cache_cache is never destroyed */ list_del(&cachep->next); + mutex_unlock(&cache_chain_mutex); + if (__cache_shrink(cachep)) { slab_error(cachep, "Can't free all objects"); + mutex_lock(&cache_chain_mutex); list_add(&cachep->next, &cache_chain); mutex_unlock(&cache_chain_mutex); + unlock_cpu_hotplug(); return; } @@ -2535,7 +2524,7 @@ void kmem_cache_destroy(struct kmem_cache *cachep) synchronize_rcu(); __kmem_cache_destroy(cachep); - mutex_unlock(&cache_chain_mutex); + unlock_cpu_hotplug(); } EXPORT_SYMBOL(kmem_cache_destroy); @@ -2559,7 +2548,7 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, if (OFF_SLAB(cachep)) { /* Slab management obj is off-slab. */ slabp = kmem_cache_alloc_node(cachep->slabp_cache, - local_flags & ~GFP_THISNODE, nodeid); + local_flags, nodeid); if (!slabp) return NULL; } else { @@ -2629,7 +2618,7 @@ static void cache_init_objs(struct kmem_cache *cachep, static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags) { - if (flags & GFP_DMA) + if (flags & SLAB_DMA) BUG_ON(!(cachep->gfpflags & GFP_DMA)); else BUG_ON(cachep->gfpflags & GFP_DMA); @@ -2700,10 +2689,10 @@ static void slab_map_pages(struct kmem_cache *cache, struct slab *slab, * Grow (by 1) the number of slabs within a cache. This is called by * kmem_cache_alloc() when there are no active objs left in a cache. */ -static int cache_grow(struct kmem_cache *cachep, - gfp_t flags, int nodeid, void *objp) +static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid) { struct slab *slabp; + void *objp; size_t offset; gfp_t local_flags; unsigned long ctor_flags; @@ -2713,12 +2702,12 @@ static int cache_grow(struct kmem_cache *cachep, * Be lazy and only check for valid flags here, keeping it out of the * critical path in kmem_cache_alloc(). */ - BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK | __GFP_NO_GROW)); - if (flags & __GFP_NO_GROW) + BUG_ON(flags & ~(SLAB_DMA | SLAB_LEVEL_MASK | SLAB_NO_GROW)); + if (flags & SLAB_NO_GROW) return 0; ctor_flags = SLAB_CTOR_CONSTRUCTOR; - local_flags = (flags & GFP_LEVEL_MASK); + local_flags = (flags & SLAB_LEVEL_MASK); if (!(local_flags & __GFP_WAIT)) /* * Not allowed to sleep. Need to tell a constructor about @@ -2755,14 +2744,12 @@ static int cache_grow(struct kmem_cache *cachep, * Get mem for the objs. Attempt to allocate a physical page from * 'nodeid'. */ - if (!objp) - objp = kmem_getpages(cachep, flags, nodeid); + objp = kmem_getpages(cachep, flags, nodeid); if (!objp) goto failed; /* Get slab management. */ - slabp = alloc_slabmgmt(cachep, objp, offset, - local_flags & ~GFP_THISNODE, nodeid); + slabp = alloc_slabmgmt(cachep, objp, offset, local_flags, nodeid); if (!slabp) goto opps1; @@ -3000,7 +2987,7 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) if (unlikely(!ac->avail)) { int x; - x = cache_grow(cachep, flags | GFP_THISNODE, node, NULL); + x = cache_grow(cachep, flags, node); /* cache_grow can reenable interrupts, then ac could change. */ ac = cpu_cache_get(cachep); @@ -3076,12 +3063,6 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, cachep->ctor(objp, cachep, ctor_flags); } -#if ARCH_SLAB_MINALIGN - if ((u32)objp & (ARCH_SLAB_MINALIGN-1)) { - printk(KERN_ERR "0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n", - objp, ARCH_SLAB_MINALIGN); - } -#endif return objp; } #else @@ -3124,10 +3105,10 @@ static __always_inline void *__cache_alloc(struct kmem_cache *cachep, objp = ____cache_alloc(cachep, flags); /* * We may just have run out of memory on the local node. - * ____cache_alloc_node() knows how to locate memory on other nodes + * __cache_alloc_node() knows how to locate memory on other nodes */ if (NUMA_BUILD && !objp) - objp = ____cache_alloc_node(cachep, flags, numa_node_id()); + objp = __cache_alloc_node(cachep, flags, numa_node_id()); local_irq_restore(save_flags); objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller); @@ -3154,17 +3135,15 @@ static void *alternate_node_alloc(struct kmem_cache *cachep, gfp_t flags) else if (current->mempolicy) nid_alloc = slab_node(current->mempolicy); if (nid_alloc != nid_here) - return ____cache_alloc_node(cachep, flags, nid_alloc); + return __cache_alloc_node(cachep, flags, nid_alloc); return NULL; } /* * Fallback function if there was no memory available and no objects on a - * certain node and fall back is permitted. First we scan all the - * available nodelists for available objects. If that fails then we - * perform an allocation without specifying a node. This allows the page - * allocator to do its reclaim / fallback magic. We then insert the - * slab into the proper nodelist and then allocate from it. + * certain node and we are allowed to fall back. We mimick the behavior of + * the page allocator. We fall back according to a zonelist determined by + * the policy layer while obeying cpuset constraints. */ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) { @@ -3172,51 +3151,15 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) ->node_zonelists[gfp_zone(flags)]; struct zone **z; void *obj = NULL; - int nid; -retry: - /* - * Look through allowed nodes for objects available - * from existing per node queues. - */ for (z = zonelist->zones; *z && !obj; z++) { - nid = zone_to_nid(*z); - - if (cpuset_zone_allowed(*z, flags) && - cache->nodelists[nid] && - cache->nodelists[nid]->free_objects) - obj = ____cache_alloc_node(cache, - flags | GFP_THISNODE, nid); - } + int nid = zone_to_nid(*z); - if (!obj) { - /* - * This allocation will be performed within the constraints - * of the current cpuset / memory policy requirements. - * We may trigger various forms of reclaim on the allowed - * set and go into memory reserves if necessary. - */ - obj = kmem_getpages(cache, flags, -1); - if (obj) { - /* - * Insert into the appropriate per node queues - */ - nid = page_to_nid(virt_to_page(obj)); - if (cache_grow(cache, flags, nid, obj)) { - obj = ____cache_alloc_node(cache, - flags | GFP_THISNODE, nid); - if (!obj) - /* - * Another processor may allocate the - * objects in the slab since we are - * not holding any locks. - */ - goto retry; - } else { - kmem_freepages(cache, obj); - obj = NULL; - } - } + if (zone_idx(*z) <= ZONE_NORMAL && + cpuset_zone_allowed(*z, flags) && + cache->nodelists[nid]) + obj = __cache_alloc_node(cache, + flags | __GFP_THISNODE, nid); } return obj; } @@ -3224,7 +3167,7 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) /* * A interface to enable slab creation on nodeid */ -static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, +static void *__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) { struct list_head *entry; @@ -3273,7 +3216,7 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, must_grow: spin_unlock(&l3->list_lock); - x = cache_grow(cachep, flags | GFP_THISNODE, nodeid, NULL); + x = cache_grow(cachep, flags, nodeid); if (x) goto retry; @@ -3491,59 +3434,35 @@ int fastcall kmem_ptr_validate(struct kmem_cache *cachep, void *ptr) * @flags: See kmalloc(). * @nodeid: node number of the target node. * - * Identical to kmem_cache_alloc but it will allocate memory on the given - * node, which can improve the performance for cpu bound structures. - * - * Fallback to other node is possible if __GFP_THISNODE is not set. + * Identical to kmem_cache_alloc, except that this function is slow + * and can sleep. And it will allocate memory on the given node, which + * can improve the performance for cpu bound structures. + * New and improved: it will now make sure that the object gets + * put on the correct node list so that there is no false sharing. */ -static __always_inline void * -__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, - int nodeid, void *caller) +void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) { unsigned long save_flags; - void *ptr = NULL; + void *ptr; cache_alloc_debugcheck_before(cachep, flags); local_irq_save(save_flags); - if (unlikely(nodeid == -1)) - nodeid = numa_node_id(); - - if (likely(cachep->nodelists[nodeid])) { - if (nodeid == numa_node_id()) { - /* - * Use the locally cached objects if possible. - * However ____cache_alloc does not allow fallback - * to other nodes. It may fail while we still have - * objects on other nodes available. - */ - ptr = ____cache_alloc(cachep, flags); - } - if (!ptr) { - /* ___cache_alloc_node can fall back to other nodes */ - ptr = ____cache_alloc_node(cachep, flags, nodeid); - } - } else { - /* Node not bootstrapped yet */ - if (!(flags & __GFP_THISNODE)) - ptr = fallback_alloc(cachep, flags); - } - + if (nodeid == -1 || nodeid == numa_node_id() || + !cachep->nodelists[nodeid]) + ptr = ____cache_alloc(cachep, flags); + else + ptr = __cache_alloc_node(cachep, flags, nodeid); local_irq_restore(save_flags); - ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller); - return ptr; -} + ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, + __builtin_return_address(0)); -void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) -{ - return __cache_alloc_node(cachep, flags, nodeid, - __builtin_return_address(0)); + return ptr; } EXPORT_SYMBOL(kmem_cache_alloc_node); -static __always_inline void * -__do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) +void *__kmalloc_node(size_t size, gfp_t flags, int node) { struct kmem_cache *cachep; @@ -3552,29 +3471,8 @@ __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) return NULL; return kmem_cache_alloc_node(cachep, flags, node); } - -#ifdef CONFIG_DEBUG_SLAB -void *__kmalloc_node(size_t size, gfp_t flags, int node) -{ - return __do_kmalloc_node(size, flags, node, - __builtin_return_address(0)); -} EXPORT_SYMBOL(__kmalloc_node); - -void *__kmalloc_node_track_caller(size_t size, gfp_t flags, - int node, void *caller) -{ - return __do_kmalloc_node(size, flags, node, caller); -} -EXPORT_SYMBOL(__kmalloc_node_track_caller); -#else -void *__kmalloc_node(size_t size, gfp_t flags, int node) -{ - return __do_kmalloc_node(size, flags, node, NULL); -} -EXPORT_SYMBOL(__kmalloc_node); -#endif /* CONFIG_DEBUG_SLAB */ -#endif /* CONFIG_NUMA */ +#endif /** * __do_kmalloc - allocate memory @@ -3685,15 +3583,13 @@ static int alloc_kmemlist(struct kmem_cache *cachep) int node; struct kmem_list3 *l3; struct array_cache *new_shared; - struct array_cache **new_alien = NULL; + struct array_cache **new_alien; for_each_online_node(node) { - if (use_alien_caches) { - new_alien = alloc_alien_cache(node, cachep->limit); - if (!new_alien) - goto fail; - } + new_alien = alloc_alien_cache(node, cachep->limit); + if (!new_alien) + goto fail; new_shared = alloc_arraycache(node, cachep->shared*cachep->batchcount, @@ -4142,7 +4038,7 @@ static int s_show(struct seq_file *m, void *p) * + further values on SMP and with statistics enabled */ -const struct seq_operations slabinfo_op = { +struct seq_operations slabinfo_op = { .start = s_start, .next = s_next, .stop = s_stop, @@ -4340,7 +4236,7 @@ static int leaks_show(struct seq_file *m, void *p) return 0; } -const struct seq_operations slabstats_op = { +struct seq_operations slabstats_op = { .start = leaks_start, .next = s_next, .stop = s_stop, diff --git a/trunk/mm/sparse.c b/trunk/mm/sparse.c index ac26eb0d73cd..b3c82ba30012 100644 --- a/trunk/mm/sparse.c +++ b/trunk/mm/sparse.c @@ -24,25 +24,6 @@ struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] #endif EXPORT_SYMBOL(mem_section); -#ifdef NODE_NOT_IN_PAGE_FLAGS -/* - * If we did not store the node number in the page then we have to - * do a lookup in the section_to_node_table in order to find which - * node the page belongs to. - */ -#if MAX_NUMNODES <= 256 -static u8 section_to_node_table[NR_MEM_SECTIONS] __cacheline_aligned; -#else -static u16 section_to_node_table[NR_MEM_SECTIONS] __cacheline_aligned; -#endif - -int page_to_nid(struct page *page) -{ - return section_to_node_table[page_to_section(page)]; -} -EXPORT_SYMBOL(page_to_nid); -#endif - #ifdef CONFIG_SPARSEMEM_EXTREME static struct mem_section *sparse_index_alloc(int nid) { @@ -68,10 +49,6 @@ static int sparse_index_init(unsigned long section_nr, int nid) struct mem_section *section; int ret = 0; -#ifdef NODE_NOT_IN_PAGE_FLAGS - section_to_node_table[section_nr] = nid; -#endif - if (mem_section[root]) return -EEXIST; diff --git a/trunk/mm/swap.c b/trunk/mm/swap.c index 2ed7be39795e..d9a3770d8f3c 100644 --- a/trunk/mm/swap.c +++ b/trunk/mm/swap.c @@ -57,9 +57,9 @@ static void put_compound_page(struct page *page) { page = (struct page *)page_private(page); if (put_page_testzero(page)) { - compound_page_dtor *dtor; + void (*dtor)(struct page *page); - dtor = get_compound_page_dtor(page); + dtor = (void (*)(struct page *))page[1].lru.next; (*dtor)(page); } } @@ -514,7 +514,5 @@ void __init swap_setup(void) * Right now other parts of the system means that we * _really_ don't want to cluster much more */ -#ifdef CONFIG_HOTPLUG_CPU hotcpu_notifier(cpu_swap_callback, 0); -#endif } diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index c5431072f422..a15def63f28f 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -427,48 +427,34 @@ void free_swap_and_cache(swp_entry_t entry) #ifdef CONFIG_SOFTWARE_SUSPEND /* - * Find the swap type that corresponds to given device (if any). + * Find the swap type that corresponds to given device (if any) * - * @offset - number of the PAGE_SIZE-sized block of the device, starting - * from 0, in which the swap header is expected to be located. - * - * This is needed for the suspend to disk (aka swsusp). + * This is needed for software suspend and is done in such a way that inode + * aliasing is allowed. */ -int swap_type_of(dev_t device, sector_t offset) +int swap_type_of(dev_t device) { - struct block_device *bdev = NULL; int i; - if (device) - bdev = bdget(device); - spin_lock(&swap_lock); for (i = 0; i < nr_swapfiles; i++) { - struct swap_info_struct *sis = swap_info + i; + struct inode *inode; - if (!(sis->flags & SWP_WRITEOK)) + if (!(swap_info[i].flags & SWP_WRITEOK)) continue; - if (!bdev) { + if (!device) { spin_unlock(&swap_lock); return i; } - if (bdev == sis->bdev) { - struct swap_extent *se; - - se = list_entry(sis->extent_list.next, - struct swap_extent, list); - if (se->start_block == offset) { - spin_unlock(&swap_lock); - bdput(bdev); - return i; - } + inode = swap_info[i].swap_file->f_dentry->d_inode; + if (S_ISBLK(inode->i_mode) && + device == MKDEV(imajor(inode), iminor(inode))) { + spin_unlock(&swap_lock); + return i; } } spin_unlock(&swap_lock); - if (bdev) - bdput(bdev); - return -ENODEV; } @@ -945,23 +931,6 @@ sector_t map_swap_page(struct swap_info_struct *sis, pgoff_t offset) } } -#ifdef CONFIG_SOFTWARE_SUSPEND -/* - * Get the (PAGE_SIZE) block corresponding to given offset on the swapdev - * corresponding to given index in swap_info (swap type). - */ -sector_t swapdev_block(int swap_type, pgoff_t offset) -{ - struct swap_info_struct *sis; - - if (swap_type >= nr_swapfiles) - return 0; - - sis = swap_info + swap_type; - return (sis->flags & SWP_WRITEOK) ? map_swap_page(sis, offset) : 0; -} -#endif /* CONFIG_SOFTWARE_SUSPEND */ - /* * Free all of a swapdev's extent information */ @@ -1305,13 +1274,10 @@ static void *swap_start(struct seq_file *swap, loff_t *pos) mutex_lock(&swapon_mutex); - if (!l) - return SEQ_START_TOKEN; - for (i = 0; i < nr_swapfiles; i++, ptr++) { if (!(ptr->flags & SWP_USED) || !ptr->swap_map) continue; - if (!--l) + if (!l--) return ptr; } @@ -1320,17 +1286,10 @@ static void *swap_start(struct seq_file *swap, loff_t *pos) static void *swap_next(struct seq_file *swap, void *v, loff_t *pos) { - struct swap_info_struct *ptr; + struct swap_info_struct *ptr = v; struct swap_info_struct *endptr = swap_info + nr_swapfiles; - if (v == SEQ_START_TOKEN) - ptr = swap_info; - else { - ptr = v; - ptr++; - } - - for (; ptr < endptr; ptr++) { + for (++ptr; ptr < endptr; ptr++) { if (!(ptr->flags & SWP_USED) || !ptr->swap_map) continue; ++*pos; @@ -1351,10 +1310,8 @@ static int swap_show(struct seq_file *swap, void *v) struct file *file; int len; - if (ptr == SEQ_START_TOKEN) { - seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n"); - return 0; - } + if (v == swap_info) + seq_puts(swap, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n"); file = ptr->swap_file; len = seq_path(swap, file->f_vfsmnt, file->f_dentry, " \t\n\\"); @@ -1368,7 +1325,7 @@ static int swap_show(struct seq_file *swap, void *v) return 0; } -static const struct seq_operations swaps_op = { +static struct seq_operations swaps_op = { .start = swap_start, .next = swap_next, .stop = swap_stop, @@ -1380,7 +1337,7 @@ static int swaps_open(struct inode *inode, struct file *file) return seq_open(file, &swaps_op); } -static const struct file_operations proc_swaps_operations = { +static struct file_operations proc_swaps_operations = { .open = swaps_open, .read = seq_read, .llseek = seq_lseek, @@ -1583,11 +1540,6 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) error = -EINVAL; if (!maxpages) goto bad_swap; - if (swapfilesize && maxpages > swapfilesize) { - printk(KERN_WARNING - "Swap area shorter than signature indicates\n"); - goto bad_swap; - } if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) goto bad_swap; if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) @@ -1615,6 +1567,12 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) goto bad_swap; } + if (swapfilesize && maxpages > swapfilesize) { + printk(KERN_WARNING + "Swap area shorter than signature indicates\n"); + error = -EINVAL; + goto bad_swap; + } if (nr_good_pages) { p->swap_map[0] = SWAP_MAP_BAD; p->max = maxpages; diff --git a/trunk/mm/thrash.c b/trunk/mm/thrash.c index 9ef9071f99bc..f4c560b4a2b7 100644 --- a/trunk/mm/thrash.c +++ b/trunk/mm/thrash.c @@ -7,74 +7,100 @@ * * Simple token based thrashing protection, using the algorithm * described in: http://www.cs.wm.edu/~sjiang/token.pdf - * - * Sep 2006, Ashwin Chaugule - * Improved algorithm to pass token: - * Each task has a priority which is incremented if it contended - * for the token in an interval less than its previous attempt. - * If the token is acquired, that task's priority is boosted to prevent - * the token from bouncing around too often and to let the task make - * some progress in its execution. */ - #include #include #include #include static DEFINE_SPINLOCK(swap_token_lock); -struct mm_struct *swap_token_mm; -static unsigned int global_faults; +static unsigned long swap_token_timeout; +static unsigned long swap_token_check; +struct mm_struct * swap_token_mm = &init_mm; -void grab_swap_token(void) -{ - int current_interval; +#define SWAP_TOKEN_CHECK_INTERVAL (HZ * 2) +#define SWAP_TOKEN_TIMEOUT (300 * HZ) +/* + * Currently disabled; Needs further code to work at HZ * 300. + */ +unsigned long swap_token_default_timeout = SWAP_TOKEN_TIMEOUT; - global_faults++; +/* + * Take the token away if the process had no page faults + * in the last interval, or if it has held the token for + * too long. + */ +#define SWAP_TOKEN_ENOUGH_RSS 1 +#define SWAP_TOKEN_TIMED_OUT 2 +static int should_release_swap_token(struct mm_struct *mm) +{ + int ret = 0; + if (!mm->recent_pagein) + ret = SWAP_TOKEN_ENOUGH_RSS; + else if (time_after(jiffies, swap_token_timeout)) + ret = SWAP_TOKEN_TIMED_OUT; + mm->recent_pagein = 0; + return ret; +} - current_interval = global_faults - current->mm->faultstamp; +/* + * Try to grab the swapout protection token. We only try to + * grab it once every TOKEN_CHECK_INTERVAL, both to prevent + * SMP lock contention and to check that the process that held + * the token before is no longer thrashing. + */ +void grab_swap_token(void) +{ + struct mm_struct *mm; + int reason; - if (!spin_trylock(&swap_token_lock)) + /* We have the token. Let others know we still need it. */ + if (has_swap_token(current->mm)) { + current->mm->recent_pagein = 1; + if (unlikely(!swap_token_default_timeout)) + disable_swap_token(); return; - - /* First come first served */ - if (swap_token_mm == NULL) { - current->mm->token_priority = current->mm->token_priority + 2; - swap_token_mm = current->mm; - goto out; } - if (current->mm != swap_token_mm) { - if (current_interval < current->mm->last_interval) - current->mm->token_priority++; - else { - current->mm->token_priority--; - if (unlikely(current->mm->token_priority < 0)) - current->mm->token_priority = 0; + if (time_after(jiffies, swap_token_check)) { + + if (!swap_token_default_timeout) { + swap_token_check = jiffies + SWAP_TOKEN_CHECK_INTERVAL; + return; } - /* Check if we deserve the token */ - if (current->mm->token_priority > - swap_token_mm->token_priority) { - current->mm->token_priority += 2; + + /* ... or if we recently held the token. */ + if (time_before(jiffies, current->mm->swap_token_time)) + return; + + if (!spin_trylock(&swap_token_lock)) + return; + + swap_token_check = jiffies + SWAP_TOKEN_CHECK_INTERVAL; + + mm = swap_token_mm; + if ((reason = should_release_swap_token(mm))) { + unsigned long eligible = jiffies; + if (reason == SWAP_TOKEN_TIMED_OUT) { + eligible += swap_token_default_timeout; + } + mm->swap_token_time = eligible; + swap_token_timeout = jiffies + swap_token_default_timeout; swap_token_mm = current->mm; } - } else { - /* Token holder came in again! */ - current->mm->token_priority += 2; + spin_unlock(&swap_token_lock); } - -out: - current->mm->faultstamp = global_faults; - current->mm->last_interval = current_interval; - spin_unlock(&swap_token_lock); -return; + return; } /* Called on process exit. */ void __put_swap_token(struct mm_struct *mm) { spin_lock(&swap_token_lock); - if (likely(mm == swap_token_mm)) - swap_token_mm = NULL; + if (likely(mm == swap_token_mm)) { + mm->swap_token_time = jiffies + SWAP_TOKEN_CHECK_INTERVAL; + swap_token_mm = &init_mm; + swap_token_check = jiffies; + } spin_unlock(&swap_token_lock); } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 093f5fe6dd77..518540a4a2a6 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -1173,12 +1172,11 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) if (!zone_watermark_ok(zone, order, zone->pages_high, 0, 0)) { end_zone = i; - break; + goto scan; } } - if (i < 0) - goto out; - + goto out; +scan: for (i = 0; i <= end_zone; i++) { struct zone *zone = pgdat->node_zones + i; @@ -1261,9 +1259,6 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) } if (!all_zones_ok) { cond_resched(); - - try_to_freeze(); - goto loop_again; } @@ -1513,6 +1508,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) } #endif +#ifdef CONFIG_HOTPLUG_CPU /* It's optimal to keep kswapds on the same CPUs as their memory, but not required for correctness. So if the last cpu in a node goes away, we get changed to run anywhere: as the first one comes back, @@ -1533,6 +1529,7 @@ static int __devinit cpu_callback(struct notifier_block *nfb, } return NOTIFY_OK; } +#endif /* CONFIG_HOTPLUG_CPU */ /* * This kswapd start function will be called by init and node-hot-add. diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index dc005a0c96ae..8614e8f6743b 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -430,7 +430,7 @@ static int frag_show(struct seq_file *m, void *arg) return 0; } -const struct seq_operations fragmentation_op = { +struct seq_operations fragmentation_op = { .start = frag_start, .next = frag_next, .stop = frag_stop, @@ -452,7 +452,7 @@ const struct seq_operations fragmentation_op = { #define TEXTS_FOR_ZONES(xx) xx "_dma", TEXT_FOR_DMA32(xx) xx "_normal", \ TEXT_FOR_HIGHMEM(xx) -static const char * const vmstat_text[] = { +static char *vmstat_text[] = { /* Zoned VM counters */ "nr_anon_pages", "nr_mapped", @@ -597,7 +597,7 @@ static int zoneinfo_show(struct seq_file *m, void *arg) return 0; } -const struct seq_operations zoneinfo_op = { +struct seq_operations zoneinfo_op = { .start = frag_start, /* iterate over all zones. The same as in * fragmentation. */ .next = frag_next, @@ -660,7 +660,7 @@ static void vmstat_stop(struct seq_file *m, void *arg) m->private = NULL; } -const struct seq_operations vmstat_op = { +struct seq_operations vmstat_op = { .start = vmstat_start, .next = vmstat_next, .stop = vmstat_stop, @@ -679,13 +679,13 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb, void *hcpu) { switch (action) { - case CPU_UP_PREPARE: - case CPU_UP_CANCELED: - case CPU_DEAD: - refresh_zone_stat_thresholds(); - break; - default: - break; + case CPU_UP_PREPARE: + case CPU_UP_CANCELED: + case CPU_DEAD: + refresh_zone_stat_thresholds(); + break; + default: + break; } return NOTIFY_OK; } diff --git a/trunk/net/bridge/br_fdb.c b/trunk/net/bridge/br_fdb.c index 8ca448db7a0d..d9f04864d15d 100644 --- a/trunk/net/bridge/br_fdb.c +++ b/trunk/net/bridge/br_fdb.c @@ -23,7 +23,7 @@ #include #include "br_private.h" -static struct kmem_cache *br_fdb_cache __read_mostly; +static kmem_cache_t *br_fdb_cache __read_mostly; static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index e660cb57e42a..59d058a3b504 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -3340,6 +3340,7 @@ void unregister_netdev(struct net_device *dev) EXPORT_SYMBOL(unregister_netdev); +#ifdef CONFIG_HOTPLUG_CPU static int dev_cpu_callback(struct notifier_block *nfb, unsigned long action, void *ocpu) @@ -3383,6 +3384,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } +#endif /* CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_NET_DMA /** diff --git a/trunk/net/core/dst.c b/trunk/net/core/dst.c index 836ec6606925..1a5e49da0e77 100644 --- a/trunk/net/core/dst.c +++ b/trunk/net/core/dst.c @@ -125,7 +125,7 @@ void * dst_alloc(struct dst_ops * ops) if (ops->gc()) return NULL; } - dst = kmem_cache_alloc(ops->kmem_cachep, GFP_ATOMIC); + dst = kmem_cache_alloc(ops->kmem_cachep, SLAB_ATOMIC); if (!dst) return NULL; memset(dst, 0, ops->entry_size); diff --git a/trunk/net/core/flow.c b/trunk/net/core/flow.c index d137f971f97d..b16d31ae5e54 100644 --- a/trunk/net/core/flow.c +++ b/trunk/net/core/flow.c @@ -44,7 +44,7 @@ static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL }; #define flow_table(cpu) (per_cpu(flow_tables, cpu)) -static struct kmem_cache *flow_cachep __read_mostly; +static kmem_cache_t *flow_cachep __read_mostly; static int flow_lwm, flow_hwm; @@ -211,7 +211,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, if (flow_count(cpu) > flow_hwm) flow_cache_shrink(cpu); - fle = kmem_cache_alloc(flow_cachep, GFP_ATOMIC); + fle = kmem_cache_alloc(flow_cachep, SLAB_ATOMIC); if (fle) { fle->next = *head; *head = fle; @@ -340,6 +340,7 @@ static void __devinit flow_cache_cpu_prepare(int cpu) tasklet_init(tasklet, flow_cache_flush_tasklet, 0); } +#ifdef CONFIG_HOTPLUG_CPU static int flow_cache_cpu(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -348,6 +349,7 @@ static int flow_cache_cpu(struct notifier_block *nfb, __flow_cache_shrink((unsigned long)hcpu, 0); return NOTIFY_OK; } +#endif /* CONFIG_HOTPLUG_CPU */ static int __init flow_cache_init(void) { diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 0ab1987b9348..ba509a4a8e92 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -251,7 +251,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) goto out_entries; } - n = kmem_cache_alloc(tbl->kmem_cachep, GFP_ATOMIC); + n = kmem_cache_alloc(tbl->kmem_cachep, SLAB_ATOMIC); if (!n) goto out_entries; diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index de7801d589e7..8e1c385e5ba9 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -68,8 +68,8 @@ #include "kmap_skb.h" -static struct kmem_cache *skbuff_head_cache __read_mostly; -static struct kmem_cache *skbuff_fclone_cache __read_mostly; +static kmem_cache_t *skbuff_head_cache __read_mostly; +static kmem_cache_t *skbuff_fclone_cache __read_mostly; /* * Keep out-of-line to prevent kernel bloat. @@ -132,7 +132,6 @@ EXPORT_SYMBOL(skb_truesize_bug); * @gfp_mask: allocation mask * @fclone: allocate from fclone cache instead of head cache * and allocate a cloned (child) skb - * @node: numa node to allocate memory on * * Allocate a new &sk_buff. The returned buffer has no headroom and a * tail room of size bytes. The object has a reference count of one. @@ -142,9 +141,9 @@ EXPORT_SYMBOL(skb_truesize_bug); * %GFP_ATOMIC. */ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, - int fclone, int node) + int fclone) { - struct kmem_cache *cache; + kmem_cache_t *cache; struct skb_shared_info *shinfo; struct sk_buff *skb; u8 *data; @@ -152,14 +151,14 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, cache = fclone ? skbuff_fclone_cache : skbuff_head_cache; /* Get the HEAD */ - skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); + skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA); if (!skb) goto out; /* Get the DATA. Size must match skb_add_mtu(). */ size = SKB_DATA_ALIGN(size); - data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), - gfp_mask, node); + data = kmalloc_track_caller(size + sizeof(struct skb_shared_info), + gfp_mask); if (!data) goto nodata; @@ -211,7 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, * Buffers may only be allocated from interrupts using a @gfp_mask of * %GFP_ATOMIC. */ -struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp, +struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, unsigned int size, gfp_t gfp_mask) { @@ -268,10 +267,9 @@ struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp, struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int length, gfp_t gfp_mask) { - int node = dev->class_dev.dev ? dev_to_node(dev->class_dev.dev) : -1; struct sk_buff *skb; - skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node); + skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); if (likely(skb)) { skb_reserve(skb, NET_SKB_PAD); skb->dev = dev; diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 0ed5b4f0bc40..419c7d3289c7 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -810,11 +810,24 @@ int sock_getsockopt(struct socket *sock, int level, int optname, */ static void inline sock_lock_init(struct sock *sk) { - sock_lock_init_class_and_name(sk, - af_family_slock_key_strings[sk->sk_family], - af_family_slock_keys + sk->sk_family, - af_family_key_strings[sk->sk_family], - af_family_keys + sk->sk_family); + spin_lock_init(&sk->sk_lock.slock); + sk->sk_lock.owner = NULL; + init_waitqueue_head(&sk->sk_lock.wq); + /* + * Make sure we are not reinitializing a held lock: + */ + debug_check_no_locks_freed((void *)&sk->sk_lock, sizeof(sk->sk_lock)); + + /* + * Mark both the sk_lock and the sk_lock.slock as a + * per-address-family lock class: + */ + lockdep_set_class_and_name(&sk->sk_lock.slock, + af_family_slock_keys + sk->sk_family, + af_family_slock_key_strings[sk->sk_family]); + lockdep_init_map(&sk->sk_lock.dep_map, + af_family_key_strings[sk->sk_family], + af_family_keys + sk->sk_family, 0); } /** @@ -828,7 +841,7 @@ struct sock *sk_alloc(int family, gfp_t priority, struct proto *prot, int zero_it) { struct sock *sk = NULL; - struct kmem_cache *slab = prot->slab; + kmem_cache_t *slab = prot->slab; if (slab != NULL) sk = kmem_cache_alloc(slab, priority); diff --git a/trunk/net/dccp/ackvec.c b/trunk/net/dccp/ackvec.c index 1f4727ddbdbf..bdf1bb7a82c0 100644 --- a/trunk/net/dccp/ackvec.c +++ b/trunk/net/dccp/ackvec.c @@ -21,8 +21,8 @@ #include -static struct kmem_cache *dccp_ackvec_slab; -static struct kmem_cache *dccp_ackvec_record_slab; +static kmem_cache_t *dccp_ackvec_slab; +static kmem_cache_t *dccp_ackvec_record_slab; static struct dccp_ackvec_record *dccp_ackvec_record_new(void) { diff --git a/trunk/net/dccp/ccid.c b/trunk/net/dccp/ccid.c index d8cf92f09e68..ff05e59043cd 100644 --- a/trunk/net/dccp/ccid.c +++ b/trunk/net/dccp/ccid.c @@ -55,9 +55,9 @@ static inline void ccids_read_unlock(void) #define ccids_read_unlock() do { } while(0) #endif -static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...) +static kmem_cache_t *ccid_kmem_cache_create(int obj_size, const char *fmt,...) { - struct kmem_cache *slab; + kmem_cache_t *slab; char slab_name_fmt[32], *slab_name; va_list args; @@ -75,7 +75,7 @@ static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,. return slab; } -static void ccid_kmem_cache_destroy(struct kmem_cache *slab) +static void ccid_kmem_cache_destroy(kmem_cache_t *slab) { if (slab != NULL) { const char *name = kmem_cache_name(slab); diff --git a/trunk/net/dccp/ccid.h b/trunk/net/dccp/ccid.h index bcc2d12ae81c..c7c29514dce8 100644 --- a/trunk/net/dccp/ccid.h +++ b/trunk/net/dccp/ccid.h @@ -27,9 +27,9 @@ struct ccid_operations { unsigned char ccid_id; const char *ccid_name; struct module *ccid_owner; - struct kmem_cache *ccid_hc_rx_slab; + kmem_cache_t *ccid_hc_rx_slab; __u32 ccid_hc_rx_obj_size; - struct kmem_cache *ccid_hc_tx_slab; + kmem_cache_t *ccid_hc_tx_slab; __u32 ccid_hc_tx_obj_size; int (*ccid_hc_rx_init)(struct ccid *ccid, struct sock *sk); int (*ccid_hc_tx_init)(struct ccid *ccid, struct sock *sk); diff --git a/trunk/net/dccp/ccids/ccid3.c b/trunk/net/dccp/ccids/ccid3.c index 66a27b9688ca..cf8c07b2704f 100644 --- a/trunk/net/dccp/ccids/ccid3.c +++ b/trunk/net/dccp/ccids/ccid3.c @@ -295,7 +295,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); if (new_packet == NULL || new_packet->dccphtx_sent) { new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist, - GFP_ATOMIC); + SLAB_ATOMIC); if (unlikely(new_packet == NULL)) { DCCP_WARN("%s, sk=%p, not enough mem to add to history," @@ -889,7 +889,7 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss) /* new loss event detected */ /* calculate last interval length */ seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss); - entry = dccp_li_hist_entry_new(ccid3_li_hist, GFP_ATOMIC); + entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC); if (entry == NULL) { DCCP_BUG("out of memory - can not allocate entry"); @@ -1011,7 +1011,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) } packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp, - skb, GFP_ATOMIC); + skb, SLAB_ATOMIC); if (unlikely(packet == NULL)) { DCCP_WARN("%s, sk=%p, Not enough mem to add rx packet " "to history, consider it lost!\n", dccp_role(sk), sk); diff --git a/trunk/net/dccp/ccids/lib/loss_interval.c b/trunk/net/dccp/ccids/lib/loss_interval.c index 0a0baef16b3e..48b9b93f8acb 100644 --- a/trunk/net/dccp/ccids/lib/loss_interval.c +++ b/trunk/net/dccp/ccids/lib/loss_interval.c @@ -125,7 +125,7 @@ int dccp_li_hist_interval_new(struct dccp_li_hist *hist, int i; for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) { - entry = dccp_li_hist_entry_new(hist, GFP_ATOMIC); + entry = dccp_li_hist_entry_new(hist, SLAB_ATOMIC); if (entry == NULL) { dccp_li_hist_purge(hist, list); DCCP_BUG("loss interval list entry is NULL"); diff --git a/trunk/net/dccp/ccids/lib/loss_interval.h b/trunk/net/dccp/ccids/lib/loss_interval.h index eb257014dd74..0ae85f0340b2 100644 --- a/trunk/net/dccp/ccids/lib/loss_interval.h +++ b/trunk/net/dccp/ccids/lib/loss_interval.h @@ -20,7 +20,7 @@ #define DCCP_LI_HIST_IVAL_F_LENGTH 8 struct dccp_li_hist { - struct kmem_cache *dccplih_slab; + kmem_cache_t *dccplih_slab; }; extern struct dccp_li_hist *dccp_li_hist_new(const char *name); diff --git a/trunk/net/dccp/ccids/lib/packet_history.h b/trunk/net/dccp/ccids/lib/packet_history.h index 9a8bcf224aa7..067cf1c85a37 100644 --- a/trunk/net/dccp/ccids/lib/packet_history.h +++ b/trunk/net/dccp/ccids/lib/packet_history.h @@ -68,14 +68,14 @@ struct dccp_rx_hist_entry { }; struct dccp_tx_hist { - struct kmem_cache *dccptxh_slab; + kmem_cache_t *dccptxh_slab; }; extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name); extern void dccp_tx_hist_delete(struct dccp_tx_hist *hist); struct dccp_rx_hist { - struct kmem_cache *dccprxh_slab; + kmem_cache_t *dccprxh_slab; }; extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name); diff --git a/trunk/net/decnet/dn_table.c b/trunk/net/decnet/dn_table.c index 13b2421991ba..bdbc3f431668 100644 --- a/trunk/net/decnet/dn_table.c +++ b/trunk/net/decnet/dn_table.c @@ -79,7 +79,7 @@ for( ; ((f) = *(fp)) != NULL && dn_key_eq((f)->fn_key, (key)); (fp) = &(f)->fn_n static struct hlist_head dn_fib_table_hash[DN_FIB_TABLE_HASHSZ]; static DEFINE_RWLOCK(dn_fib_tables_lock); -static struct kmem_cache *dn_hash_kmem __read_mostly; +static kmem_cache_t *dn_hash_kmem __read_mostly; static int dn_fib_hash_zombies; static inline dn_fib_idx_t dn_hash(dn_fib_key_t key, struct dn_zone *dz) @@ -590,7 +590,7 @@ static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct replace: err = -ENOBUFS; - new_f = kmem_cache_alloc(dn_hash_kmem, GFP_KERNEL); + new_f = kmem_cache_alloc(dn_hash_kmem, SLAB_KERNEL); if (new_f == NULL) goto out; diff --git a/trunk/net/ipv4/fib_hash.c b/trunk/net/ipv4/fib_hash.c index 648f47c1c399..107bb6cbb0b3 100644 --- a/trunk/net/ipv4/fib_hash.c +++ b/trunk/net/ipv4/fib_hash.c @@ -45,8 +45,8 @@ #include "fib_lookup.h" -static struct kmem_cache *fn_hash_kmem __read_mostly; -static struct kmem_cache *fn_alias_kmem __read_mostly; +static kmem_cache_t *fn_hash_kmem __read_mostly; +static kmem_cache_t *fn_alias_kmem __read_mostly; struct fib_node { struct hlist_node fn_hash; @@ -485,13 +485,13 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) goto out; err = -ENOBUFS; - new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); + new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); if (new_fa == NULL) goto out; new_f = NULL; if (!f) { - new_f = kmem_cache_alloc(fn_hash_kmem, GFP_KERNEL); + new_f = kmem_cache_alloc(fn_hash_kmem, SLAB_KERNEL); if (new_f == NULL) goto out_free_new_fa; diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index cfb249cc0a58..d17990ec724f 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -172,7 +172,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn); static struct tnode *halve(struct trie *t, struct tnode *tn); static void tnode_free(struct tnode *tn); -static struct kmem_cache *fn_alias_kmem __read_mostly; +static kmem_cache_t *fn_alias_kmem __read_mostly; static struct trie *trie_local = NULL, *trie_main = NULL; @@ -1187,7 +1187,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) u8 state; err = -ENOBUFS; - new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); + new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); if (new_fa == NULL) goto out; @@ -1232,7 +1232,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) goto out; err = -ENOBUFS; - new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); + new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); if (new_fa == NULL) goto out; diff --git a/trunk/net/ipv4/inet_hashtables.c b/trunk/net/ipv4/inet_hashtables.c index 8c79c8a4ea5c..244c4f445c7d 100644 --- a/trunk/net/ipv4/inet_hashtables.c +++ b/trunk/net/ipv4/inet_hashtables.c @@ -27,11 +27,11 @@ * Allocate and initialize a new local port bind bucket. * The bindhash mutex for snum's hash chain must be held here. */ -struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep, +struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep, struct inet_bind_hashbucket *head, const unsigned short snum) { - struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC); + struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, SLAB_ATOMIC); if (tb != NULL) { tb->port = snum; @@ -45,7 +45,7 @@ struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep, /* * Caller must hold hashbucket lock for this tb with local BH disabled */ -void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket *tb) +void inet_bind_bucket_destroy(kmem_cache_t *cachep, struct inet_bind_bucket *tb) { if (hlist_empty(&tb->owners)) { __hlist_del(&tb->node); diff --git a/trunk/net/ipv4/inet_timewait_sock.c b/trunk/net/ipv4/inet_timewait_sock.c index e28330aa4139..8c74f9168b7d 100644 --- a/trunk/net/ipv4/inet_timewait_sock.c +++ b/trunk/net/ipv4/inet_timewait_sock.c @@ -91,7 +91,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat { struct inet_timewait_sock *tw = kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab, - GFP_ATOMIC); + SLAB_ATOMIC); if (tw != NULL) { const struct inet_sock *inet = inet_sk(sk); diff --git a/trunk/net/ipv4/inetpeer.c b/trunk/net/ipv4/inetpeer.c index 711eb6d0285a..f072f3875af8 100644 --- a/trunk/net/ipv4/inetpeer.c +++ b/trunk/net/ipv4/inetpeer.c @@ -73,7 +73,7 @@ /* Exported for inet_getid inline function. */ DEFINE_SPINLOCK(inet_peer_idlock); -static struct kmem_cache *peer_cachep __read_mostly; +static kmem_cache_t *peer_cachep __read_mostly; #define node_height(x) x->avl_height static struct inet_peer peer_fake_node = { diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index ecb5422ea237..efcf45ecc818 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -105,7 +105,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock); In this case data path is free of exclusive locks at all. */ -static struct kmem_cache *mrt_cachep __read_mostly; +static kmem_cache_t *mrt_cachep __read_mostly; static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local); static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); diff --git a/trunk/net/ipv4/ipvs/ip_vs_conn.c b/trunk/net/ipv4/ipvs/ip_vs_conn.c index 8086787a2c51..8832eb517d52 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_conn.c +++ b/trunk/net/ipv4/ipvs/ip_vs_conn.c @@ -44,7 +44,7 @@ static struct list_head *ip_vs_conn_tab; /* SLAB cache for IPVS connections */ -static struct kmem_cache *ip_vs_conn_cachep __read_mostly; +static kmem_cache_t *ip_vs_conn_cachep __read_mostly; /* counter for current IPVS connections */ static atomic_t ip_vs_conn_count = ATOMIC_INIT(0); diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_core.c b/trunk/net/ipv4/netfilter/ip_conntrack_core.c index 8556a4f4f60a..f4b0e68a16d2 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_core.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_core.c @@ -65,8 +65,8 @@ static LIST_HEAD(helpers); unsigned int ip_conntrack_htable_size __read_mostly = 0; int ip_conntrack_max __read_mostly; struct list_head *ip_conntrack_hash __read_mostly; -static struct kmem_cache *ip_conntrack_cachep __read_mostly; -static struct kmem_cache *ip_conntrack_expect_cachep __read_mostly; +static kmem_cache_t *ip_conntrack_cachep __read_mostly; +static kmem_cache_t *ip_conntrack_expect_cachep __read_mostly; struct ip_conntrack ip_conntrack_untracked; unsigned int ip_ct_log_invalid __read_mostly; static LIST_HEAD(unconfirmed); diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index e5cd83b2205d..87c8f54872b7 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -720,8 +720,10 @@ snmp6_mib_free(void *ptr[2]) { if (ptr == NULL) return; - free_percpu(ptr[0]); - free_percpu(ptr[1]); + if (ptr[0]) + free_percpu(ptr[0]); + if (ptr[1]) + free_percpu(ptr[1]); ptr[0] = ptr[1] = NULL; } diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index 96d8310ae9c8..bf526115e518 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -50,7 +50,7 @@ struct rt6_statistics rt6_stats; -static struct kmem_cache * fib6_node_kmem __read_mostly; +static kmem_cache_t * fib6_node_kmem __read_mostly; enum fib_walk_state_t { @@ -150,7 +150,7 @@ static __inline__ struct fib6_node * node_alloc(void) { struct fib6_node *fn; - if ((fn = kmem_cache_alloc(fib6_node_kmem, GFP_ATOMIC)) != NULL) + if ((fn = kmem_cache_alloc(fib6_node_kmem, SLAB_ATOMIC)) != NULL) memset(fn, 0, sizeof(struct fib6_node)); return fn; diff --git a/trunk/net/ipv6/xfrm6_tunnel.c b/trunk/net/ipv6/xfrm6_tunnel.c index 12e426b9aacd..01a5c52a2be3 100644 --- a/trunk/net/ipv6/xfrm6_tunnel.c +++ b/trunk/net/ipv6/xfrm6_tunnel.c @@ -50,7 +50,7 @@ static u32 xfrm6_tunnel_spi; #define XFRM6_TUNNEL_SPI_MIN 1 #define XFRM6_TUNNEL_SPI_MAX 0xffffffff -static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly; +static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly; #define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256 #define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256 @@ -180,7 +180,7 @@ try_next_2:; spi = 0; goto out; alloc_spi: - x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC); + x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC); if (!x6spi) goto out; diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index a9638ff52a72..eaa0f8a1adb6 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -108,7 +108,7 @@ static struct { size_t size; /* slab cache pointer */ - struct kmem_cache *cachep; + kmem_cache_t *cachep; /* allocated slab cache + modules which uses this slab cache */ int use; @@ -147,7 +147,7 @@ int nf_conntrack_register_cache(u_int32_t features, const char *name, { int ret = 0; char *cache_name; - struct kmem_cache *cachep; + kmem_cache_t *cachep; DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n", features, name, size); @@ -226,7 +226,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_register_cache); /* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */ void nf_conntrack_unregister_cache(u_int32_t features) { - struct kmem_cache *cachep; + kmem_cache_t *cachep; char *name; /* diff --git a/trunk/net/netfilter/nf_conntrack_expect.c b/trunk/net/netfilter/nf_conntrack_expect.c index c20f901fa177..588d37937046 100644 --- a/trunk/net/netfilter/nf_conntrack_expect.c +++ b/trunk/net/netfilter/nf_conntrack_expect.c @@ -29,7 +29,7 @@ LIST_HEAD(nf_conntrack_expect_list); EXPORT_SYMBOL_GPL(nf_conntrack_expect_list); -struct kmem_cache *nf_conntrack_expect_cachep __read_mostly; +kmem_cache_t *nf_conntrack_expect_cachep __read_mostly; static unsigned int nf_conntrack_expect_next_id; /* nf_conntrack_expect helper functions */ diff --git a/trunk/net/netfilter/xt_hashlimit.c b/trunk/net/netfilter/xt_hashlimit.c index a5a6e192ac2d..a98de0b54d65 100644 --- a/trunk/net/netfilter/xt_hashlimit.c +++ b/trunk/net/netfilter/xt_hashlimit.c @@ -92,7 +92,7 @@ struct xt_hashlimit_htable { static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */ static DEFINE_MUTEX(hlimit_mutex); /* additional checkentry protection */ static HLIST_HEAD(hashlimit_htables); -static struct kmem_cache *hashlimit_cachep __read_mostly; +static kmem_cache_t *hashlimit_cachep __read_mostly; static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b) { diff --git a/trunk/net/netlink/genetlink.c b/trunk/net/netlink/genetlink.c index b9b03747c1f3..b5df749cba8f 100644 --- a/trunk/net/netlink/genetlink.c +++ b/trunk/net/netlink/genetlink.c @@ -143,6 +143,13 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops) goto errout; } + if (ops->dumpit) + ops->flags |= GENL_CMD_CAP_DO; + if (ops->doit) + ops->flags |= GENL_CMD_CAP_DUMP; + if (ops->policy) + ops->flags |= GENL_CMD_CAP_HASPOL; + genl_lock(); list_add_tail(&ops->ops_list, &family->ops_list); genl_unlock(); @@ -387,7 +394,7 @@ static void genl_rcv(struct sock *sk, int len) static struct genl_family genl_ctrl = { .id = GENL_ID_CTRL, .name = "nlctrl", - .version = 0x1, + .version = 0x2, .maxattr = CTRL_ATTR_MAX, }; @@ -425,15 +432,6 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); - if (ops->policy) - NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY); - - if (ops->doit) - NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT); - - if (ops->dumpit) - NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT); - nla_nest_end(skb, nest); } diff --git a/trunk/net/rxrpc/krxiod.c b/trunk/net/rxrpc/krxiod.c index 49effd92144e..dada34a77b21 100644 --- a/trunk/net/rxrpc/krxiod.c +++ b/trunk/net/rxrpc/krxiod.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/net/rxrpc/krxsecd.c b/trunk/net/rxrpc/krxsecd.c index 3ab0f77409f4..cea4eb5e2497 100644 --- a/trunk/net/rxrpc/krxsecd.c +++ b/trunk/net/rxrpc/krxsecd.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "internal.h" diff --git a/trunk/net/rxrpc/krxtimod.c b/trunk/net/rxrpc/krxtimod.c index 9a9b6132dba4..3e7466900bd4 100644 --- a/trunk/net/rxrpc/krxtimod.c +++ b/trunk/net/rxrpc/krxtimod.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index f2ba8615895b..11f3b549f4a4 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -79,8 +79,8 @@ static struct sctp_pf *sctp_pf_inet_specific; static struct sctp_af *sctp_af_v4_specific; static struct sctp_af *sctp_af_v6_specific; -struct kmem_cache *sctp_chunk_cachep __read_mostly; -struct kmem_cache *sctp_bucket_cachep __read_mostly; +kmem_cache_t *sctp_chunk_cachep __read_mostly; +kmem_cache_t *sctp_bucket_cachep __read_mostly; /* Return the address of the control sock. */ struct sock *sctp_get_ctl_sock(void) diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index 30927d3a597f..04954e5f6846 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -65,7 +65,7 @@ #include #include -extern struct kmem_cache *sctp_chunk_cachep; +extern kmem_cache_t *sctp_chunk_cachep; SCTP_STATIC struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc, @@ -979,7 +979,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb, { struct sctp_chunk *retval; - retval = kmem_cache_alloc(sctp_chunk_cachep, GFP_ATOMIC); + retval = kmem_cache_alloc(sctp_chunk_cachep, SLAB_ATOMIC); if (!retval) goto nodata; diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 1e8132b8c4d9..02b27145b279 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -107,7 +107,7 @@ static void sctp_sock_migrate(struct sock *, struct sock *, struct sctp_association *, sctp_socket_type_t); static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; -extern struct kmem_cache *sctp_bucket_cachep; +extern kmem_cache_t *sctp_bucket_cachep; /* Get the sndbuf space available at the time on the association. */ static inline int sctp_wspace(struct sctp_association *asoc) @@ -4989,7 +4989,7 @@ static struct sctp_bind_bucket *sctp_bucket_create( { struct sctp_bind_bucket *pp; - pp = kmem_cache_alloc(sctp_bucket_cachep, GFP_ATOMIC); + pp = kmem_cache_alloc(sctp_bucket_cachep, SLAB_ATOMIC); SCTP_DBG_OBJCNT_INC(bind_bucket); if (pp) { pp->port = snum; diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 29ea1de43ecb..e8db54702a69 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -230,13 +230,13 @@ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, #define SOCKFS_MAGIC 0x534F434B -static struct kmem_cache *sock_inode_cachep __read_mostly; +static kmem_cache_t *sock_inode_cachep __read_mostly; static struct inode *sock_alloc_inode(struct super_block *sb) { struct socket_alloc *ei; - ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL); + ei = kmem_cache_alloc(sock_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; init_waitqueue_head(&ei->socket.wait); @@ -257,7 +257,7 @@ static void sock_destroy_inode(struct inode *inode) container_of(inode, struct socket_alloc, vfs_inode)); } -static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct socket_alloc *ei = (struct socket_alloc *)foo; @@ -305,14 +305,7 @@ static struct file_system_type sock_fs_type = { static int sockfs_delete_dentry(struct dentry *dentry) { - /* - * At creation time, we pretended this dentry was hashed - * (by clearing DCACHE_UNHASHED bit in d_flags) - * At delete time, we restore the truth : not hashed. - * (so that dput() can proceed correctly) - */ - dentry->d_flags |= DCACHE_UNHASHED; - return 0; + return 1; } static struct dentry_operations sockfs_dentry_operations = { .d_delete = sockfs_delete_dentry, @@ -360,20 +353,14 @@ static int sock_attach_fd(struct socket *sock, struct file *file) this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); this.name = name; - this.hash = 0; + this.hash = SOCK_INODE(sock)->i_ino; file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); if (unlikely(!file->f_dentry)) return -ENOMEM; file->f_dentry->d_op = &sockfs_dentry_operations; - /* - * We dont want to push this dentry into global dentry hash table. - * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED - * This permits a working /proc/$pid/fd/XXX on sockets - */ - file->f_dentry->d_flags &= ~DCACHE_UNHASHED; - d_instantiate(file->f_dentry, SOCK_INODE(sock)); + d_add(file->f_dentry, SOCK_INODE(sock)); file->f_vfsmnt = mntget(sock_mnt); file->f_mapping = file->f_dentry->d_inode->i_mapping; diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 19703aa9659e..49dba5febbbd 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -33,7 +33,7 @@ static int rpc_mount_count; static struct file_system_type rpc_pipe_fs_type; -static struct kmem_cache *rpc_inode_cachep __read_mostly; +static kmem_cache_t *rpc_inode_cachep __read_mostly; #define RPC_UPCALL_TIMEOUT (30*HZ) @@ -143,7 +143,7 @@ static struct inode * rpc_alloc_inode(struct super_block *sb) { struct rpc_inode *rpci; - rpci = (struct rpc_inode *)kmem_cache_alloc(rpc_inode_cachep, GFP_KERNEL); + rpci = (struct rpc_inode *)kmem_cache_alloc(rpc_inode_cachep, SLAB_KERNEL); if (!rpci) return NULL; return &rpci->vfs_inode; @@ -824,7 +824,7 @@ static struct file_system_type rpc_pipe_fs_type = { }; static void -init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { struct rpc_inode *rpci = (struct rpc_inode *) foo; diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index 225e6510b523..eff44bcdc95a 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -34,8 +34,8 @@ static int rpc_task_id; #define RPC_BUFFER_MAXSIZE (2048) #define RPC_BUFFER_POOLSIZE (8) #define RPC_TASK_POOLSIZE (8) -static struct kmem_cache *rpc_task_slabp __read_mostly; -static struct kmem_cache *rpc_buffer_slabp __read_mostly; +static kmem_cache_t *rpc_task_slabp __read_mostly; +static kmem_cache_t *rpc_buffer_slabp __read_mostly; static mempool_t *rpc_task_mempool __read_mostly; static mempool_t *rpc_buffer_mempool __read_mostly; diff --git a/trunk/net/sunrpc/svcauth.c b/trunk/net/sunrpc/svcauth.c index c7bb5f7f21a5..ee9bb1522d5e 100644 --- a/trunk/net/sunrpc/svcauth.c +++ b/trunk/net/sunrpc/svcauth.c @@ -119,8 +119,7 @@ EXPORT_SYMBOL(svc_auth_unregister); #define DN_HASHMASK (DN_HASHMAX-1) static struct hlist_head auth_domain_table[DN_HASHMAX]; -static spinlock_t auth_domain_lock = - __SPIN_LOCK_UNLOCKED(auth_domain_lock); +static spinlock_t auth_domain_lock = SPIN_LOCK_UNLOCKED; void auth_domain_put(struct auth_domain *dom) { diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index 99f54fb6d669..64ca1f61dd94 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -85,35 +84,6 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req); */ static int svc_conn_age_period = 6*60; -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static struct lock_class_key svc_key[2]; -static struct lock_class_key svc_slock_key[2]; - -static inline void svc_reclassify_socket(struct socket *sock) -{ - struct sock *sk = sock->sk; - BUG_ON(sk->sk_lock.owner != NULL); - switch (sk->sk_family) { - case AF_INET: - sock_lock_init_class_and_name(sk, "slock-AF_INET-NFSD", - &svc_slock_key[0], "sk_lock-AF_INET-NFSD", &svc_key[0]); - break; - - case AF_INET6: - sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFSD", - &svc_slock_key[1], "sk_lock-AF_INET6-NFSD", &svc_key[1]); - break; - - default: - BUG(); - } -} -#else -static inline void svc_reclassify_socket(struct socket *sock) -{ -} -#endif - /* * Queue up an idle server thread. Must have pool->sp_lock held. * Note: this is really a stack rather than a queue, so that we only @@ -1586,8 +1556,6 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin) if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0) return error; - svc_reclassify_socket(sock); - if (type == SOCK_STREAM) sock->sk->sk_reuse = 1; /* allow address reuse */ error = kernel_bind(sock, (struct sockaddr *) sin, diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index 2fc4a3123261..cfe3c15be948 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -1058,35 +1058,6 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) return err; } -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static struct lock_class_key xs_key[2]; -static struct lock_class_key xs_slock_key[2]; - -static inline void xs_reclassify_socket(struct socket *sock) -{ - struct sock *sk = sock->sk; - BUG_ON(sk->sk_lock.owner != NULL); - switch (sk->sk_family) { - case AF_INET: - sock_lock_init_class_and_name(sk, "slock-AF_INET-NFS", - &xs_slock_key[0], "sk_lock-AF_INET-NFS", &xs_key[0]); - break; - - case AF_INET6: - sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFS", - &xs_slock_key[1], "sk_lock-AF_INET6-NFS", &xs_key[1]); - break; - - default: - BUG(); - } -} -#else -static inline void xs_reclassify_socket(struct socket *sock) -{ -} -#endif - /** * xs_udp_connect_worker - set up a UDP socket * @work: RPC transport to connect @@ -1110,7 +1081,6 @@ static void xs_udp_connect_worker(struct work_struct *work) dprintk("RPC: can't create UDP transport socket (%d).\n", -err); goto out; } - xs_reclassify_socket(sock); if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { sock_release(sock); @@ -1195,7 +1165,6 @@ static void xs_tcp_connect_worker(struct work_struct *work) dprintk("RPC: can't create TCP transport socket (%d).\n", -err); goto out; } - xs_reclassify_socket(sock); if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { sock_release(sock); diff --git a/trunk/net/tipc/handler.c b/trunk/net/tipc/handler.c index eb80778d6d9c..ae6ddf00a1aa 100644 --- a/trunk/net/tipc/handler.c +++ b/trunk/net/tipc/handler.c @@ -42,7 +42,7 @@ struct queue_item { unsigned long data; }; -static struct kmem_cache *tipc_queue_item_cache; +static kmem_cache_t *tipc_queue_item_cache; static struct list_head signal_queue_head; static DEFINE_SPINLOCK(qitem_lock); static int handler_enabled = 0; diff --git a/trunk/net/xfrm/xfrm_input.c b/trunk/net/xfrm/xfrm_input.c index 414f89070380..e8198a2c785d 100644 --- a/trunk/net/xfrm/xfrm_input.c +++ b/trunk/net/xfrm/xfrm_input.c @@ -12,7 +12,7 @@ #include #include -static struct kmem_cache *secpath_cachep __read_mostly; +static kmem_cache_t *secpath_cachep __read_mostly; void __secpath_destroy(struct sec_path *sp) { @@ -27,7 +27,7 @@ struct sec_path *secpath_dup(struct sec_path *src) { struct sec_path *sp; - sp = kmem_cache_alloc(secpath_cachep, GFP_ATOMIC); + sp = kmem_cache_alloc(secpath_cachep, SLAB_ATOMIC); if (!sp) return NULL; diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index 3f3f563eb4ab..f6c77bd36fdd 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -39,7 +39,7 @@ EXPORT_SYMBOL(xfrm_policy_count); static DEFINE_RWLOCK(xfrm_policy_afinfo_lock); static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO]; -static struct kmem_cache *xfrm_dst_cache __read_mostly; +static kmem_cache_t *xfrm_dst_cache __read_mostly; static struct work_struct xfrm_policy_gc_work; static HLIST_HEAD(xfrm_policy_gc_list); diff --git a/trunk/scripts/kallsyms.c b/trunk/scripts/kallsyms.c index f359b730c2c5..22d281c6ec24 100644 --- a/trunk/scripts/kallsyms.c +++ b/trunk/scripts/kallsyms.c @@ -43,7 +43,7 @@ struct sym_entry { static struct sym_entry *table; static unsigned int table_size, table_cnt; -static unsigned long long _text, _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext; +static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext; static int all_symbols = 0; static char symbol_prefix_char = '\0'; @@ -91,9 +91,7 @@ static int read_symbol(FILE *in, struct sym_entry *s) sym++; /* Ignore most absolute/undefined (?) symbols. */ - if (strcmp(sym, "_text") == 0) - _text = s->addr; - else if (strcmp(sym, "_stext") == 0) + if (strcmp(sym, "_stext") == 0) _stext = s->addr; else if (strcmp(sym, "_etext") == 0) _etext = s->addr; @@ -267,25 +265,9 @@ static void write_src(void) printf(".data\n"); - /* Provide proper symbols relocatability by their '_text' - * relativeness. The symbol names cannot be used to construct - * normal symbol references as the list of symbols contains - * symbols that are declared static and are private to their - * .o files. This prevents .tmp_kallsyms.o or any other - * object from referencing them. - */ output_label("kallsyms_addresses"); for (i = 0; i < table_cnt; i++) { - if (toupper(table[i].sym[0]) != 'A') { - if (_text <= table[i].addr) - printf("\tPTR\t_text + %#llx\n", - table[i].addr - _text); - else - printf("\tPTR\t_text - %#llx\n", - _text - table[i].addr); - } else { - printf("\tPTR\t%#llx\n", table[i].addr); - } + printf("\tPTR\t%#llx\n", table[i].addr); } printf("\n"); diff --git a/trunk/scripts/kconfig/qconf.cc b/trunk/scripts/kconfig/qconf.cc index f5628c57640b..338bdea96541 100644 --- a/trunk/scripts/kconfig/qconf.cc +++ b/trunk/scripts/kconfig/qconf.cc @@ -798,7 +798,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) QAction *action; headerPopup = new QPopupMenu(this); - action = new QAction(NULL, "Show Name", 0, this); + action = new QAction("Show Name", 0, this); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowName(bool))); @@ -806,7 +806,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action, SLOT(setOn(bool))); action->setOn(showName); action->addTo(headerPopup); - action = new QAction(NULL, "Show Range", 0, this); + action = new QAction("Show Range", 0, this); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowRange(bool))); @@ -814,7 +814,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action, SLOT(setOn(bool))); action->setOn(showRange); action->addTo(headerPopup); - action = new QAction(NULL, "Show Data", 0, this); + action = new QAction("Show Data", 0, this); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowData(bool))); @@ -1161,7 +1161,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) { QPopupMenu* popup = Parent::createPopupMenu(pos); - QAction* action = new QAction(NULL,"Show Debug Info", 0, popup); + QAction* action = new QAction("Show Debug Info", 0, popup); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); diff --git a/trunk/scripts/kernel-doc b/trunk/scripts/kernel-doc index df3b272f7ce6..187f5de4612c 100755 --- a/trunk/scripts/kernel-doc +++ b/trunk/scripts/kernel-doc @@ -1430,7 +1430,7 @@ sub create_parameterlist($$$) { # corresponding data structures "correctly". Catch it later in # output_* subs. push_parameter($arg, "", $file); - } elsif ($arg =~ m/\(.*\*/) { + } elsif ($arg =~ m/\(/) { # pointer-to-function $arg =~ tr/#/,/; $arg =~ m/[^\(]+\(\*([^\)]+)\)/; diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index ac0a58222992..2e1141623147 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -911,7 +911,6 @@ static int init_section_ref_ok(const char *name) ".toc1", /* used by ppc64 */ ".stab", ".rodata", - ".parainstructions", ".text.lock", "__bug_table", /* used by powerpc for BUG() */ ".pci_fixup_header", @@ -932,7 +931,6 @@ static int init_section_ref_ok(const char *name) ".altinstructions", ".eh_frame", ".debug", - ".parainstructions", NULL }; /* part of section name */ diff --git a/trunk/scripts/ver_linux b/trunk/scripts/ver_linux index 72876dfadc8a..84999f69773d 100755 --- a/trunk/scripts/ver_linux +++ b/trunk/scripts/ver_linux @@ -48,8 +48,6 @@ fsck.reiser4 -V 2>&1 | grep ^fsck.reiser4 | awk \ xfs_db -V 2>&1 | grep version | awk \ 'NR==1{print "xfsprogs ", $3}' -pccardctl -V 2>&1| grep pcmciautils | awk '{print "pcmciautils ", $2}' - cardmgr -V 2>&1| grep version | awk \ 'NR==1{print "pcmcia-cs ", $3}' @@ -89,16 +87,10 @@ loadkeys -h 2>&1 | awk \ loadkeys -V 2>&1 | awk \ '(NR==1 && ($2 ~ /console-tools/)) {print "Console-tools ", $3}' -oprofiled --version 2>&1 | awk \ -'(NR==1 && ($2 == "oprofile")) {print "oprofile ", $3}' - expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}' udevinfo -V 2>&1 | grep version | awk '{print "udev ", $3}' -iwconfig --version 2>&1 | awk \ -'(NR==1 && ($3 == "version")) {print "wireless-tools ",$4}' - if [ -e /proc/modules ]; then X=`cat /proc/modules | sed -e "s/ .*$//"` echo "Modules Loaded "$X diff --git a/trunk/security/keys/key.c b/trunk/security/keys/key.c index ac9326c5f1da..70eacbe5abde 100644 --- a/trunk/security/keys/key.c +++ b/trunk/security/keys/key.c @@ -20,7 +20,7 @@ #include #include "internal.h" -static struct kmem_cache *key_jar; +static kmem_cache_t *key_jar; struct rb_root key_serial_tree; /* tree of keys indexed by serial */ DEFINE_SPINLOCK(key_serial_lock); @@ -285,14 +285,16 @@ struct key *key_alloc(struct key_type *type, const char *desc, } /* allocate and initialise the key and its description */ - key = kmem_cache_alloc(key_jar, GFP_KERNEL); + key = kmem_cache_alloc(key_jar, SLAB_KERNEL); if (!key) goto no_memory_2; if (desc) { - key->description = kmemdup(desc, desclen, GFP_KERNEL); + key->description = kmalloc(desclen, GFP_KERNEL); if (!key->description) goto no_memory_3; + + memcpy(key->description, desc, desclen); } atomic_set(&key->usage, 1); diff --git a/trunk/security/keys/keyring.c b/trunk/security/keys/keyring.c index ad45ce73964b..e8d02acc51e7 100644 --- a/trunk/security/keys/keyring.c +++ b/trunk/security/keys/keyring.c @@ -706,10 +706,12 @@ int __key_link(struct key *keyring, struct key *key) BUG_ON(size > PAGE_SIZE); ret = -ENOMEM; - nklist = kmemdup(klist, size, GFP_KERNEL); + nklist = kmalloc(size, GFP_KERNEL); if (!nklist) goto error2; + memcpy(nklist, klist, size); + /* replace matched key */ atomic_inc(&key->usage); nklist->keys[loop] = key; diff --git a/trunk/security/keys/process_keys.c b/trunk/security/keys/process_keys.c index b6f86808475a..32150cf7c37f 100644 --- a/trunk/security/keys/process_keys.c +++ b/trunk/security/keys/process_keys.c @@ -27,7 +27,7 @@ static DEFINE_MUTEX(key_session_mutex); struct key_user root_key_user = { .usage = ATOMIC_INIT(3), .consq = LIST_HEAD_INIT(root_key_user.consq), - .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), + .lock = SPIN_LOCK_UNLOCKED, .nkeys = ATOMIC_INIT(2), .nikeys = ATOMIC_INIT(2), .uid = 0, diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index e7c0b5e2066b..e73ac1ab7cfd 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -124,7 +124,7 @@ DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 }; static struct avc_cache avc_cache; static struct avc_callback_node *avc_callbacks; -static struct kmem_cache *avc_node_cachep; +static kmem_cache_t *avc_node_cachep; static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) { @@ -332,7 +332,7 @@ static struct avc_node *avc_alloc_node(void) { struct avc_node *node; - node = kmem_cache_alloc(avc_node_cachep, GFP_ATOMIC); + node = kmem_cache_alloc(avc_node_cachep, SLAB_ATOMIC); if (!node) goto out; diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 44e9cd470543..78f98fe084eb 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -124,7 +124,7 @@ static struct security_operations *secondary_ops = NULL; static LIST_HEAD(superblock_security_head); static DEFINE_SPINLOCK(sb_security_lock); -static struct kmem_cache *sel_inode_cache; +static kmem_cache_t *sel_inode_cache; /* Return security context for a given sid or just the context length if the buffer is null or length is 0 */ @@ -181,7 +181,7 @@ static int inode_alloc_security(struct inode *inode) struct task_security_struct *tsec = current->security; struct inode_security_struct *isec; - isec = kmem_cache_alloc(sel_inode_cache, GFP_KERNEL); + isec = kmem_cache_alloc(sel_inode_cache, SLAB_KERNEL); if (!isec) return -ENOMEM; diff --git a/trunk/security/selinux/ss/avtab.c b/trunk/security/selinux/ss/avtab.c index ebb993c5c244..d049c7acbc8b 100644 --- a/trunk/security/selinux/ss/avtab.c +++ b/trunk/security/selinux/ss/avtab.c @@ -28,7 +28,7 @@ (keyp->source_type << 9)) & \ AVTAB_HASH_MASK) -static struct kmem_cache *avtab_node_cachep; +static kmem_cache_t *avtab_node_cachep; static struct avtab_node* avtab_insert_node(struct avtab *h, int hvalue, @@ -36,7 +36,7 @@ avtab_insert_node(struct avtab *h, int hvalue, struct avtab_key *key, struct avtab_datum *datum) { struct avtab_node * newnode; - newnode = kmem_cache_alloc(avtab_node_cachep, GFP_KERNEL); + newnode = kmem_cache_alloc(avtab_node_cachep, SLAB_KERNEL); if (newnode == NULL) return NULL; memset(newnode, 0, sizeof(struct avtab_node)); diff --git a/trunk/sound/arm/sa11xx-uda1341.c b/trunk/sound/arm/sa11xx-uda1341.c index c7e1b2646193..c79a9afd0955 100644 --- a/trunk/sound/arm/sa11xx-uda1341.c +++ b/trunk/sound/arm/sa11xx-uda1341.c @@ -125,7 +125,7 @@ struct audio_stream { #else dma_regs_t *dma_regs; /* points to our DMA registers */ #endif - unsigned int active:1; /* we are using this stream for transfer now */ + int active:1; /* we are using this stream for transfer now */ int period; /* current transfer period */ int periods; /* current count of periods registerd in the DMA engine */ int tx_spin; /* are we recoding - flag used to do DMA trans. for sync */ diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index 6ea67b16c676..66e24b5da469 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -3027,7 +3027,7 @@ static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, struct page * page; if (substream == NULL) - return NOPAGE_SIGBUS; + return NOPAGE_OOM; runtime = substream->runtime; page = virt_to_page(runtime->status); get_page(page); @@ -3070,7 +3070,7 @@ static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, struct page * page; if (substream == NULL) - return NOPAGE_SIGBUS; + return NOPAGE_OOM; runtime = substream->runtime; page = virt_to_page(runtime->control); get_page(page); @@ -3131,18 +3131,18 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, size_t dma_bytes; if (substream == NULL) - return NOPAGE_SIGBUS; + return NOPAGE_OOM; runtime = substream->runtime; offset = area->vm_pgoff << PAGE_SHIFT; offset += address - area->vm_start; - snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS); + snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM); dma_bytes = PAGE_ALIGN(runtime->dma_bytes); if (offset > dma_bytes - PAGE_SIZE) return NOPAGE_SIGBUS; if (substream->ops->page) { page = substream->ops->page(substream, offset); if (! page) - return NOPAGE_OOM; /* XXX: is this really due to OOM? */ + return NOPAGE_OOM; } else { vaddr = runtime->dma_area + offset; page = virt_to_page(vaddr); diff --git a/trunk/sound/oss/Kconfig b/trunk/sound/oss/Kconfig index a0588c21324a..cc2b9ab7f4e5 100644 --- a/trunk/sound/oss/Kconfig +++ b/trunk/sound/oss/Kconfig @@ -5,6 +5,20 @@ # # Prompt user for primary drivers. +config OSS_OBSOLETE_DRIVER + bool "Obsolete OSS drivers" + depends on SOUND_PRIME + help + This option enables support for obsolete OSS drivers that + are scheduled for removal in the near future since there + are ALSA drivers for the same hardware. + + Please contact Adrian Bunk if you had to + say Y here because your soundcard is not properly supported + by ALSA. + + If unsure, say N. + config SOUND_BT878 tristate "BT878 audio dma" depends on SOUND_PRIME && PCI @@ -21,6 +35,40 @@ config SOUND_BT878 To compile this driver as a module, choose M here: the module will be called btaudio. +config SOUND_EMU10K1 + tristate "Creative SBLive! (EMU10K1)" + depends on SOUND_PRIME && PCI && OSS_OBSOLETE_DRIVER + ---help--- + Say Y or M if you have a PCI sound card using the EMU10K1 chipset, + such as the Creative SBLive!, SB PCI512 or Emu-APS. + + For more information on this driver and the degree of support for + the different card models please check: + + + + It is now possible to load dsp microcode patches into the EMU10K1 + chip. These patches are used to implement real time sound + processing effects which include for example: signal routing, + bass/treble control, AC3 passthrough, ... + Userspace tools to create new patches and load/unload them can be + found in the emu-tools package at the above URL. + +config MIDI_EMU10K1 + bool "Creative SBLive! MIDI (EXPERIMENTAL)" + depends on SOUND_EMU10K1 && EXPERIMENTAL && ISA_DMA_API + help + Say Y if you want to be able to use the OSS /dev/sequencer + interface. This code is still experimental. + +config SOUND_FUSION + tristate "Crystal SoundFusion (CS4280/461x)" + depends on SOUND_PRIME && PCI && OSS_OBSOLETE_DRIVER + help + This module drives the Crystal SoundFusion devices (CS4280/46xx + series) when wired as native sound drivers with AC97 codecs. If + this driver does not work try the CS4232 driver. + config SOUND_BCM_CS4297A tristate "Crystal Sound CS4297a (for Swarm)" depends on SOUND_PRIME && SIBYTE_SWARM @@ -400,6 +448,47 @@ config SOUND_DMAP Say Y unless you have 16MB or more RAM or a PCI sound card. +config SOUND_AD1816 + tristate "AD1816(A) based cards (EXPERIMENTAL)" + depends on EXPERIMENTAL && SOUND_OSS && OSS_OBSOLETE_DRIVER + help + Say M here if you have a sound card based on the Analog Devices + AD1816(A) chip. + + If you compile the driver into the kernel, you have to add + "ad1816=,,," to the kernel command line. + +config SOUND_AD1889 + tristate "AD1889 based cards (AD1819 codec) (EXPERIMENTAL)" + depends on EXPERIMENTAL && SOUND_OSS && PCI && OSS_OBSOLETE_DRIVER + help + Say M here if you have a sound card based on the Analog Devices + AD1889 chip. + +config SOUND_ADLIB + tristate "Adlib Cards" + depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + help + Includes ASB 64 4D. Information on programming AdLib cards is + available at . + +config SOUND_ACI_MIXER + tristate "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20)" + depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + ---help--- + ACI (Audio Command Interface) is a protocol used to communicate with + the microcontroller on some sound cards produced by miro and + Cardinal Technologies. The main function of the ACI is to control + the mixer and to get a product identification. + + This VoxWare ACI driver currently supports the ACI functions on the + miroSOUND PCM1-pro, PCM12 and PCM20 radio. On the PCM20 radio, ACI + also controls the radio tuner. This is supported in the video4linux + miropcm20 driver (say M or Y here and go back to "Multimedia + devices" -> "Radio Adapters"). + + This driver is also available as a module and will be called aci. + config SOUND_CS4232 tristate "Crystal CS4232 based (PnP) cards" depends on SOUND_OSS @@ -505,6 +594,18 @@ config SOUND_MPU401 If you compile the driver into the kernel, you have to add "mpu401=," to the kernel command line. +config SOUND_NM256 + tristate "NM256AV/NM256ZX audio support" + depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + help + Say M here to include audio support for the NeoMagic 256AV/256ZX + chipsets. These are the audio chipsets found in the Sony + Z505S/SX/DX, some Sony F-series, and the Dell Latitude CPi and CPt + laptops. It includes support for an AC97-compatible mixer and an + apparently proprietary sound engine. + + See for further information. + config SOUND_PAS tristate "ProAudioSpectrum 16 support" depends on SOUND_OSS @@ -613,6 +714,20 @@ config SOUND_YM3812 If unsure, say Y. +config SOUND_OPL3SA2 + tristate "Yamaha OPL3-SA2 and SA3 based PnP cards" + depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + help + Say Y or M if you have a card based on one of these Yamaha sound + chipsets or the "SAx", which is actually a SA3. Read + for more information on + configuring these cards. + + If you compile the driver into the kernel and do not also + configure in the optional ISA PnP support, you will have to add + "opl3sa2=,,,,," to the kernel + command line. + config SOUND_UART6850 tristate "6850 UART support" depends on SOUND_OSS diff --git a/trunk/sound/oss/btaudio.c b/trunk/sound/oss/btaudio.c index ad7210a00dc0..6ad384114239 100644 --- a/trunk/sound/oss/btaudio.c +++ b/trunk/sound/oss/btaudio.c @@ -1020,7 +1020,6 @@ static int __devinit btaudio_probe(struct pci_dev *pci_dev, fail2: free_irq(bta->irq,bta); fail1: - iounmap(bta->mmio); kfree(bta); fail0: release_mem_region(pci_resource_start(pci_dev,0), @@ -1052,7 +1051,6 @@ static void __devexit btaudio_remove(struct pci_dev *pci_dev) free_irq(bta->irq,bta); release_mem_region(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0)); - iounmap(bta->mmio); /* remove from linked list */ if (bta == btaudios) { diff --git a/trunk/sound/oss/emu10k1/audio.c b/trunk/sound/oss/emu10k1/audio.c index 49f902f35c28..86dd23974e05 100644 --- a/trunk/sound/oss/emu10k1/audio.c +++ b/trunk/sound/oss/emu10k1/audio.c @@ -111,15 +111,9 @@ static ssize_t emu10k1_audio_read(struct file *file, char __user *buffer, size_t if ((bytestocopy >= wiinst->buffer.fragment_size) || (bytestocopy >= count)) { - int rc; - bytestocopy = min_t(u32, bytestocopy, count); - rc = emu10k1_wavein_xferdata(wiinst, - (u8 __user *)buffer, - &bytestocopy); - if (rc) - return rc; + emu10k1_wavein_xferdata(wiinst, (u8 __user *)buffer, &bytestocopy); count -= bytestocopy; buffer += bytestocopy; diff --git a/trunk/sound/oss/emu10k1/cardwi.c b/trunk/sound/oss/emu10k1/cardwi.c index 060d1be94d33..8bbf44b881b4 100644 --- a/trunk/sound/oss/emu10k1/cardwi.c +++ b/trunk/sound/oss/emu10k1/cardwi.c @@ -304,12 +304,11 @@ void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size) } } -static int copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov) +static void copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov) { - if (cov == 1) { - if (__copy_to_user(dst, src + str, len)) - return -EFAULT; - } else { + if (cov == 1) + __copy_to_user(dst, src + str, len); + else { u8 byte; u32 i; @@ -317,26 +316,22 @@ static int copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov) for (i = 0; i < len; i++) { byte = src[2 * i] ^ 0x80; - if (__copy_to_user(dst + i, &byte, 1)) - return -EFAULT; + __copy_to_user(dst + i, &byte, 1); } } - - return 0; } -int emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size) +void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size) { struct wavein_buffer *buffer = &wiinst->buffer; u32 sizetocopy, sizetocopy_now, start; unsigned long flags; - int ret; sizetocopy = min_t(u32, buffer->size, *size); *size = sizetocopy; if (!sizetocopy) - return 0; + return; spin_lock_irqsave(&wiinst->lock, flags); start = buffer->pos; @@ -350,17 +345,11 @@ int emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size) if (sizetocopy > sizetocopy_now) { sizetocopy -= sizetocopy_now; - ret = copy_block(data, buffer->addr, start, sizetocopy_now, - buffer->cov); - if (ret == 0) - ret = copy_block(data + sizetocopy_now, buffer->addr, 0, - sizetocopy, buffer->cov); + copy_block(data, buffer->addr, start, sizetocopy_now, buffer->cov); + copy_block(data + sizetocopy_now, buffer->addr, 0, sizetocopy, buffer->cov); } else { - ret = copy_block(data, buffer->addr, start, sizetocopy, - buffer->cov); + copy_block(data, buffer->addr, start, sizetocopy, buffer->cov); } - - return ret; } void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst) diff --git a/trunk/sound/oss/emu10k1/cardwi.h b/trunk/sound/oss/emu10k1/cardwi.h index e82029b46ad1..15cfb9b35596 100644 --- a/trunk/sound/oss/emu10k1/cardwi.h +++ b/trunk/sound/oss/emu10k1/cardwi.h @@ -83,7 +83,7 @@ void emu10k1_wavein_close(struct emu10k1_wavedevice *); void emu10k1_wavein_start(struct emu10k1_wavedevice *); void emu10k1_wavein_stop(struct emu10k1_wavedevice *); void emu10k1_wavein_getxfersize(struct wiinst *, u32 *); -int emu10k1_wavein_xferdata(struct wiinst *, u8 __user *, u32 *); +void emu10k1_wavein_xferdata(struct wiinst *, u8 __user *, u32 *); int emu10k1_wavein_setformat(struct emu10k1_wavedevice *, struct wave_format *); void emu10k1_wavein_update(struct emu10k1_card *, struct wiinst *); diff --git a/trunk/sound/oss/emu10k1/passthrough.c b/trunk/sound/oss/emu10k1/passthrough.c index 6d21d4368dec..4e3baca7d41f 100644 --- a/trunk/sound/oss/emu10k1/passthrough.c +++ b/trunk/sound/oss/emu10k1/passthrough.c @@ -162,15 +162,12 @@ ssize_t emu10k1_pt_write(struct file *file, const char __user *buffer, size_t co DPD(3, "prepend size %d, prepending %d bytes\n", pt->prepend_size, needed); if (count < needed) { - if (copy_from_user(pt->buf + pt->prepend_size, - buffer, count)) - return -EFAULT; + copy_from_user(pt->buf + pt->prepend_size, buffer, count); pt->prepend_size += count; DPD(3, "prepend size now %d\n", pt->prepend_size); return count; } - if (copy_from_user(pt->buf + pt->prepend_size, buffer, needed)) - return -EFAULT; + copy_from_user(pt->buf + pt->prepend_size, buffer, needed); r = pt_putblock(wave_dev, (u16 *) pt->buf, nonblock); if (r) return r; @@ -181,8 +178,7 @@ ssize_t emu10k1_pt_write(struct file *file, const char __user *buffer, size_t co blocks_copied = 0; while (blocks > 0) { u16 __user *bufptr = (u16 __user *) buffer + (bytes_copied/2); - if (copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE)) - return -EFAULT; + copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE); r = pt_putblock(wave_dev, (u16 *)pt->buf, nonblock); if (r) { if (bytes_copied) @@ -197,8 +193,7 @@ ssize_t emu10k1_pt_write(struct file *file, const char __user *buffer, size_t co i = count - bytes_copied; if (i) { pt->prepend_size = i; - if (copy_from_user(pt->buf, buffer + bytes_copied, i)) - return -EFAULT; + copy_from_user(pt->buf, buffer + bytes_copied, i); bytes_copied += i; DPD(3, "filling prepend buffer with %d bytes", i); } diff --git a/trunk/sound/oss/via82cxxx_audio.c b/trunk/sound/oss/via82cxxx_audio.c index c96cc8c68b3b..17837d4b5ed3 100644 --- a/trunk/sound/oss/via82cxxx_audio.c +++ b/trunk/sound/oss/via82cxxx_audio.c @@ -2120,8 +2120,8 @@ static struct page * via_mm_nopage (struct vm_area_struct * vma, return NOPAGE_SIGBUS; /* Disallow mremap */ } if (!card) { - DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n"); - return NOPAGE_SIGBUS; /* Nothing allocated */ + DPRINTK ("EXIT, returning NOPAGE_OOM\n"); + return NOPAGE_OOM; /* Nothing allocated */ } pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT); diff --git a/trunk/sound/usb/usx2y/usX2Yhwdep.c b/trunk/sound/usb/usx2y/usX2Yhwdep.c index b76b3dd9df25..4b52d18dcd53 100644 --- a/trunk/sound/usb/usx2y/usX2Yhwdep.c +++ b/trunk/sound/usb/usx2y/usX2Yhwdep.c @@ -48,7 +48,7 @@ static struct page * snd_us428ctls_vm_nopage(struct vm_area_struct *area, unsign offset = area->vm_pgoff << PAGE_SHIFT; offset += address - area->vm_start; - snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS); + snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM); vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->us428ctls_sharedmem + offset; page = virt_to_page(vaddr); get_page(page);